一、图解

在这里插入图片描述

二、相关概念

1、PO(Persistant Object - 持久化对象)

核心定位:

  • 直接与数据库表结构一一映射的对象,通常用于 ORM(对象关系映射)框架(如 MyBatis、Hibernate)中。

特点:

  • 字段与数据库表的列完全对应(包括数据类型、字段名)。
  • 通常包含 getter/setter 方法,可能有默认构造方法。
  • 不包含复杂的业务逻辑,仅作为数据的载体。
  • 生命周期与数据库操作相关,常用于数据库的 CRUD(增删改查)操作。

示例代码:

// 与数据库user表一一映射的PO类
public class UserPO {private Long id;         // 对应表中id列private String username; // 对应表中username列private Integer age;     // 对应表中age列// getter/setter方法
}

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

在 Java 开发中,BO(Business Object,业务对象) 是封装了业务逻辑和业务规则的对象,主要用于实现核心业务功能,是业务逻辑层的核心组件。

BO 的核心特点:

  • 包含业务逻辑: BO 是业务规则、计算逻辑、流程控制的载体,例如订单状态流转、价格计算、权限校验等核心业务逻辑都在 BO 中实现。
  • 依赖数据层: BO 通常会调用 DAO(数据访问对象)获取数据,或通过 DTO/PO 接收数据,经过业务处理后返回结果(可能转换为 VO/DTO)。
  • 代表业务概念: BO 的设计与业务领域紧密相关,例如OrderBO(订单业务对象)、PaymentBO(支付业务对象)等,对应实际业务中的实体或流程。

BO 与其他对象的关系:
在典型的分层架构中,BO 处于核心位置,协调各层数据流转:

视图层(VO) ←→ 控制层 ←→ 业务层(BO) ←→ 数据访问层(DAO) ←→ 数据源(PO/DO)
  • BO 接收从控制层传递的 DTO 数据,或通过 DAO 获取 PO/DO 数据。
  • 对数据进行业务处理(如验证、计算、状态转换等)。
  • 将处理结果转换为 VO 或 DTO,返回给上层(控制层或其他服务)。

示例代码:
以订单业务为例,OrderBO 封装订单创建的核心逻辑:

// 订单业务对象(BO)
public class OrderBO {// 依赖订单DAO和商品DAOprivate OrderDAO orderDAO;private ProductDAO productDAO;// 构造方法注入依赖(实际开发中常用Spring注入)public OrderBO(OrderDAO orderDAO, ProductDAO productDAO) {this.orderDAO = orderDAO;this.productDAO = productDAO;}/*** 创建订单的核心业务逻辑*/public OrderVO createOrder(OrderDTO orderDTO) {// 1. 业务校验:检查商品库存ProductPO product = productDAO.getById(orderDTO.getProductId());if (product.getStock() < orderDTO.getQuantity()) {throw new BusinessException("商品库存不足");}// 2. 业务计算:计算订单金额(含折扣)BigDecimal totalAmount = calculateTotalAmount(product.getPrice(), orderDTO.getQuantity());// 3. 封装订单数据(PO)并保存到数据库OrderPO orderPO = new OrderPO();orderPO.setUserId(orderDTO.getUserId());orderPO.setProductId(orderDTO.getProductId());orderPO.setQuantity(orderDTO.getQuantity());orderPO.setTotalAmount(totalAmount);orderPO.setStatus("CREATED"); // 设置初始状态orderDAO.save(orderPO);// 4. 更新商品库存productDAO.decreaseStock(product.getId(), orderDTO.getQuantity());// 5. 转换为VO返回给前端OrderVO orderVO = new OrderVO();orderVO.setOrderId(orderPO.getId());orderVO.setTotalAmount(totalAmount);orderVO.setStatus("已创建");return orderVO;}// 私有方法:封装折扣计算逻辑private BigDecimal calculateTotalAmount(BigDecimal price, int quantity) {BigDecimal total = price.multiply(new BigDecimal(quantity));// 应用折扣规则(例如满100减10)if (total.compareTo(new BigDecimal(100)) >= 0) {return total.subtract(new BigDecimal(10));}return total;}
}

