一句话先说结论:Entity 是数据库表的映射,DTO 是接口之间传数据的对象,两者职责完全不同,不能混用。

一、各自是什么
Entity(实体类)
- 一张数据库表对应一个 Entity,字段和表的列一一对应。
- 通常用 JPA / MyBatis-Plus 的注解(
@Entity、@Table、@Id、@Column)标注。 - 它存在的唯一目的:把数据库里的行,变成 Java 对象,让你不用手写 SQL 也能读写表。
@Entity
@Table(name = "t_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderNo;
private Long userId;
private BigDecimal amount;
private String status;
private String payPassword; // 敏感字段也在表里
private Date createTime;
}
DTO(Data Transfer Object,数据传输对象)
- 专门用来在层与层、服务与服务之间传数据。
- Controller 返回给前端的、Feign 调用远程服务传的、MQ 消息体,通常都是 DTO。
- 它的字段只放对方需要看的东西,数据库里有什么,跟它没关系。
// 给前端看的订单详情
public class OrderVO {
private String orderNo;
private String userName; // 关联查出来的,不是表里的列
private BigDecimal amount;
private String statusDesc; // 把 status 翻译成中文
}
// 接收前端提交的下单请求
public class OrderCreateDTO {
private Long userId;
private BigDecimal amount;
private String remark;
}
二、核心区别
| 维度 | Entity | DTO |
|---|---|---|
| 对应什么 | 数据库表的一行 | 一次接口调用 / 一次数据传输 |
| 字段来源 | 表的列 | 业务需要什么放什么 |
| 能不能包含敏感字段 | 必须有(比如 payPassword) | 绝对不能(前端不该看到) |
| 能不能有派生字段 | 一般不放 | 可以放(userName、statusDesc) |
| 生命周期 | 跟着事务、跟着数据库走 | 只在一次调用的传输过程中存在 |
| 被谁使用 | DAO / Mapper / Repository | Controller、Service、Feign、MQ |
| 改动成本 | 改 Entity = 动数据库结构 | 改 DTO 只是改接口出参,影响小 |
三、为什么不能图省事混用
新手最常见的错误就是:Controller 直接返回 Entity。这样会出三个问题:
- 信息泄露:
payPassword、删除标记、内部状态码这些字段会被 Jackson 直接序列化返给前端。 - 结构耦合:数据库加一列,接口的 JSON 就跟着多一个字段,前端被迫跟着改。
- 懒加载炸掉:JPA 的
@OneToMany关联在事务关闭后再序列化,会抛LazyInitializationException。
所以标准的分层是:
DB ←→ Entity ←→ Service(业务逻辑) ←→ DTO/VO/Req ←→ Controller ←→ 前端
(表结构) (接口契约)
四、常见的几个"Xxx 模式对象"顺带说清
你后面大概率会一起看到这几个,其实它们都是 DTO 的细分,只是用途不同:
- DTO:服务层之间传的通用对象。
- VO(View Object):Controller 返回给前端的视图对象。
- Req / Request / Command:接收前端入参的对象(比如
OrderCreateDTO)。 - BO(Business Object):Service 内部拼装的业务对象,比 DTO 更重。
- PO(Persistent Object):就是 Entity 的另一种叫法,MyBatis 圈子常叫 PO。
这些本质上都是"装数据的 POJO",只是站的位置不同、命名习惯不同,不是什么新的设计模式。
五、一句话记忆
Entity 是给数据库看的,DTO 是给人(前端/调用方)看的。
数据库有什么就往 Entity 里放,对方需要什么才往 DTO 里放。中间用 MapStruct / BeanUtils 做转换,不要互相直接赋值。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/qq_24147051/article/details/170196251



