什么是POJO、PO、DO、DTO、VO

1,017 阅读3分钟

在Java开发中,​POJO、VO、DTO、DO、PO​ 是常见的对象模型术语,它们分别用于不同场景,职责明确但容易混淆。以下是它们的核心区别和用途:


1. ​POJO (Plain Ordinary Java Object)​

  • 定义​:最简单的Java对象,不依赖任何框架或接口(如不继承特定类、不实现特定接口)。

  • 特点​:

    • 只有私有属性和对应的getter/setter方法。
    • 不包含业务逻辑或约束注解(除非手动添加)。
  • 作用​:作为其他对象(VO/DTO/PO等)的基类,强调简单性可复用性

  • 示例​:

    public class User {  // 纯POJO
        private String name;
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }
    

2. ​PO (Persistent Object)​

  • 定义​:与数据库表直接映射的对象,通常由ORM框架(如MyBatis、Hibernate)管理。

  • 特点​:

    • 字段与数据库表一一对应。
    • 可能包含JPA/Hibernate注解(如@Entity@Table)。
  • 示例​:

    @Entity
    @Table(name = "user")
    public class UserPO {
        @Id
        private Long id;
        private String name;
        // getter/setter...
    }
    

3. ​DO (Domain Object)​

  • 定义​:在领域驱动设计(DDD)中表示业务核心逻辑的对象。

  • 特点​:

    • 包含业务方法和状态(如校验规则、计算逻辑)。
    • 可能由多个PO组合而成,或独立于数据库设计。
  • 示例​:

    public class UserDO {
        private Long id;
        private String name;
        
        // 业务方法
        public boolean isVip() {
            return /* 业务规则判断 */;
        }
    }
    

4. ​DTO (Data Transfer Object)​

  • 定义​:用于跨系统或跨层(如Controller → Service)数据传输的对象。

  • 特点​:

    • 仅包含数据字段,无业务逻辑。
    • 可能聚合多个PO/DO的数据(如分页查询结果)。
  • 示例​:

    public class UserDTO {
        private Long userId;
        private String userName;
        // 无业务逻辑,只有getter/setter
    }
    

5. ​VO (View Object)​

  • 定义​:适配前端展示的数据模型,根据视图需求定制。

  • 特点​:

    • 字段可能经过格式化或组合(如日期转为字符串)。
    • 与前端UI强绑定,可能包含冗余字段。
  • 示例​:

    public class UserVO {
        private String name;
        private String joinDate; // 格式化后的日期(如"2023-01-01")
    }
    

关键对比表

类型层级用途是否依赖框架是否含业务逻辑
POJO无层级基础Java对象可选
PO持久层数据库交互是(ORM)
DO业务层实现业务规则
DTO传输层跨进程/跨层数据传输
VO展示层前端数据展示

常见问题

  1. POJO与其他对象的关系

    • VO/DTO/DO/PO本质上都是POJO,但增加了特定场景的约束或职责。
    • 例如:POJO + JPA注解 = PO;POJO + 业务方法 = DO。
  2. 什么情况下需要区分这些对象?​

    • 简单CRUD项目:PO直接当DTO/VO使用。
    • 复杂业务系统:严格分层,避免数据库字段污染业务逻辑或前端展示。
  3. 转换工具
    使用BeanUtilsMapStruct或手动转换对象,例如:

    // PO → DTO
    UserDTO userDTO = new UserDTO();
    BeanUtils.copyProperties(userPO, userDTO);
    

理解这些概念能帮助设计更清晰的架构,但需根据项目实际需求灵活运用,避免过度设计。