BO 与 Service 的关系:
在实际开发中,BO 和 Service 常被混用,尤其是在 Spring 框架中:

  • 很多团队直接将@Service注解的类视为 BO,因为它们同样承载业务逻辑。
  • 严格来说,BO 更偏向 “业务实体的逻辑封装”,而 Service 可能包含多个 BO 的协同(如跨领域的业务流程)。

但核心思想一致:BO 是业务逻辑的载体,负责实现系统的核心业务规则和流程。

总结:
BO 的核心价值在于集中管理业务逻辑,使业务规则可复用、易维护,同时隔离业务逻辑与数据访问、视图展示等其他关注点,是分层架构中实现 “高内聚、低耦合” 的重要组件。

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

核心定位:

  • 更广义的数据载体,可用于表示任意数据源的数据(不仅限于数据库),如缓存、消息队列、文件等。

特点:

  • 字段与数据源的结构对应,但数据源可以是多样的(不一定是数据库表)。
  • 同样以数据存储和传递为主要目的,通常也不含复杂业务逻辑。
  • 概念范围比 PO 更广,PO 可以视为 DO 的一种特殊情况(当数据源为数据库时)。

示例:

// 从缓存中读取的用户数据对象(DO)
public class UserDO {private String userId;   // 缓存中的用户IDprivate String nickName; // 缓存中的昵称private Long cacheTime;  // 缓存时间(非数据库字段)// getter/setter方法
}

实际开发中的使用:

  • 在纯数据库操作场景中,PO 和 DO 可能被混用(此时 DO 即 PO)。
  • 在复杂系统中(如包含缓存、多数据源),DO 会被更广泛地用于统一数据格式,而 PO 仅特指数据库映射对象。

4、VO(Value Object - 值对象)

核心定位:

  • 用于表示业务层或视图层的数据,通常用于封装前端展示或服务间交互的 “值”,不依赖数据源。

特点:

  • 字段与业务需求或前端视图对应,可能是多个数据源数据的组合(例如:用户详情页需要的用户名+订单数量+积分,可能来自用户表和订单表)。
  • 通常是只读的(无 setter 方法),由构造方法或工厂方法创建后不可修改。
  • 不包含业务逻辑,仅作为数据传递的容器。

适用场景:

  • 后端返回给前端的 JSON 数据(如 Controller 层返回的对象)。
  • 服务间调用时传递的业务数据(如微服务之间的接口响应)。

示例:

// 前端用户详情页需要的VO
public class UserVO {private String username;  // 用户名(来自用户表)private int orderCount;   // 订单数量(来自订单表)private int积分;          // 积分(来自积分表)// 仅含getter和全参构造方法public UserVO(String username, int orderCount, int score) {this.username = username;this.orderCount = orderCount;this.score = score;}// getter方法...
}

5、POJO(Plain Old Java Object - 简单老式Java对象)

核心定位:

  • 一个 “纯” Java 对象,是所有简单数据载体的统称,没有任何框架或技术的约束。

特点:

  • 仅包含私有字段、getter/setter 方法、无参构造方法(可选)。
  • 不继承任何特定框架的类(如Serializable是允许的,因其是 JDK 自带接口)。
  • 不实现任何框架的接口(如 MyBatis 的BaseMapper或 Spring 的Component)。
  • 不包含业务逻辑方法(如计算、校验等)。

范围:

  • PO、DO、DTO、VO 都可以是 POJO 的子类,只要它们符合 “无框架依赖、仅存数据” 的特征。

示例:

// 一个典型的POJO
public class User {private String name;private int age;// 无参构造、getter、setterpublic User() {}public String getName() { return name; }public void setName(String name) { this.name = name; }// age的getter/setter...
}

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

核心定位:
专门用于跨层或跨服务传递数据的对象,解决 “数据传输效率” 问题。

特点:

  • 字段根据 “传输需求” 定义,可能合并或裁剪数据源的字段(例如:传输用户信息时,只保留id+name,隐藏password)。
  • 用于减少接口调用次数(例如:一次传输用户+订单数据,避免两次接口调用)。
  • 可能包含序列化相关代码(如实现Serializable),方便网络传输。

适用场景:

  • 前后端数据传输(但此时可能与 VO 重叠,需根据团队规范区分)。
  • 微服务之间的接口调用(如服务 A 向服务 B 传递数据)。

示例:

