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

关于DTO、DO、BO、VO

一、参考文章

  • https://blog.csdn.net/lairikeqi/article/details/106081782

  • https://blog.csdn.net/2301_81298401/article/details/137342582

二、详解

这些都不是强制性要求,只是一个规范,比如对于一个比较小的系统,强制增加分层对象,可能各个分层对象之间的转换成了最繁琐的事情

典型分层架构使用对象:

Controller (Web层) ↓ VO/Request/Response
Service (业务层)↓ BO/DTO
Manager/Repository (数据访问层)↓ DO/Entity
Database (数据库层)

典型数据流转:

前端 Request/Response ↔ VO ↔ Controller↓Service ↔ DTO ↔ BO↓Repository ↔ DO ↔ Database

转换方法示例:

// VO ↔ DTO 转换
public class OrderConverter {public static OrderVO toVO(OrderDTO dto) { ... }public static OrderDTO toDTO(OrderVO vo) { ... }
}// DTO ↔ BO 转换
public class OrderBO {public static OrderBO fromDTO(OrderDTO dto) { ... }public OrderDTO toDTO() { ... }
}// BO ↔ DO 转换
public class OrderBO {public OrderDO toDO() { ... }public static OrderBO fromDO(OrderDO do) { ... }
}

1、VO (View Object) - 视图对象

概述:

VO (View Object),用于表示一个与前端进行交互的视图对象,它的作用是把某个指定页面(或组件)的所有数据封装起来。实际上,这里的 VO 只包含前端需要展示的数据,对于前端不需要的数据,比如数据创建和修改的时间等字段,出于减少传输数据量大小和保护数据库结构不外泄的目的,不应该在 VO 中体现出来

使用场景:

  • 前端展示层:专门为前端界面设计的数据结构

  • API 响应:Controller 返回给前端的数据

  • 页面渲染:JSP/Thymeleaf 等模板引擎使用

典型例子:

// 用户列表页面的 VO
public class UserListVO {private Long userId;private String userName;private String statusName;        // 状态中文名private String createTimeStr;     // 格式化后的时间private Boolean canEdit;          // 是否可编辑(业务权限)private String avatarUrl;         // 头像完整URL
}// controller层
public class xxxController {@PostMapping("/query")public Result<UserListVO> query(@RequestBody xxxParam param) {// 返回 VO 给前端}
}

2、DO (Data Object) - 数据对象

概述:

DO(Data Object) ,持久化对象,它跟持久层(Dao)的数据结构形成一一对应的映射关系。如果持久层是关系型数据库,那么数据库表中的每个字段就对应PO的一个属性,常是entity实体类。

使用场景:

  • 数据库映射:与数据库表一一对应

  • ORM 框架:MyBatis/JPA 的实体映射

  • 数据持久化:直接操作数据库的对象

典型例子:

@TableName("user")
public class UserDO {private Long id;private String name;private String email;// getters and setters
}

3、BO (Business Object) - 业务对象

概述:

BO(Business Object):业务对象,就是从现实世界中抽象出来的有形或无形的业务实体。

使用场景:

  • 复杂业务逻辑:封装核心业务规则和计算

  • 聚合根:DDD 中的聚合根对象

  • 状态管理:管理复杂的业务状态

  • 业务验证:包含业务验证逻辑

典型例子:

// 复杂业务逻辑的 BO
public class OrderBO {private Long orderId;private OrderStatus status;private List<OrderItemDTO> items;private CustomerDTO customer;// 业务方法public boolean canCancel() {return status == OrderStatus.PENDING && createTime.isAfter(LocalDateTime.now().minusHours(24));}public BigDecimal calculateTotalWithDiscount() {BigDecimal total = items.stream().map(OrderItemDTO::getSubtotal).reduce(BigDecimal.ZERO, BigDecimal::add);return applyCustomerDiscount(total, customer.getVipLevel());}public void processPayment(PaymentDTO payment) {validatePaymentAmount(payment);updateOrderStatus();sendNotification();}// 包含复杂的业务逻辑和数据转换public static BillingDetailBO of(...) { ... }public OrderDTO get() { ... }
}

4、DTO (Data Transfer Object) - 数据传输对象

概述:

DTO(Data Transfer Object),用于表示一个数据传输对象,DTO 通常用于展示层(Controller)和服务层(Service)之间的数据传输对象。DTO 与 VO 概念相似,并且通常情况下字段也基本一致。但 DTO 与 VO 又有一些不同,这个不同主要是设计理念上的,比如 API 服务需要使用的 DTO 就可能与 VO 存在差异。

使用场景:

