Java 项目包命名中经常见到 po、do 和 entity,它们之间到底有何区别?该用哪个?

引言

在 Java 企业级项目开发中,po、do 和 entity 都用于承载数据(POJO,即简单Java对象),但它们的核心定位、起源生态和分层边界有显著区别。

核心定位与区别对比

维度 PO (Persistent Object) DO (Data Object) Entity (领域实体)
全称​ 持久化对象 数据对象 领域实体
核心定位​ 数据库表的直接映射,用于 ORM 框架交互。 数据库表的一一对应,作为数据源传输对象。 业务领域的核心抽象(DDD 概念)。
起源/推崇者​ MyBatis 体系传统叫法。 阿里巴巴《Java开发手册》​ 强烈推荐。 JPA / Hibernate 官方标准叫法。
典型包名​ po 或 persistence do 或 dataobject entity
典型类名​ UserPO / OrderPO UserDO / OrderDO UserEntity / OrderEntity
模型特征​ 贫血模型(只有数据,无业务逻辑)。 贫血模型(只有数据,无业务逻辑)。 可能是充血模型(封装核心业务规则与行为)。
唯一标识​ 数据库主键(如 ID)。 数据库主键(如 ID)。 业务唯一标识(如订单号)。
分层边界​ 仅在持久层(DAO/Mapper)内部使用,禁止跨层。 通过 DAO 层向上传输,禁止传到表现层(Controller)。 领域层核心,禁止跨层到表现层或持久层。

详细场景说明

PO (Persistent Object)
  • 场景:传统 MyBatis 项目常用。它严格对应数据库表结构,包含表里的所有字段(包括创建时间、更新时间等审计字段)。
  • 特点:强调“持久化”,生命周期与数据库操作绑定。
DO (Data Object)
  • 场景:受阿里巴巴《Java开发手册》影响,大量国内互联网公司及 MyBatis-Plus 项目采用此命名。
  • 特点:阿里规约明确规定数据对象与数据库表一一对应,类名命名为 XxxDO。它比 PO 更强调作为“数据传输载体”的属性。
Entity (领域实体)
  • 场景:使用 Spring Data JPA / Hibernate 的项目绝对主流。同时在领域驱动设计(DDD)中代表聚合根或核心领域模型。
  • 特点:如果是 JPA 的 Entity,它依然直接映射数据库表(使用 @Entity 注解);但如果是 DDD 中的 Entity,它不与数据库绑定,而是以业务语义优先,并且内部可以包含业务逻辑方法(充血模型)。

企业级通用规约与避坑指南

  • 类名后缀大写:根据阿里规约,这些缩写命名必须大写。正例:UserDO、OrderPO;反例:UserDo、OrderPo。
  • 禁止 POJO 后缀:POJO(Plain Ordinary Java Object)是 DO/DTO/BO/VO 的统称,禁止将具体类命名为 XxxPOJO。
  • 严禁直接暴露给前端:无论使用 po、do 还是 entity,它们都代表底层数据结构。绝对不能直接作为 Controller 接口的返回对象或接收参数。必须通过 DTO / VO 进行转换,以防止数据库结构变更影响前端,并避免泄露密码、盐值等敏感字段。
  • 包名与类名统一:如果包名定为 entity,类名最好叫 XxxEntity;如果包名是 po,类名最好是 XxxPO。

选型建议(该用哪个?)

  • 选 entity:如果你使用的是 JPA / Hibernate,或者项目偏向领域驱动设计(DDD),或者只是想简单省事(MyBatis-Plus 默认生成也是 entity)。
  • 选 do:如果你所在的团队严格遵循阿里巴巴《Java开发手册》规范(目前国内互联网中大厂非常普遍)。
  • 选 po:如果你维护的是传统 MyBatis​ 老项目,或者团队习惯强调“持久化”概念。

总结

统一即可:无论选哪种,只要在整个项目中保持统一,并且不与 DTO/VO 混淆,就是好的规范。

posted @ 2026-09-04 08:45  Binge-和时间做朋友  阅读(62)  评论(0)    收藏  举报