// 服务间传输用户基本信息的DTO(隐藏敏感字段)
public class UserDTO implements Serializable {private Long id;private String username;// 不含password等敏感字段// getter/setter...
}

7、DAO(Data Access Object - 数据访问对象)

在 Java 开发中,DAO(Data Access Object,数据访问对象) 是一种设计模式,主要用于封装对数据源(如数据库、文件、缓存等)的访问操作,是业务逻辑层与数据层之间的桥梁。

DAO 的核心作用:

  • 隔离数据访问逻辑:将数据库连接、CRUD(增删改查)等操作封装在 DAO 中,使业务层无需关心数据存储的细节(如 SQL 语句、连接管理等)。
  • 统一数据访问接口:定义标准化的方法(如save()、getById()、update()),便于维护和替换数据源(例如从 MySQL 切换到 Oracle 时,只需修改 DAO 实现,无需改动业务代码)。

DAO 的典型组成:

  • DAO 接口:定义数据操作的抽象方法,明确 “做什么”。
  • DAO 实现类:实现接口中的方法,负责具体的数据库操作(如编写 SQL、管理连接、处理结果集)。
  • 实体类:通常是 PO/DO,作为数据传输的载体(DAO 操作的结果会封装成实体类返回给业务层)。

示例代码:
1、实体类(PO,与数据库表映射):

public class UserPO {private Long id;private String username;private Integer age;// getter/setter
}

2、DAO接口(定义操作规范)

public interface UserDAO {// 新增用户void save(UserPO user);// 根据ID查询用户UserPO getById(Long id);// 更新用户信息void update(UserPO user);// 删除用户void delete(Long id);
}

3、DAO 实现类(具体数据访问逻辑)

public class UserDAOImpl implements UserDAO {// 模拟数据库连接(实际开发中会用连接池)private Connection getConnection() {// 连接数据库的逻辑...return null;}@Overridepublic void save(UserPO user) {String sql = "INSERT INTO user (username, age) VALUES (?, ?)";// 执行SQL的逻辑(使用JDBC或MyBatis等框架)}@Overridepublic UserPO getById(Long id) {String sql = "SELECT * FROM user WHERE id = ?";// 查询并封装结果为UserPO返回return null;}// 其他方法实现...
}

DAO 在分层架构中的位置:
通常位于持久层,上层是业务逻辑层(Service),下层是数据源(数据库等):

业务层(Service) → DAO → 数据源(数据库)
  • 业务层通过调用 DAO 接口获取数据,无需关注数据如何存储和读取。
  • DAO 专注于数据访问,不包含业务逻辑(如权限校验、事务管理通常在 Service 层处理)。

实际开发中的应用:

  • 传统 JDBC 开发中,DAO 需手动管理连接、SQL 执行和结果集转换。
  • 主流框架(如 MyBatis、Spring Data JPA)会简化 DAO 的实现:
    • MyBatis 通过 Mapper 接口(本质是 DAO 接口)和 XML / 注解映射 SQL,无需手动编写实现类。
    • Spring Data JPA 通过继承JpaRepository接口,自动生成 CRUD 实现,进一步减少代码量。

DAO 的核心思想是 “数据访问与业务逻辑分离”,使系统更易维护、扩展和测试。

三、类型比较

概念全称核心用途数据来源典型场景主要特点
DOData Object(数据对象)表示任意数据源的数据载体可来自数据库、缓存、文件等任意数据源各层间通用的数据存储和传递字段与数据源结构对应,不包含业务逻辑;概念范围广,PO是其特例
VOValue Object(值对象)封装视图层展示数据多来自业务层组装(可能整合多个数据源)前端页面展示、接口响应返回字段与视图需求对应;通常只读;可能是多源数据的组合
POPersistent Object(持久化对象)与数据库表结构一一映射仅对应数据库表ORM框架的数据库CRUD操作字段与数据库表列严格对应;生命周期与数据库操作相关
BOBusiness Object(业务对象)封装核心业务逻辑和规则来自DAO获取的PO/DO或控制层传递的DTO业务流程实现、规则校验、计算逻辑包含业务逻辑;依赖DAO或DTO;与业务领域紧密相关
DAOData Access Object(数据访问对象)封装对数据源的访问操作直接操作数据源(数据库、文件等)数据库连接、SQL执行、结果集处理隔离数据访问逻辑;提供标准化接口;衔接业务层与数据源
DTOData Transfer Object(数据传输对象)跨层/跨服务高效传递数据单源或多源数据的裁剪、合并前后端数据传输、微服务间接口调用按需定义字段(减少冗余);可能实现序列化;提高传输效率

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93063.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93063.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/93063.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

