当前位置: 首页 > news >正文

DO,VO,DTO.....

在 Java 项目里(尤其是 Spring、MyBatis 这类框架),经常会看到一堆以 O 结尾的类:VO、DO、DTO、BO、POJO……它们本质上都是普通的 Java Bean(即 POJO),但职责和出现的位置不同。下面用“用户下单”这个场景,把常见的几种 O 讲清楚。


1. DO(Data Object)

  • 别名:Entity、PO(Persistent Object)。

  • 出现位置数据库访问层(DAO / Mapper)。

  • 职责

    • 一张表对应一个 DO。

    • 字段与列一一对应,命名也尽量保持和列名一致。

    • 只做数据持久化,不带业务逻辑。

  • 示例

    @TableName("t_user")
    public class UserDO {private Long id;private String name;private String password;   // 数据库里加密存储private LocalDateTime createTime;private LocalDateTime updateTime;
    }

2. DTO(Data Transfer Object)

  • 出现位置:服务间或层间远程/进程间通信(Controller ↔ Service、Service ↔ 外部 RPC、消息队列)。

  • 职责

    • 专门用来“搬运”数据,屏蔽内部实现细节。

    • 当DO无法接收前端传来的全部数据时,使用DTO。

    • 可以聚合多张 DO 的字段,也可以只取部分字段,避免把 DO 直接暴露出去。

    • 序列化友好(JSON / Protobuf / Hessian)。

  • 示例

    public class UserDTO {private Long id;private String name;// 没有 password!
    }

3. VO(View Object / Value Object)

  • 出现位置:展示层(前端页面、移动端、小程序、Thymeleaf、Vue/React)。

  • 职责

    • 面向“页面渲染”或“接口返回”。

    • 业务服务层,处理完数据,返回信息给前端,可以通过VO.

    • 字段名、格式尽量贴近前端需求(驼峰、下划线、枚举值转中文)。

    • 经常做脱敏、格式化、单位换算(钱→元/分、日期→yyyy-MM-dd)。

  • 示例

    public class UserVO {private Long userId;        // id -> userIdprivate String nickName;    // name -> nickNameprivate String createTimeStr; // LocalDateTime -> "2024-07-14 12:00"
    }

4. BO(Business Object)

  • 出现位置:业务逻辑层(Service)。

  • 职责

    • 把多张 DO 组合成一个业务意义上的对象。

    • 可以包含业务方法(例如计算折扣、校验库存)。

    • 很多团队偷懒直接用 DO 代替 BO,导致贫血模型。

  • 示例

    public class OrderBO {private UserDO buyer;private List<OrderItemDO> items;private CouponDO coupon;public BigDecimal calcPayAmount() { ... }
    }

5. POJO(Plain Old Java Object)

  • 定义:上面所有 O 的统称。只要是一个“只有属性+getter/setter+toString”的简单 Java 类,都叫 POJO。

  • 注意:POJO 不是某一种 O,而是它们的“祖宗”。


一张图总结(从下往上数据流动)

数据库表↓
DO(持久化)↓
DAO 层↓
Service 层(组装 DO → BO,做业务计算)↓
Manager / RPC 层(BO → DTO,远程传输)↓
Controller 层(DTO → VO,适配前端)↓
前端页面 / 小程序

常见疑问

问题解答
DO 和 Entity 有什么区别?没区别,只是叫法不同。JPA 喜欢叫 Entity,MyBatis 喜欢叫 DO/PO。
可以直接把 DO 返回给前端吗?不建议。一来字段可能多余(密码、逻辑删除),二来命名格式可能不符合前端习惯。
项目小,有必要分这么细吗?如果只有几个接口,全部用 XxxDTO 一把梭也行。但人多了、接口多了以后,分层对象能显著降低心智负担。
MapStruct / BeanUtils 干嘛用?做对象转换(DO→DTO→VO)的胶水代码,省掉手写 100 个 setter。

一句话记忆:
DO 存库,DTO 跑路,VO 露脸,BO 干活,POJO 是户口本。

http://www.dtcms.com/a/279740.html

相关文章:

  • (二十四)-java+ selenium自动化测试-三大延时等待
  • UI前端与数字孪生融合案例:智慧城市的智慧停车引导系统
  • 苍穹外卖Day4
  • JavaScript进阶篇——第二章 高级特性核心
  • vue笔记4 vue3核心语法和pinia基础使用
  • 【leetcode】326. 3的幂
  • VSCode中使用容器及容器编排docker-compose
  • L1与L2正则化详解:原理、API使用与实践指南
  • FastAPI + gRPC 全栈实践:Windows 开发到 Ubuntu 部署全指南
  • JVM监控及诊断工具-命令行篇
  • ubuntu 22.04 anaconda comfyui安装
  • 8.数据库索引
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘collections’问题
  • WIFI MTU含义 ,协商修改的过程案例分析
  • ansys2021R Fluent 的UDF配置问题
  • 开疆智能EtherCAT转CANopen网关连接磁导航传感器配置案例
  • 《美术教育研究》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • Python项目中Protocol Buffers的应用示例
  • MySQL Innodb Cluster介绍
  • 零基础 “入坑” Java--- 十一、多态
  • Spring Boot + Vue2 实现腾讯云 COS 文件上传:从零搭建分片上传系统
  • 并发编程核心概念详解:进程、线程与协程的本质与差异
  • 解锁HTTP:从理论到实战的奇妙之旅
  • Windows系统使用docker部署项目(有网与离线)
  • LeetCode--45.跳跃游戏 II
  • 破局与重构:文心大模型开源的产业变革密码
  • 北京饮马河科技公司 Java 实习面经
  • vscode 打开项目时候,有部分外部依赖包找不到定义或者声明,但是能使用cmake正常编译并且运行
  • C#——数据与变量
  • 软件构件组装三层次体系:定制、集成与扩展的深度解析