⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Fight/biezaihunxiaoleJava-kaifaguifanPOVOBODTODAOPOJO-chedigaodong/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

Java 项目里最容易吵起来的,不是技术选型,而是对象命名。

UserPO、UserDTO、UserVO、UserBO、UserDAO、UserPOJO 到底谁是谁?很多项目嘴上说分层,代码里全叫 User。最后 Controller 直接把数据库字段返回给前端,密码字段也跟着裸奔。

这几个名字的核心目的只有一个:让不同层的数据对象各司其职,别把数据库、业务逻辑、接口参数和页面展示搅在一起。

先记住这条主线

最简单的流向是:

前端页面
↑ ↓
VO (给前端看)
↑ ↓
Controller
↑ ↓
DTO (接口传参)
↑ ↓
Service
↑ ↓
BO (业务处理)
↑ ↓
Mapper/DAO
↑ ↓
PO (对应数据库)
↑ ↓
数据库表

一句话版:PO 贴数据库,DTO 走接口,VO 给前端,BO 放业务,DAO 管读写,POJO 是统称。

PO:数据库表的一行记录

PO 是 Persistent Object,持久化对象。

它通常和数据库表结构一一对应,一张 user 表,就可能有一个 UserPO。

常见特点:

  • 字段尽量贴近数据库列。
  • 主要出现在 Mapper、Repository、DAO 层。
  • 不建议放复杂业务逻辑。

例子:user(id, username, password, create_time) 对应 UserPO。

注意,PO 不是给前端看的。数据库里有 password_hash、deleted、tenant_id 这类字段,不代表接口就该原样返回。

DAO:操作数据库的入口

DAO 是 Data Access Object,数据访问对象。

它不是实体类,而是操作数据库的接口或类。在 MyBatis 里通常叫 Mapper,在 JPA 里可能叫 Repository。

常见职责:

  • 增删改查。
  • 封装 SQL 或 ORM 查询。
  • 返回 PO 或基础查询结果。

比如 UserMapper、UserDao、UserRepository 都属于这一类。

BO:业务逻辑里的对象

BO 是 Business Object,业务对象。

它服务于业务逻辑,字段不一定和数据库、接口完全一致。一个 BO 可能由多个 PO 组装而来,也可能包含计算后的业务状态。

例子:用户基础信息 + 会员信息 + 最近订单,可以封装成 UserProfileBO 给 Service 层处理。

BO 最容易被忽略。很多项目直接拿 DTO 或 PO 在 Service 里传来传去,短期省事,长期会让业务逻辑越来越脏。

DTO:接口之间传输的数据

DTO 是 Data Transfer Object,数据传输对象。

它解决的是“接口传什么”的问题,常见于 Controller 入参、RPC 入参、微服务调用参数。

常见特点:

  • 只包含接口需要的字段。
  • 可以加校验注解,比如 @NotBlank、@NotNull。
  • 不暴露数据库内部字段。

例如新增用户接口可以用 CreateUserDTO,里面只有 username、mobile、roleIds,不应该出现 id、createTime、deleted。

VO:返回给前端展示的数据

VO 是 View Object,视图对象。

它解决的是“前端看什么”的问题。页面需要什么字段,VO 就提供什么字段。

常见特点:

  • 用于 Controller 返回值。
  • 可以包含展示友好的字段,比如 statusName、roleNames。
  • 不包含敏感字段,比如密码、密钥、内部标识。

同一个 PO 可以对应多个 VO。列表页一个 UserListVO,详情页一个 UserDetailVO,下拉框一个 UserOptionVO,这很正常。

POJO:所有简单 Java 对象的统称

POJO 是 Plain Old Java Object,简单 Java 对象。

它不是某一层的专属对象,而是一个大类。只要是普通 Java 类,没有强依赖特定框架、主要由字段和 getter/setter 组成,都可以叫 POJO。

所以 PO、DTO、VO、BO 大多都属于 POJO。

企业项目里怎么用才不乱

不用把命名搞成宗教。大多数业务项目,先把这四类用好就够了:

对象 放在哪 解决什么问题
PO dal / repository / mapper 数据库映射
DTO controller / api 接收请求和远程调用
VO controller / web 返回给前端
BO service / domain 业务聚合和计算

DAO 或 Mapper 是数据访问层入口,不要和实体对象混在一起。POJO 是统称,不建议拿来做具体类名后缀,否则等于什么都没说。

最容易踩的三个坑

第一,PO 直接返回前端。这是最常见也最危险的写法。字段一多,敏感信息迟早泄露。

第二,DTO、VO 混用。入参对象和出参对象职责不同,混用会让校验、展示、兼容性都变得难维护。

第三,所有对象都叫 Entity。小项目能忍,大项目会崩。你根本看不出来这个对象是查库用、接口入参用,还是前端展示用。

最后用一句话收尾

别背缩写,背职责。

PO 贴库,DAO 查库,BO 做业务,DTO 传入参,VO 做展示,POJO 是普通对象统称。只要这条线清楚,Java 分层命名基本就不会乱。

文章目录
  1. 1. 先记住这条主线
  2. 2. PO:数据库表的一行记录
  3. 3. DAO:操作数据库的入口
  4. 4. BO:业务逻辑里的对象
  5. 5. DTO:接口之间传输的数据
  6. 6. VO:返回给前端展示的数据
  7. 7. POJO:所有简单 Java 对象的统称
  8. 8. 企业项目里怎么用才不乱
  9. 9. 最容易踩的三个坑
  10. 10. 最后用一句话收尾