todoList清单(HTML+CSS+JavaScript)

&#x1f30f;个人博客主页&#xff1a; 前言&#xff1a; 前段时间学习了JavaScript&#xff0c;然后写了一个todoList小项目&#xff0c;现在和大家分享一下我的清单以及如何实现的&#xff0c;希望对大家有所帮助 &#x1f525;&#x1f525;&#x1f525;文章专题&#xff…

Mac M1探索AnythingLLM+Ollama+知识库问答

AnythingLLM内置 RAG、AI Agent、可视化/无代码的 Agent 编排&#xff0c;支持多家模型与本地/云端向量库&#xff0c;并提供多用户与可嵌入的聊天组件&#xff0c;用来快速验证“知识 模型 工具”拼成的 AI 应用。 1 AnythingLLM、Ollama准备 1&#xff09;AnythingLLM 打…

【 Navicat Premium 17 完全图形化新手指南(从零开始)】

Navicat Premium 17 完全图形化新手指南&#xff08;从零开始&#xff09; 一、准备阶段&#xff1a;清理现有环境 1. 删除已创建的测试数据库&#xff08;如需重新开始&#xff09;打开Navicat Premium 17 双击桌面图标启动程序在左侧连接面板中找到你的MySQL连接&#xff08;…

Web学习笔记5

Javascript概述1、JS简介JS是运行在浏览器的脚本编程语言&#xff0c;最初用于Web表单的校验。现在的作用主要有三个&#xff1a;网页特效、表单验证、数据交互JS由三部分组成&#xff0c;分别是ECMAscript、DOM、BOM&#xff0c;其中ECMAscript规定了JS的基本语法和规则&#…

部署一个开源的证件照系统

以下数据来自官方网站,记录下来,方便自己 项目简介 &#x1f680; 谢谢你对我们的工作感兴趣。您可能还想查看我们在图像领域的其他成果&#xff0c;欢迎来信:zeyi.linswanhub.co. HivisionIDPhoto 旨在开发一种实用、系统性的证件照智能制作算法。 它利用一套完善的AI模型工作…

Linux客户端利用MinIO对服务器数据进行同步

接上篇 Windows客户端利用MinIO对服务器数据进行同步 本篇为Linux下 操作&#xff0c;先看下我本地的系统版本 所以我这里下载的话&#xff0c;是AMD64 文档在这 因为我这里只是需要用到客户端&#xff0c;获取数据而已&#xff0c;所以我只需要下载个MC工具用来数据获取就可以…

Docker 中部署 MySQL 5.7 并远程连接 Navicat 的完整指南

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

自己动手造个球平衡机器人

你是否曾对那些能够精妙地保持平衡的机器设备感到好奇&#xff1f; 从无人机到独轮平衡车&#xff0c;背后都蕴藏着复杂的控制系统。 今天&#xff0c;我们来介绍一个充满挑战与乐趣的项目——制作一个球平衡机器人。这不仅是一个酷炫的摆件&#xff0c;更是一次深入学习机器…

21.Linux HTTPS服务

Linux : HTTPS服务协议传输方式端口安全性HTTP明文传输80无加密&#xff0c;可被窃听HTTPS加密传输443HTTP SSL/TLS 数据加密&#xff08;防窃听&#xff09;身份认证&#xff08;防伪装&#xff09;完整性校验&#xff08;防篡改&#xff09;OpenSSL 证书操作核心命令命令选项…

SqlSugar 跨方法 操作临时表

