我学习到的Java中domain和dto区别

核心概念

  • Domain(领域模型)/实体(Entity) :通常映射到数据库表(JPA 中的 @Entity,MyBatis 中的 POJO)。包含数据 + 业务逻辑(通常只是数据,带有贫血模型,但在更广泛的意义上,它代表业务实体)。
  • DTO(数据传输对象) :为传输而设计的普通数据容器(API 请求/响应、RPC 调用)。无业务逻辑。专为特定用例(如 UI 视图)量身定制。

1. Domain 和 DTO 的异同

对比维度 Domain(领域对象 / PO / Entity) DTO(数据传输对象)
核心职责 持久化:负责与数据库表结构一一映射(ORM)。 传输:负责在"后端"与"前端(或第三方接口)"之间传递数据。
包含属性 全量字段 :包含数据库表中所有的列(比如:id, name, password, salt, create_time, update_time)。 部分字段 :只包含前端当前页面需要 的字段(比如:只返回 id 和 name,不要 password)。
包含逻辑 可以有业务逻辑:可以包含一些针对该实体类的校验方法或业务计算方法。 纯数据载体 :只应该有字段和 getter/setter,绝对不包含任何业务逻辑。
敏感信息 包含敏感信息:直接包含数据库里的密码、加密盐值等。 过滤敏感信息:严禁包含密码、身份证号等不该暴露给前端的数据。

2. 为什么需要分两个?

如果偷懒不分层,直接把 Domain 对象返回给前端(Controller 层直接返回 Entity),你会遇到以下 3 个致命问题:

  • ① 安全问题(最严重) :你的 Domain 对象里一定有 password(密码密文)和 salt(盐值)。如果你直接把 Domain 传给前端,这些敏感数据就会被接口泄露出去。而 DTO 可以只挑出 username 和 avatar 返回。
  • ② 接口稳定性(防破环) :数据库表结构经常变动(比如加个字段、改个字段名)。如果你把 Domain 当接口返回对象,只要数据库加一个字段,所有调用你接口的前端 App 都得跟着改代码 (因为序列化后多了一个不需要的字段)。而有了 DTO,你可以通过 @JsonProperty 或手动 set/get 组装,保证接口字段永远不变,哪怕数据库翻天覆地,前端也无需升级。
  • ③ 结构聚合(性能与便捷性) :前端的一个页面往往需要多张表 的联合数据。比如前端需要"用户信息 + 订单总数 + 积分"。如果你只返回 Domain,前端需要调 3 个接口,发 3 次请求。但你可以在 Service 层查完 3 张表后,组装成一个完整的 DTO (比如 UserProfileDTO),一次返回给前端,大幅减少网络开销。

3. 一个生动的"外卖"类比

  • Domain 就像中央厨房的后厨食材库(包含整只鸡、未处理的生肉、秘制酱料配方)。这些东西很全,但绝不能直接端给客人。
  • DTO 就像端上餐桌的精美菜品(比如一盘宫保鸡丁)。它只是食材库的一部分组合,经过加工(业务处理),去掉了不能吃的部分(敏感信息),摆盘精致(结构符合前端展示需求)。

💡 实践中的归属划分

  • DTO 的组装逻辑 写在 Service 层 (业务层),由 Service 从多个 Mapper 查数据,然后 new UserDTO(),往里 set 值,再返回给 Controller。
  • Controller 层 只接收 Service 返回的 DTO,直接通过 @ResponseBody 转为 JSON 返回给前端,Controller 绝不直接返回 Domain。

总结一句话:Domain 面向数据库(对内),DTO 面向用户(对外)。 分开了,后端代码可以随便重构优化,前端永远不知情,这才是正规军写法的精髓。

相关推荐
学长毕设5 小时前
基于SpringBoot的景点管理系统-附源码
java·spring boot·后端
sxlishaobin6 小时前
Maven Setting详解
java·学习·maven
知守观6 小时前
一个方法两个触发口:反编译 XXL-Job 后,我看清了 inner/job 子包的裸奔现状
java·spring boot·微服务
用户3126874877206 小时前
CompletableFuture 链式编排:异步编程的优雅解法
java
生锈的键盘6 小时前
从实战搞懂 Docker:一个 Python 项目的开发环境容器化笔记
后端
瑞雪兆丰年兮6 小时前
JavaWeb-day14-SpringBootWeb原理篇
java·开发语言·spring boot·spring·bean·mybatis·javaweb
神仙别闹7 小时前
基于 Java GUI 贪心策略直接搜索算法和极大极小博弈树算法的智能人机博弈五子棋游戏
java·毕业设计·gui·贪心策略·极大极小博弈树
九零HTTP7 小时前
RFC 7230 把请求行分了四种,网关只用得上两种
后端
Flynn Liang8 小时前
RAG 评估体系:黄金集、检索指标与 LLM-as-Judge 落地
java·langchain·rag·评估·langchain4j·检索指标
SomeOtherTime8 小时前
Rust生命周期介绍(AI回答)
开发语言·后端·rust