实体和DTO之间的区别

Posted

技术标签:

【中文标题】实体和DTO之间的区别【英文标题】:Difference between Entity and DTO 【发布时间】:2017-01-16 18:04:18 【问题描述】:

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;
    
    
    

有一个单向连接(一对一)和一个双向连接(多对一),一个简单的字符串和整数数据,当然还有id。在MyFirstDTOMySecondDTO 类中可以从他们那里得到什么?

    如果实体之间存在继承,那么我应该如何在 DTO 中表示它?例如:

    @Entity
    public class MyFirstEntity extends MySecondEntity 
        ....
    
    
    @Entity
    public class MyFirstDTO extends MySecondDTO 
        ....
    
    

    我应该如何使用它们?例如,我发现:我正在做一个网络项目。网页的用户想要注册。他/她填写表格,并将其发送到服务器。在服务器端,我首先创建了一个 DTO,因为它的字段具有验证。我从 DTO 创建了一个实体并将其保存到数据库中。当有实体请求时,我将请求的实体转换为 DTO,并将其提供给客户端的用户。这是一个很好的想象吗?

【问题讨论】:

您是否查看过此处与 DTO 相关的其他几十个问题?喜欢this one? 我读过那些。我只是想确定这些具体的例子。 你链接的页面甚至没有提到我问的问题。 您的意思是“DTO 应该有哪些字段”? 例如。没有提及 id、实体之间的连接、继承。我的最后一个问题很具体。 【参考方案1】:

简答:

实体可能是业务域的一部分。因此,它们可以实现行为并应用于域内的不同用例。

DTO 仅用于将数据从一个进程或上下文传输到另一个。因此,它们没有行为 - 除了非常基本且通常标准化的存储和检索功能。

长答案:

虽然术语“数据传输对象”(DTO) 的定义非常明确,但 “实体”一词在不同的语境中有不同的解释。

在我看来,对“实体”一词最相关的解释是以下三种:

    在企业 java 和 jpa 的上下文中: “表示数据库中维护的持久数据的对象。”

    在“领域驱动设计”的背景下(作者 Eric Evans): “一个主要由其标识而非属性定义的对象。”

    在“干净架构”的背景下(作者:Robert C. Martin): “一个封装企业范围内关键业务规则的对象。”

Jee 和 Jpa 社区主要将实体视为映射到的对象 一个数据库表。这个观点非常接近于一个DTO的定义 - 这就是很多混乱的根源。

在领域驱动设计的背景下,以及 Robert Martins 的观点, 但是,实体是业务领域的一部分,因此可以而且应该 实现行为。

【讨论】:

很好的答案!考虑添加更多链接enterprisecraftsmanship.com/2015/04/13/… 我在理解 DTO 和实体应如何实现时遇到了一些麻烦。在blog post R. Martin 中说 DTO 是数据结构。因此,ORM 框架不构建业务对象,而是提取业务对象操作的数据。但是我如何正确地实现这种区别呢?我应该定义一个包含由 ORM 提取的 EmployeeDTO 的 EmployeeEntity 吗?我一直认为我的实体类(业务对象)必须通过ORM来映射。【参考方案2】:

DTO 和实体的区别:

实体是映射到表的类。 Dto 主要是映射到“视图”层的类。 需要存储的是实体,需要在网页上“显示”的是 DTO。

示例:如果我想按如下方式存储员工模型: 以员工为例,我需要存储性别为男/女/其他。 但在 JSP 上,我需要将所有三个值显示为“选项”表单,以便用户选择一个。

@Entity
public class Employee
//annotate with @Id and others

private Long id;
private String name;
private Gender gender; //this is enum viz Male,female

//Now extend Dto with employee

public EmployeeDto extends Employee
Gender[] genders=Gender.values(); //put all gender types in array.

在渲染jsp时我们可以给

<select name="gender"> //pointed towards entity gender field.
  <option value="Male">Male</option>
  <option value="Female">Female</option>
  <option value="Other">Other</option>