.net项目中时长会有用到临时表的操作结果如下所示但是在SqlSugar中可能因为会话问题导致临时表访问受限 搜索到的方式var conn (SqlConnection)sugarClient.Ado.Connection;if (conn.State ! System.Data.ConnectionState.Open) {conn.Open();}using (var cmd new SqlCommand…

怎么用飞算javaAI实现视频逐帧截图并保存

相信很多朋友都遇到过这样的需求&#xff1a;想从视频中截取特定帧作为素材&#xff0c;却苦于没有简单易用的工具&#xff0c;要么操作复杂难以精准定位&#xff0c;要么导出的图片质量不佳。市面上的视频处理软件要么功能冗余&#xff0c;要么需要付费才能使用逐帧截取功能&a…

【2】Transformers快速入门:统计语言模型是啥?

一句话看懂统计语言模型核心任务&#xff1a;教电脑判断一句话 “像不像人话” &#xff08;比如“我爱吃苹果”✅ vs “苹果吃爱我”❌&#xff09;1. 早期&#xff1a;死磕语法规则 → 失败&#xff01; 科学家思路&#xff08;1970年前&#xff09;&#xff1a; 像语文老师一…

[激光原理与应用-230]:物理学主要分支、研究对象、衍生技术及职业方向解析

物理学作为自然科学的核心学科&#xff0c;其分支体系覆盖从微观粒子到宏观宇宙的广阔领域&#xff0c;并通过交叉融合衍生出众多前沿技术。以下从经典与现代物理学分支、交叉学科、技术转化及职业方向四个维度展开分析&#xff1a;一、经典物理学分支&#xff1a;宏观世界的基…

北京JAVA基础面试30天打卡08

RocketMQ、RabbitMQ与Kafka对比及常见问题解决方案 一、概述 消息队列&#xff08;Message Queue, MQ&#xff09;是企业IT系统内部通信的核心手段&#xff0c;用于提升性能、实现系统解耦和流量削峰。它具有低耦合、可靠投递、广播、流量控制、最终一致性等功能&#xff0c;是…

【CSS 变量】让你的 CSS “活”起来:深入理解 CSS 自定义属性与主题切换

【CSS 变量】让你的 CSS “活”起来&#xff1a;深入理解 CSS 自定义属性与主题切换 所属专栏&#xff1a; 《前端小技巧集合&#xff1a;让你的代码更优雅高效》 上一篇&#xff1a; 【CSS 视觉】无需JS&#xff0c;纯 CSS 实现酷炫视觉效果&#xff08;clip-path, filter, b…

RAG初步实战:从 PDF 到问答:我的第一个轻量级 RAG 系统(附详细项目代码内容与说明)

RAG初步实战&#xff1a;从 PDF 到问答&#xff1a;我的第一个轻量级 RAG 系统 项目背景与目标 在大模型逐渐普及的今天&#xff0c;Retrieval-Augmented Generation&#xff08;RAG&#xff0c;检索增强生成&#xff09;作为连接“知识库”和“大语言模型”的核心范式&#…

自主泊车算法

看我的git 在 open space 空间下规划出⼀条⾃⻋到停⻋位的⽆碰撞轨迹 满⾜平滑约束 可跟踪 考虑动态障碍物约束 在路径不可⽤的情况下 具备重规划能⼒ 重规划时能够做到⽆缝切换 即从原路径⽆缝切换到重规划路径 ⽆明显体感 规划频率 10HZ

USB 2.0 学习(2)- 连接

上回说到 usb的信号 k 状态和 j 状态&#xff0c;补充一下 usb的一些电气小知识。 1.USB设备有四根线 电源线VBus、 D、 D-、 地线GND 2.USB主机端的 D 和 D-各有1个15k下拉电阻&#xff0c;这是为了准确检测 D还是D-线上电平的变化 因为USB总线检测USB设备是低速还是全速设备…

解锁 Appium Inspector:移动端 UI 自动化定位的利器

​ 在移动端 UI 自动化测试中&#xff0c;元素定位是绕不开的核心环节。无论是 Android 还是 iOS 应用&#xff0c;能否精准、高效地定位到界面元素&#xff0c;直接决定了自动化脚本的稳定性和可维护性。而 Appium Inspector 作为 Appium 生态中专门用于元素定位的工具&#…

机器学习概念1

了解机器学习1、什么是机器学习机器学习是一门通过编程让计算机从数据中进行学习的科学 通用定义&#xff1a;机器学习是一个研究领域让计算机无须进行明确编程就具备学习能力 工程化定义&#xff1a;一个计算机程序利用经验E来学习任务T&#xff0c;性能是P&#xff0c;如果针…