我有很多java域对象需要转换为DTO.
请不要以反模式的东西开始,因为历史悠久,Domain Objects就是它们的原因,我无法修改它们(或者不能修改它们,见下文).
所以,当然,我们已经过了手工完成这一切的时代.我环顾四周,推土机似乎是DTO映射的首选框架.
但是......我真正喜欢的是:在DTO中注释我想要的类和字段,并运行一个生成DTO和映射器的工具.
这听起来太不合理吗?
这样的工具已经存在吗?
我有一个带有POCO域模型和NHibernate存储库层的ASP.NET MVC 2应用程序.我的域模型不知道我的viewmodels所以我使用automapper从viewmodel转到实体,反之亦然.
当我将WCF引入我的项目(一个迟到的要求)时,我开始不得不处理断开连接的对象.也就是说,我使用NHibernate从数据库中检索实体,并且一旦该实体被序列化,它就会断开连接并且每个子集合都被加载,无论我是否计划使用它,这意味着我正在做很多不必要的数据库工作.
在阅读完本文后,我发现强烈建议您不要在域项目之外公开您的实体,而应该使用DTO.
我看到了这个的原因,但我无法弄清楚如何实现它.
我是否从ASP.NET MVC中的viewmodel映射到DTO,通过服务层发送DTO,并从DTO映射到服务层中的实体?我应该在哪里定义我的DTO?
我的问题是: JPA merge在无状态Web应用程序中是否有角色?
关于mergeJPA中的操作,有很多关于SO的讨论.还有一篇关于这个主题的文章,它通过一个更加手动的自己动手过程(通过实体管理器找到实体并进行更改)来对比JPA合并.
我的应用程序有一个丰富的域模型(ala域驱动设计),它使用@Version注释来利用乐观锁定.作为RESTful Web服务的一部分,我们还创建了DTO以通过线路发送.这个DTO层的创建还允许我们向客户端发送它需要的一切,而不是它没有.
到目前为止,我知道这是一个相当典型的架构.我的问题是关于需要UPDATE(即HTTP PUT)现有对象的服务方法.在这种情况下,我们有这两种方法1)JPA Merge,和2)DIY.
我不明白的是JPA合并如何被视为处理更新的选项.这是我的想法,我想知道是否有一些我不明白的事情:
1)为了从有线DTO正确创建分离的JPA实体,必须正确设置版本号...否则抛出OptimisticLockException.但JPA规范说:
实体可以访问其版本字段或属性的状态,或者导出应用程序用于访问版本的方法,但不得修改版本值[30].只允许持久性提供程序设置或更新对象中version属性的值.
2)Merge不处理双向关系......后向字段总是以null结尾.
3)如果DTO中缺少任何字段或数据(由于部分更新),则JPA合并将删除这些关系或使这些字段无效.Hibernate可以处理部分更新,但不能处理JPA合并.DIY可以处理部分更新.
4)合并方法将要做的第一件事就是在数据库中查询实体ID,因此没有DIY的性能优势.
5)在DYI更新,我们加载实体,并根据DTO的变化-有没有电话merge或persist为此事,因为JPA背景下实现了单位的工作格局开箱.
我有这个吗?
编辑:
6)关于延迟加载关系的合并行为可能因提供者而异.
在stackoverflow上阅读了一些Q/As后,我仍然对在我的Web应用程序中正确实现DTO感到困惑.我目前的实现是一个(基于Java EE的)多层架构(具有持久性,服务和表示层),但是所有层都使用"公共"包,包含(以及其他)域对象.在这种情况下,层不能真正被认为是独立的.我打算逐步删除常见的包,但我遇到了各种挑战/问题:
谢谢你的任何答案.
最近我学习了ORM(对象关系映射)和3层架构风格(表示,业务和数据持久性).如果我理解正确,我可以将数据持久层分成DTO和DAO层.
我想了解,以下部分如何在数据持久层中一起工作.
最重要的是,我了解到了这一点
在较大的应用程序中,MVC是仅N层架构的表示层.
我真的很困惑,例如在3层架构风格中它是如何可能的,其中MVC只是一个表示层,而DTO,DAO,DAL只是数据持久层的一部分.我完全迷失了.
如果有人告诉我它是如何一起工作的真相,我会很高兴的.
请不要关闭这个问题,因为有许多不同的表达方式,我看到它到处都是这些东西基本上在大型应用程序中相互关联,我无法想象它是如何工作的.
我很感激任何答案!
DTO和实体之间有什么区别?详细信息以下是我的问题:
DTO应该有哪些领域?例如,我的实体类是:
@Entity
public class MyFirstEntity implements Serializable {
@Id @GeneratedValue
private Long id;
private String stringData;
@OneToOne
private MySecondEntity mySecondEntity;
@OneToMany
private List<MySecondEntity> mySecondEntitesList;
}
@Entity
public class MySecondEntity implements Serializable {
@Id @GeneratedValue
private Long id;
private Integer integerData;
@ManyToOne
private MyFirstEntity myFirstEntity;
}
Run Code Online (Sandbox Code Playgroud)有一个单向连接(一对一)和一个双向连接(多对一),一个简单的字符串和整数数据,当然还有ID.什么,从他们把在MyFirstDTO和MySecondDTO班?
如果实体之间存在继承,那么我应该如何在DTO中表示它?例如:
@Entity
public class MyFirstEntity extends MySecondEntity {
....
}
@Entity
public class MyFirstDTO extends MySecondDTO {
....
}
Run Code Online (Sandbox Code Playgroud)我应该如何使用它们?例如,我发现了这一点:我正在开发一个Web项目.网页的用户想要注册.他/她填写表格,并将其发送到服务器.在服务器端,我首先创建一个DTO,因为它的字段具有验证.从DTO我创建一个实体并将其持久化到数据库.当有实体请求时,我将请求的实体转换为DTO,并将其提供给客户端的用户.是不是很好的想象力?
A.java
@Entity
@Getter
@Setter
@Inheritance
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, inclue=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=AA.class,name="aa"),
@JsonSubTypes.Type(value=AB.class,name="ab"),
})
public abstract class A {
@Id
@GeneratedValue
private Long id;
//json ignore for getter
@ManyToOne
private A parent;
@OneToMany(mappedBy="parent")
private List<A> children;
}
Run Code Online (Sandbox Code Playgroud)
AA.java
@Entity
@Getter
@Setter
@DiscriminatorValue("aa")
public class AA extends A{
private User user;
}
Run Code Online (Sandbox Code Playgroud)
AB.java
@Entity
@Getter
@Setter
@DiscriminatorValue("ab")
public class AB extends A {
private String name;
}
Run Code Online (Sandbox Code Playgroud)
现在,当我将类的实例AB作为JSON 返回时,它看起来像这样:
{
"id": 1,
"type": "ab",
"children": [...],
"name": "ali"
}
Run Code Online (Sandbox Code Playgroud)
由于我想使用自定义User …
当我在dragstart事件中执行此操作时:
e.dataTransfer.setData('text/plain', 'text');
e.dataTransfer.setData('text/html', 'html');
e.dataTransfer.setData('application/x-bookmark', 'bookmark');
Run Code Online (Sandbox Code Playgroud)
这是在drop事件中:
for (var i = 0; i < e.dataTransfer.types.length; i++) {
var type = e.dataTransfer.types[i];
console.log(type + ":" + e.dataTransfer.getData(type));
}
Run Code Online (Sandbox Code Playgroud)
我应该有:
text/plain:text
text/html:html
application/x-bookmark:bookmark
Run Code Online (Sandbox Code Playgroud)
就像我在FF中得到的那样,但实际上我得到了:
Text:text
text/plain:text
Run Code Online (Sandbox Code Playgroud)
在Chrome中.这些数据在哪里消失了?这是否意味着chrome没有正确实现dataTransfer对象?我能做些什么呢?
我在Chrome 4.0.266.0中运行了它
对不起,我是企业应用程序的新手以及设计模式.可能是这个问题缺乏对设计模式的了解.我发现使用DTO传输数据更好.
我的业务实体类如下:
public class Patient
{
public string ID { get; set; }
public string FullName { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以在我的应用程序中,用户只能提供ID和HospitalID.所以它需要另一个Web服务并获取人员信息
public class PersonDTO
{
public string NIC { get; set; }
public string FullName { get; set; }
public string FirstName { get; set; }
public string BirthPlace { get; set; }
public string BirthCertificateID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以根据这些信息我去了Patient对象.(使用DTO模式)
所以我想写一个新类来转换如下.
public class …Run Code Online (Sandbox Code Playgroud) 我开始想知道我是不是在这里遇到反模式,所以请告知最佳实践.
我正在设计一个带有一组各种端点的REST API,我想将请求和响应参数包装到漂亮的DTO中.
例如,一些端点:
public async Task<JobStateResponse> GetJobState(JobStateRequest request);
public async Task<JobDownloadRespose> DownloadJob(JobDownloadRequest request);
public async Task<CreateJobResponse> CreateJob(CreateJobRequest request);
Run Code Online (Sandbox Code Playgroud)
问题是这些请求和响应是相对类似的DTO,例如:
public class JobStateResponse{
public int TaskId {get;set;}
public string ExternalId {get;set;}
public State State {get;set;}
}
public class JobDownloadResponse {
public int TaskId {get;set;}
public string ExternalId {get;set;}
public string JobContent {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我想为这些和继承创建一个基类,但在某些情况下,某些属性可能是多余的...这意味着这些方法没有明确指出它们工作所需的参数.
我的意思是,使用DTO参数公开API端点,该参数具有7个属性,但实际上只需要2个声音非常糟糕 ......
另一方面,为大多数端点维护单独的DTO似乎也是一种过度杀伤,也是维护地狱.
而且我想要的最后一件事是请求的几个基类的复杂关系,因为这可能是一个更糟糕的主要问题.
那么,请求<>响应处理的正确方法是什么?
编辑:关于'基于意见'的标志 - 我正在寻找处理这个问题的最佳做法.我知道它可以通过多种方式完成,但我想避免使用地雷/反模式.另外,我要说到目前为止我对这些答案非常满意.
dto ×10
java ×5
jpa ×2
rest ×2
.net ×1
architecture ×1
asp.net-mvc ×1
c# ×1
dao ×1
entity ×1
javascript ×1
mapping ×1
modelmapper ×1
multi-tier ×1
orm ×1
poco ×1
wcf ×1
web ×1