Java项目中PO、DO、BO、DTO、VO的区别和用法是什么?

 更新时间:2026年07月28日 10:52:13   作者:小小称、  
还在为PO、DO、BO、DTO、VO傻傻分不清而头疼?本文用最直白的方式帮你理清Java项目中的对象分层,从持久化对象到视图对象,让你彻底搞懂它们的职责和区别,提升代码维护性

1.PO(Persistence Object,持久化对象)

  • 定义:与数据库表结构直接映射的对象,通常用于ORM(如Hibernate、MyBatis)操作数据库。

  • 职责:表示数据库中的一条记录。

特点

  • 属性与数据库表字段一一对应。

  • 通常不包含业务逻辑。

示例

@Entity
@Table(name = "user")
public class UserPO {
    @Id
    private Long id;
    private String username;
    private String email;
    // getters/setters
}

2.DO(Domain Object,领域对象)

  • 定义:在领域驱动设计(DDD)中表示核心业务逻辑的实体对象,与PO类似但关注点不同。

  • 职责:封装领域模型的属性和行为(业务逻辑)。

特点

  • 可能包含业务方法(如校验规则、状态转换)。

  • 在阿里Java规范中,DO(Data Object)可能直接对应PO。

示例

public class UserDO {
    private Long id;
    private String username;
    // 业务方法,例如校验用户名
    public boolean isValidUsername() {
        return username != null && username.length() >= 6;
    }
}

3.BO(Business Object,业务对象)

  • 定义:封装复杂业务逻辑的对象,可能组合多个PO/DO。

  • 职责:处理跨实体的业务逻辑,例如订单创建涉及用户、商品、库存等。

特点

  • 可能包含多个PO/DO的聚合。

  • 实现核心业务规则。

示例

public class OrderBO {
    private OrderPO orderPO;
    private UserPO userPO;
    private List<ProductPO> products;
    // 计算订单总价
    public BigDecimal calculateTotalPrice() { ... }
}

4.DTO(Data Transfer Object,数据传输对象)

  • 定义:用于不同层(如Controller-Service)或服务间(如微服务)传输数据的对象。

  • 职责:减少网络传输次数,避免暴露内部数据结构。

特点

  • 扁平化结构,可能组合多个领域对象的数据。

  • 无业务逻辑,仅包含数据字段。

示例

public class UserDTO {
    private Long id;
    private String username;
    private String avatarUrl; // 可能由多个PO组合而来
    // getters/setters
}

5.VO(Value Object,值对象 / View Object,视图对象)

  • 定义:用于展示层(如前端页面),封装界面需要的数据。

  • 职责:适配前端需求,格式化数据(如日期、金额)。

特点

  • 字段可能与数据库表不完全对应。

  • 包含展示逻辑(如状态码转文本)。

示例

public class UserVO {
    private String username;
    private String formattedRegisterDate; // "2023-10-01"
    // getters/setters
}

关键区别总结

对象层级核心职责典型场景
PO数据访问层(DAO)数据库映射MyBatis/Hibernate操作数据库
DO领域层(Domain)封装领域模型和业务规则DDD中的实体对象
BO业务逻辑层(Service)复杂业务逻辑聚合跨多个PO/DO的业务操作
DTO传输层跨层/跨服务数据传输Controller-Service交互
VO展示层(View)适配前端展示需求返回给前端的JSON数据

注意事项

实际项目中的简化

  • 小型项目可能合并某些对象(如PO直接作为DTO使用),但中大型项目建议分层。

命名差异

  • 不同公司/框架可能有不同习惯(如阿里规范中DO替代PO)。

工具支持

  • 使用MapStruct、ModelMapper等工具简化对象间转换。

通过合理使用这些对象模型,可以显著提高代码的可维护性和扩展性。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解Java的类加载机制及热部署的原理

    详解Java的类加载机制及热部署的原理

    今天我要讲的就是Java的热部署的原理,由于热部署的原理和类的加载机制有关,所以打算讲一下类加载的机制,文中介绍的非常详细,需要的朋友可以参考下
    2021-05-05
  • Java设计模式之策略模式(Strategy模式)介绍

    Java设计模式之策略模式(Strategy模式)介绍

    这篇文章主要介绍了Java设计模式之策略模式(Strategy模式)介绍,Strategy是属于设计模式中对象行为型模式,要是定义一系列的算法,这些算法一个个封装成单独的类,需要的朋友可以参考下
    2015-03-03
  • maven依赖的version声明控制方式

    maven依赖的version声明控制方式

    这篇文章主要介绍了maven依赖的version声明控制方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 详解Spring mvc DispatchServlet 实现机制

    详解Spring mvc DispatchServlet 实现机制

    本篇文章主要介绍了详解Spring mvc DispatchServlet 实现机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java实现后端跨域的常见解决方案

    Java实现后端跨域的常见解决方案

    跨源资源共享(CORS——Cross-Origin Resource Sharing,跨源资源共享,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,跨域的解决方案有很多种,前后端都有,本文给大家主要介绍Java实现后端跨域的常见解决方案,需要的朋友可以参考下
    2024-04-04
  • java进阶解析Springboot上传excel存入数据库步骤

    java进阶解析Springboot上传excel存入数据库步骤

    项目需要,写了一个,批量导入的接口。因为需要使用excel去批量导入数据,所以写了一个例子,经过测试已经可以用于实际开发,这里记录一下
    2021-09-09
  • 详解Java I/O流中的字符流有哪些

    详解Java I/O流中的字符流有哪些

    字节流的功能已经十分强大,几乎可以直接或间接地处理任何类型的输入/输出操作,但它却不能直接操作16位的Unicode字符,这就需要使用字符流,所以在今天的内容中,小编会给大家讲解IO流中的字符流,希望各位能够继续耐心学习
    2023-10-10
  • 浅谈java获取服务器基本信息

    浅谈java获取服务器基本信息

    这篇文章主要介绍了java获取服务器基本信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • OpenFeign无法远程调用问题及解决

    OpenFeign无法远程调用问题及解决

    文章介绍了在使用Feign客户端时遇到的读超时问题,并分析了原因是系统启动时未先加载Nacos配置,为了解决这个问题,建议将Nacos配置放在`bootstrap.yml`文件中,以便项目启动时优先加载Nacos配置
    2024-11-11
  • MyBatisPlus 暂时分页失效原因及问题解决

    MyBatisPlus 暂时分页失效原因及问题解决

    MybatisPlus升级后分页失效,因新版本PaginationInnerInterceptor中新增maxLimit限制,下面就来介绍MyBatisPlus 暂时分页失效原因及问题解决,感兴趣的可以了解一下
    2025-07-07

最新评论