</select>

然后在 spring 或任何其他框架中,无论选择哪个都将被选为实体中的性别。这是可能的,因为 Dto 在其中包含所有三个性别值。 同样,根据情况,情况如下。 由于大多数情况下我们需要 jsp 上的大部分实体字段,因此我们通过实体扩展 dto。

【讨论】:

-1。 DTO 通常被称为通过架构边界传输数据的对象。虽然它们可用于将数据传输到表示层,但它们并不受此特定用途的定义。 对,一个DTO也可以代表数据库中的一条记录。 我认为您的答案是假设您正在实施领域驱动设计?那正确吗?我认为从 ORM 的角度来看,“实体”可能是指 DatabaseEntities。【参考方案3】:

“实体”是指整个系统数据的组成单位。它们通常代表业务对象,例如:银行账户、员工、产品等。它们可用于将系统状态保存到数据库中。

“数据传输对象”是为特定目的而传输的数据的临时集合。例如,向最终用户显示特定种类的产品列表。您不想将代表每个产品实体的所有数据发送给用户,而只发送此目的所需的数据。

the Microsoft 2014 MVC documentation 解释了为什么要从实体创建 DTO。这些是他们建议您将实体转换为 DTO 的一些示例。

删除循环引用。 隐藏客户不应查看的特定属性。 省略某些属性以减小负载大小。 扁平化包含嵌套对象的对象图,使它们更方便客户使用。 避免“过度发布”漏洞。 (有关过度发布的讨论,请参阅模型验证。) 将服务层与数据库层分离。

但重要的是要了解,这些都不是需要遵守的硬性规则。这完全取决于哪些数据最适合发送给您的客户,以及哪种格式对您的客户最有用。

客户需要对数据做什么?

会被编辑还是只是查看? 客户是否关心 int 列表的顺序? 是否需要插入或删除 int? 是否需要重新排列列表?

客户是否需要了解 1-1 或 1-many 关系或存在继承这一事实?发送这些信息可能只会给客户增加不必要的复杂性。

在决定向客户端发送哪些数据以及如何发送之前,需要回答这些问题和其他问题。

【讨论】:

【参考方案4】:

简单的说说: DTO 代表数据传输对象。 DTO 主要用于在服务(Web 服务、API 等)之间传输数据,这些服务可以包含不同实体的各种属性(有或没有他们的 ID)。以这一行作为 DTO 的示例:考虑购物网站将通过 Web 服务将其运输请求发送到运输公司。它的 DTO 是这样的:CustomerFullNameShippingFeeShippingAddress。在此示例中,CustomerFullNameCustomer 实体的属性 FirstName + LastName 的组合,ShippingFee 是多个其他实体的目的地、税收等过程的结果。

相反,实体是一组属性,用于表示具有特定 ID 的单个实体(例如,TeacherStudentEmployee 等)。换句话说,DTO 是一堆无意义的属性,收集起来发送给客户端,一个 DTO 不一定与其他 DTO 有关系,而实体包括与其他实体有有意义关系的特定对象的属性。在关系数据库范例中,我们可以将 DTO 视为视图的行,而实体是具有主键的表的行。 @Shatayu Darbhe 在他/她的回答中也提到了这一点。

但是,Model 是这两者的组合。一个模型可以包含几个相关的实体以及额外的数据来处理现实世界的应用程序/UI 问题。考虑一个名为 CustomerOrdersModel 的模型,它包含 Customer 实体、List&lt;Order&gt; 实体和一个额外的布尔标志 PayWithCredit,用于指定用户是使用借记卡还是信用卡支付。

【讨论】:

以上是关于实体和DTO之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

pojo与DTO的区别是啥?

命令对象和 DTO,区别?

(扫盲)DTO数据传输对象

DTO 和 POCO(或 POJO)有什么区别

POJO(普通旧 Java 对象)和 DTO(数据传输对象)有啥区别?

c# AutoMapper踩坑