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 混淆,就是好的规范。

浙公网安备 33010602011771号