实体和 DTO 之间的区别

2022-08-31 13:28:37

DTO 和实体之间有什么区别?详细地说,这些是我的问题:

  1. 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

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

    @Entity
    public class MyFirstEntity extends MySecondEntity {
        ....
    }
    
    @Entity
    public class MyFirstDTO extends MySecondDTO {
        ....
    }
    
  2. 我应该如何使用它们?例如,我发现:我正在处理一个Web项目。网页的用户想要注册。他/她填写表单,并将其发送到服务器。在服务器端,我首先创建一个 DTO,因为它的字段具有验证。从 DTO 中,我创建了一个实体并将其保存到数据库中。当存在对实体的请求时,我将请求的实体转换为 DTO,并将其提供给客户端的用户。这是不是一个好的想象?


答案 1

简短的回答:

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

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

长答案:

虽然术语“数据传输对象”(DTO)的定义非常明确,但术语“实体”在各种上下文中的解释不同。

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

  1. 在实体关系和ORM框架的上下文中,特别是Enterprise Java和Jpa:
    “一个表示在数据库中维护的持久数据的对象。

  2. 在“领域驱动设计”(Eric Evans)的上下文中:
    “一个主要由其身份而不是其属性定义的对象。

  3. 在“Clean Architecture”(Robert C. Martin著)的上下文中:
    “封装企业范围的关键业务规则的对象”。

Jee 社区和 Jpa 社区主要将实体视为映射到数据库表的对象。这种观点非常接近DTO的定义 - 这就是大部分混乱可能源于此的地方。

然而,在领域驱动设计的背景下,以及罗伯特·马丁的观点,实体是业务领域的一部分,因此可以而且应该实现行为。


答案 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>

然后在春季或其他一些框架中,无论选择哪个,都将被选为实体中的性别。这是可能的,因为Dto具有性别的所有三个价值观。同样,根据情况,事情如下。由于大多数情况下,我们需要jsp上的大多数实体字段,因此我们逐个实体扩展dto。


推荐