在 Java 企业开发中,分层架构是最常见的模式。为了让各层职责清晰,阿里巴巴 Java 开发手册明确提出了 DO、DTO、BO、AO、VO、Query 的定义和使用规范。
很多开发者初看时觉得概念相似、容易混淆,今天我们结合手册规约和一个具体案例,来彻底搞清楚它们。

一、六大对象的定义(阿里规约原文)

  • DO(Data Object,数据对象):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
  • DTO(Data Transfer Object,数据传输对象):Service 或 Manager 向外传输的对象。
  • BO(Business Object,业务对象):由 Service 层输出的封装业务逻辑的对象。
  • AO(Application Object,应用对象):在 Web 层与 Service 层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
  • VO(View Object,显示层对象):通常是 Web 向模板渲染引擎层传输的对象。
  • Query(查询对象):用于封装查询请求。注意超过 2 个参数的查询必须封装成 Query 对象,禁止使用 Map 来传输。
    在这里插入图片描述

二、结合案例理解

我们以一个简单的 用户登录与查询 需求为例,看看这些对象在实际项目里如何应用。

1. DO —— 数据库对象

数据库表 user

id username password email role_id
1 Tom 123456 tom@xx.com 2

对应的 UserDO

@Data
public class UserDO {
    private Long id;
    private String username;
    private String password;
    private String email;
    private Long roleId;
}

👉 作用:DO 与数据库表字段一一对应,用于 DAO 层与数据库交互。


2. AO —— 应用对象

前端发起登录请求:

{
  "username": "Tom",
  "password": "123456"
}

Controller 层接收时封装成 LoginAO

@Data
public class LoginAO {
    private String username;
    private String password;
}

👉 作用:AO 封装 Web 层的请求参数。


3. BO —— 业务对象

Service 层校验用户时,不仅需要 username,还需要角色信息,于是封装成 UserBO

@Data
public class UserBO {
    private Long id;
    private String username;
    private String email;
    private List<RoleDO> roles;
}

👉 作用:BO 封装业务逻辑,通常聚合多个 DO。


4. DTO —— 传输对象

如果用户数据需要传递到 订单服务,为了避免泄露密码,我们定义 UserDTO

@Data
public class UserDTO {
    private Long id;
    private String username;
    private String email;
}

👉 作用:DTO 用于系统间、层间传输,保证安全性和可控性。


5. VO —— 视图对象

后端返回前端时,前端只关心展示数据:

@Data
public class UserVO {
    private String username;
    private String email;
    private String roleName;
}

返回结果:

{
  "username": "Tom",
  "email": "tom@xx.com",
  "roleName": "管理员"
}

👉 作用:VO 是展示层的数据对象,满足页面渲染需求。


6. Query —— 查询对象

假设有一个接口要查询用户:
条件是 用户名 + 状态 + 最小年龄 + 最大年龄,如果直接写 4 个参数很难维护。
于是我们封装一个 UserQuery

@Data
public class UserQuery {
    private String username;
    private Integer status;
    private Integer minAge;
    private Integer maxAge;
}

👉 作用:Query 用来封装复杂查询条件,避免使用 Map


三、调用链流程

一个完整的调用链可以总结为:

前端请求 → AO → Service(BO) → DAO(DO) → 数据库
                    ↓
                 DTO(跨系统传输)
                    ↓
                 VO(返回前端)

这样,每个对象的职责就非常清晰:

  • DO:数据库层
  • AO:Web 入参
  • BO:业务逻辑
  • DTO:跨层/跨系统传输
  • VO:前端展示
  • Query:查询条件

四、总结

阿里规约的核心思想是 高内聚、低耦合

  • 不要让数据库对象直接暴露到前端(DO ≠ VO)。
  • 不要用 Map 来传递复杂参数(用 Query)。
  • 不要在 Controller 里写业务逻辑(用 BO 封装)。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