  • 跨层传输:Service 层之间的数据传递【主要】

  • 跨服务调用:微服务之间的数据传输

  • RPC 调用:远程过程调用的参数和返回值

  • 缓存对象:Redis 等缓存中存储的数据结构

典型例子:

public class UserDTO {private Long id;private String displayName;public UserDTO(UserBO userBO) {this.id = userBO.getUserDO().getId();this.displayName = userBO.getUserDO().getName();}
}// service 层中的传递
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public UserDTO getUserDetails(Long userId) {UserDO userDO = userRepository.findById(userId).orElse(null);UserBO userBO = new UserBO(userDO);UserDTO userDTO = new UserDTO(userBO);return userDTO;}

5、应用示例

Controller 层:

@RestController
public class OrderController {@PostMapping("/create")public Result<OrderVO> createOrder(@RequestBody CreateOrderRequest request) {// Request → DTO 转换OrderDTO orderDTO = convertToDTO(request);// 调用 ServiceOrderDTO result = orderService.createOrder(orderDTO);// DTO → VO 转换OrderVO orderVO = convertToVO(result);return Result.success(orderVO);}
}

Service 层:

@Service
public class OrderService {public OrderDTO createOrder(OrderDTO orderDTO) {// DTO → BO 转换(复杂业务逻辑)OrderBO orderBO = OrderBO.createFromDTO(orderDTO);// 业务逻辑处理orderBO.validateOrder();orderBO.calculatePrice();orderBO.applyPromotions();// BO → DO 转换OrderDO orderDO = orderBO.toDO();// 保存到数据库orderRepository.save(orderDO);// DO → DTO 返回return OrderDTO.fromDO(orderDO);}
}

Repository/Dao 层:

@Repository
public class OrderRepository {public OrderDO save(OrderDO orderDO) {// 直接操作数据库return orderMapper.insert(orderDO);}public List<OrderDO> findByPatientId(Long patientId) {// 返回 DO 对象return orderMapper.selectByPatientId(patientId);}
}

六、特殊场景的选择

1.简单CRUD场景

// 可以简化,跳过 BO
Controller → Service → DTO → Repository → DO

2.复杂业务场景

// 必须使用 BO 封装业务逻辑
Controller → VO → Service → DTO → BO → Repository → DO

3.微服务调用

// 服务间只传输 DTO
ServiceA → DTO → RPC → ServiceB

4.报表展示

// 重点使用 VO 进行数据格式化
Service → DTO → ReportVO (包含格式化数据)
http://www.dtcms.com/a/353709.html

相关文章:

  • Linux系统性能优化全攻略:从CPU到网络的全方位监控与诊断
  • [实战] 半导体工厂生产网络项目案例分享
  • 遥感语义分割消融实验+对比实验
  • AI驱动的前端性能优化:从监控到自动化修复
  • SymPy 与 NumPy 混合编程:解决矩阵类型转换与数学函数兼容性问题
  • 计算机视觉全流程(基础知识)
  • 耐达讯自动化Profibus 集线器:变送器连接的神秘王牌
  • SCDN如何保护敏感内容不被非法访问?
  • 【PyTorch从入门到实战】全面解析PyTorch框架:安装、原理、MNIST实战与核心组件
  • 数据采集如何选择移动代理IP?合理避免网站封禁实战经验
  • Agno Agent​​
  • 需求变更的影响如何评估
  • AI Agent 发展趋势与架构演进
  • 神经网络|(十六)概率论基础知识-伽马函数·上
  • PowerShell下vim编辑文件时产生的额外文件
  • 北京先智先行科技:揭秘先知大模型的创新力量
  • 泰山区委书记张培峰率队考察深兰科技张江新总部,加速推进AI产业投资落地
  • 【AI论文】MV-RAG:检索增强的多视图扩散模型
  • Linux IPTables
  • 7、prefix-tuning、P-tuning、Prompt-tuning
  • 大规模5G无线通信网络
  • 服务器关机故障排查:大白话版笔记
  • 软件定义汽车(SDV)调试——如何做到 适配软件定义汽车(SDV)?(上)
  • R包fastWGCNA - 快速执行WGCNA分析和下游分析可视化
  • 【Mascaret】QGIS中Mascaret插件的使用
  • JAVA 引用类型深拷贝的三种实现方式
  • (48)华为云平台-rpa-安全组限制端口+ip
  • (一)光头整洁架构(Mediator Pattern/Result Patttern/UnitOfWork/Rich Domain)
  • docker部署spring boot,安装jdk17、maven3.8.8详细步骤
  • 【C++】菱形继承深度解析+实际内存分布