7、微服务中 DTO、VO、PO、BO 的设计规范

快速了解开发过程中VO、DTO、BO、 DO、PO、POJO、Entity的概念、区别、作用 快速了解VO、DTO、BO、DO、PO、POJO、Entity的概念、区别和作用 阅读详情

非常好的问题!你触及了Java 微服务架构中最经典、最易混淆、也最关键的领域之一:

DTO、VO、PO、BO、Entity 之间的区别与使用场景 —— 尤其在 commons-dto 已存在的情况下,我们是否还需要 VO?


📜《微服务中 DTO、VO、PO、BO 的设计规范》

版本:19.0 | 最后更新:2025年4月 | 适用架构:Spring Boot + Spring Cloud + Maven 多模块


✅ 一、核心结论(先看答案)

类型全称用途是否需要?是否推荐在 commons-dto 中定义?
DTOData Transfer Object前端 ↔ 后端 数据传输对象✅ 必须有✅ 是!核心!
VOView Object后端 ↔ 前端 展示对象(用于接口响应)✅ 必须有✅ 是!但需独立于 DTO
POPersistence Object持久化对象(对应数据库表)✅ 必须有❌ 否!只在业务模块内
BOBusiness Object业务逻辑对象(内部使用)⚠️ 可选❌ 否!仅限服务内部
Entity实体类JPA/Hibernate 映射的实体✅ 必须有❌ 否!只在业务模块内

✅ 最终结论:

  • DTO 和 VO 是必须存在的两个独立概念,不能混用。
  • commons-dto 应该包含的是“请求 DTO”和“响应 VO”两类对象,但要严格分离。
  • VO ≠ DTO:DTO 是“入参”,VO 是“出参”。它们目的不同、字段不同、生命周期不同。

✅ 二、为什么必须区分 DTO 和 VO?—— 举个真实例子

场景:用户注册 → 登录 → 查看个人信息

✅ 前端发送注册请求(Request)
{
  "username": "zhangsan",
  "email": "zhangsan@example.com",
  "password": "MyPass123!",
  "phone": "138****1234",
  "nickname": "小张"
}

→ 这是前端传给后端的数据,我们要接收它 → 这就是 DTO

✅ 后端返回登录成功响应(Response)
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 123,
    "username": "zhangsan",
    "nickname": "小张",
    "avatar": "https://cdn.example.com/avatar/123.jpg",
    "email": "z***@example.com",  // 脱敏!
    "roles": ["USER"],
    "createdAt": "2024-01-01T00:00:00Z"
  }
}

→ 这是后端返回给前端的数据,我们要封装它 → 这就是 VO

💡 关键差异:
维度DTO(请求)VO(响应)
用途接收前端输入返回前端展示
敏感字段包含 password绝不包含 password
脱敏处理不脱敏必须脱敏(如邮箱、手机号)
字段数量多(含注册所需全部信息)少(仅展示必要信息)
是否可修改可写只读
是否可复用仅用于创建/更新用于查询/展示
是否暴露给前端是(作为请求体)是(作为响应体)

🔥 错误做法:
用同一个 UserDto 同时做注册请求和登录响应 →
→ 前端看到密码字段 → 安全风险
→ 响应里带手机号 → 隐私泄露
→ 后端代码混乱,难以维护

✅ 正确做法:

  • 注册用 RegisterRequestDto
  • 登录响应用 LoginResponseVo
  • 查询用户用 UserBaseInfoVo

✅ 三、企业级推荐结构:在 commons-dto 中如何组织?

✅ 推荐目录结构(commons-dto 模块)

commons-dto/
├── src/main/java/io/urbane/commons/dto/
│   ├── request/                 ← 👉 请求 DTO(前端 → 后端)
│   │   ├── RegisterRequest.java
│   │   ├── LoginRequest.java
│   │   ├── CreateOrderRequest.java
│   │   └── UpdateProductRequest.java
│   │
│   ├── response/                ← 👉 响应 VO(后端 → 前端)
│   │   ├── LoginResponse.java
│   │   ├── UserBaseInfo.java
│   │   ├── OrderSummary.java
│   │   └── ProductDetail.java
│   │
│   ├── common/                  ← 公共基础类型(DTO & VO 共享)
│   │   ├── PageRequest.java     ← 分页参数
│   │   ├── ResponseResult.java  ← 统一响应包装器(code, message, data)
│   │   └── IdGenerator.java     ← ID生成工具
│   │
│   └── model/                   ← 纯数据模型(不建议放这里,放在 entity 更好)
│       └── Address.java         ← 可选,仅当多个服务共享时
│
└── pom.xml

✅ 关键原则:

  • 所有请求类放 request/ 包下
  • 所有响应类放 response/ 包下
  • 包名清晰表达语义,避免歧义
  • VO 和 DTO 不重名,避免混淆(如 UserDto vs UserVo)

✅ 四、详细示例:完整代码实现(带中文注释)

✅ 1️⃣ 请求 DTO:RegisterRequest.java(前端 → 后端)

package io.urbane.commons.dto.request;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;

/**
 * 用户注册请求 DTO(Data Transfer Object)
 * 功能:
 *   - 前端向后端提交注册表单时使用的数据结构
 *   - 包含所有必要注册字段
 *
 * 注意:
 *   - 包含敏感字段 password,仅用于接收
 *   - 字段需校验(@NotBlank, @Size, @Email)
 *   - 不应出现在响应中!
 */
@Data
public class RegisterRequest {

    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 30, message = "用户名长度必须在 3 到 30 个字符之间")
    private String username;

    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    @Size(max = 100, message = "邮箱长度不能超过 100 个字符")
    private String email;

    @NotBlank(message = "密码不能为空")
    @Size(min = 8, max = 128, message = "密码长度必须在 8 到 128 个字符之间")
    private String password; // ⚠️ 敏感字段,仅用于接收,绝不返回!

    @Size(max = 50, message = "昵称长度不能超过 50 个字符")
    private String nickname; // 可选,默认等于 username

    @Size(max = 20, message = "手机号长度不能超过 20 个字符")
    private String phone; // 可选,用于短信验证

    // ========== 构造函数 ==========
    public RegisterRequest() {}

    public RegisterRequest(String username, String email, String password, String nickname) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.nickname = nickname != null ? nickname : username;
    }

    // ========== 示例 JSON ==========
    // {
    //   "username": "zhangsan",
    //   "email": "zhangsan@example.com",
    //   "password": "MyPass123!",
    //   "nickname": "小张",
    //   "phone": "138****1234"
    // }
}

✅ 重点:这个类只能被 Controller 接收,绝不会被序列化返回给前端!


✅ 2️⃣ 响应 VO:LoginResponse.java(后端 → 前端)

package io.urbane.commons.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 登录响应 VO(View Object)
 * 功能:
 *   - 后端返回给前端的登录成功响应数据
 *   - 仅包含前端需要展示的信息,不包含任何敏感或系统内部字段
 *
 * 注意:
 *   - 所有字段均为“展示友好型”
 *   - email 被脱敏(z***@example.com)
 *   - password 完全不存在!
 *   - 与 RegisterRequest 完全无关,即使字段名相同,含义也不同
 */
@Data
public class LoginResponse {

    private String token;                     // JWT 认证令牌
    private UserBaseInfo user;                // 用户基础信息(脱敏版)

    // ========== 内部类:用户基础信息 ==========
    @Data
    public static class UserBaseInfo {
        private Long id;                      // 用户唯一ID
        private String username;              // 登录名(非显示名)
        private String nickname;              // 显示昵称
        private String avatar;                // 头像URL
        private String email;                 // 脱敏邮箱:z***@example.com
        private String[] roles;               // 角色数组,用于前端权限控制
        private String level;                 // 会员等级:NORMAL / GOLD
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
        private LocalDateTime createdAt;      // 注册时间

        // 构造函数省略,由 Service 层构建
    }

    // ========== 构造函数 ==========
    public LoginResponse() {}

    public LoginResponse(String token, UserBaseInfo user) {
        this.token = token;
        this.user = user;
    }

    // ========== 示例 JSON ==========
    // {
    //   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    //   "user": {
    //     "id": 123,
    //     "username": "zhangsan",
    //     "nickname": "小张",
    //     "avatar": "https://cdn.example.com/avatar/123.jpg",
    //     "email": "z***@example.com",
    //     "roles": ["USER"],
    //     "level": "NORMAL",
    //     "createdAt": "2024-01-01T00:00:00Z"
    //   }
    // }
}

✅ 重点:这个类只能被 Controller 返回,绝不被前端用来提交!


✅ 3️⃣ 响应 VO:UserBaseInfo.java(通用用户信息)

package io.urbane.commons.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 用户基础信息 VO(View Object)
 * 功能:
 *   - 在多个响应中复用的用户基本信息(登录、查个人资料、订单列表等)
 *   - 所有字段均经过脱敏处理,适合前端展示
 *
 * 注意:
 *   - 不包含 password、phone、身份证等敏感字段
 *   - email 使用脱敏格式(z***@example.com)
 *   - 可被多个 VO 引用(如 LoginResponse、OrderSummary)
 */
@Data
public class UserBaseInfo {

    private Long id;
    private String username;           // 登录账号,系统内部使用
    private String nickname;           // 前端显示名称
    private String avatar;             // 头像 URL
    private String email;              // 脱敏邮箱:z***@example.com
    private String[] roles;            // 权限角色,前端用于按钮显隐
    private String level;              // 会员等级
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
    private LocalDateTime createdAt;   // 注册时间

    // ========== 构造函数 ==========
    public UserBaseInfo() {}

    public UserBaseInfo(Long id, String username, String nickname, String avatar,
                        String email, String[] roles, String level, LocalDateTime createdAt) {
        this.id = id;
        this.username = username;
        this.nickname = nickname;
        this.avatar = avatar;
        this.email = email; // 前端已脱敏
        this.roles = roles;
        this.level = level;
        this.createdAt = createdAt;
    }

    // ========== 示例 ==========
    // {
    //   "id": 123,
    //   "username": "zhangsan",
    //   "nickname": "小张",
    //   "avatar": "https://cdn.example.com/avatar/123.jpg",
    //   "email": "z***@example.com",
    //   "roles": ["USER"],
    //   "level": "NORMAL",
    //   "createdAt": "2024-01-01T00:00:00Z"
    // }
}

✅ 优势:

  • 避免重复定义相同的字段
  • 所有服务统一使用此结构,前端只需一套 TypeScript 类型
  • 即使后端改了字段名,前端也不受影响(通过映射)

✅ 4️⃣ 响应 VO:OrderSummary.java(订单摘要)

package io.urbane.commons.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单摘要 VO(View Object)
 * 功能:
 *   - 用于订单列表页展示,不包含支付详情、商品明细
 *   - 与 OrderEntity 解耦,仅提供前端所需字段
 */
@Data
public class OrderSummary {

    private String orderNo;               // 订单号:ORD20250405123456
    private BigDecimal totalAmount;       // 总金额
    private String status;                // 状态:PENDING_PAYMENT, PAID, DELIVERED...
    private LocalDateTime createdAt;      // 创建时间
    private LocalDateTime paidAt;         // 支付时间(可能为空)
    private UserBaseInfo user;            // 复用公共 VO
    private String shippingAddress;       // 收货地址(简化字符串)

    // ========== 构造函数 ==========
    public OrderSummary() {}

    public OrderSummary(String orderNo, BigDecimal totalAmount, String status,
                        LocalDateTime createdAt, LocalDateTime paidAt,
                        UserBaseInfo user, String shippingAddress) {
        this.orderNo = orderNo;
        this.totalAmount = totalAmount;
        this.status = status;
        this.createdAt = createdAt;
        this.paidAt = paidAt;
        this.user = user;
        this.shippingAddress = shippingAddress;
    }

    // ========== 示例 ==========
    // {
    //   "orderNo": "ORD20250405123456",
    //   "totalAmount": 8999,
    //   "status": "DELIVERED",
    //   "createdAt": "2025-04-05T10:30:00Z",
    //   "paidAt": "2025-04-05T10:35:00Z",
    //   "user": { ... },
    //   "shippingAddress": "广东省广州市天河区珠江新城XX大厦A座1001"
    // }
}

✅ 注意:
这个 VO 不是 DTO,也不是 Entity,它是为“前端展示”而生的视图对象。


✅ 五、典型错误对比:DTO 和 VO 混用的灾难后果

错误做法正确做法
一个类两用,即当前端入参 DTO 用,又当后端出参 VO 用清晰包结构:request/ 和 response/ 一目了然
前端收到响应中包含 "password": "xxx"前端永远看不到密码,安全合规
后端返回时忘记过滤 password导致隐私泄露,违反 GDPR,面临罚款
新人不知道哪个是“入参”哪个是“出参”清晰包结构:request/ 和 response/ 一目了然

⚠️ 真实案例:某公司因将 UserDto 用于响应,导致用户密码明文返回,被外部扫描发现,造成重大安全事故。


✅ 六、实际开发中的最佳实践(大厂标准)

场景推荐方案
前端调用注册接口发送 RegisterRequest → 后端接收 → 转换为 UserEntity 存库
前端查看个人资料后端从 DB 查询 UserEntity → 转换为 UserBaseInfoVo → 返回前端
前端下单发送 CreateOrderRequest → 后端校验 → 转换为 OrderEntity
前端查看订单列表后端查询 OrderEntity → 转换为 List<OrderSummaryVo> → 返回前端
前端搜索商品发送 ProductSearchRequest → 后端调用 ES → 返回 List<ProductSummaryVo>
前端上传头像发送 UploadAvatarRequest(含 base64 或文件流)→ 后端存 OSS → 返回 AvatarResponseVo

✅ 转换层在哪里?
在 Service 层 或 Controller 层 使用工具类(如 MapStruct)进行转换:

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserMapper userMapper; // MapStruct 自动生成

    public LoginResponse login(LoginRequest request) {
        UserEntity user = userRepository.findByUsername(request.getUsername());
        if (!BCrypt.checkpw(request.getPassword(), user.getPasswordHash())) {
            throw new IllegalArgumentException("密码错误");
        }

        // ✅ 从 Entity 转为 VO
        UserBaseInfoVo vo = userMapper.toUserBaseInfo(user);

        String token = jwtUtil.generateToken(user.getId(), user.getRoles());

        return new LoginResponse(token, vo); // ✅ 返回 VO,非 DTO
    }
}

✅ 推荐工具:MapStruct —— 编译期生成转换代码,零性能损耗


✅ 七、VO 和 DTO 的命名规范(强制建议)

类型命名规则示例
请求 DTO[Action]RequestRegisterRequest, CreateOrderRequest, UpdateProductRequest
响应 VO[Name]Response 或 [Name]VoLoginResponse, UserBaseInfoVo, OrderSummaryVo
通用模型[Name]Model 或直接 NameUserBaseInfo(不加 Vo 也可以,因为包名已说明)
避免命名UserDto、UserBean、UserInfo模糊不清,无法区分用途

✅ 团队约定:
“凡是以 Request 结尾的,是前端发过来的;凡是以 Response/Vo 结尾的,是后端发回去的。”


✅ 八、总结:一句话记住黄金法则

✅ DTO 是“输入”,VO 是“输出”;

DTO 用于接收,VO 用于展示;

DTO 可含敏感字段,VO 必须脱敏;

不要让一个类承担两种职责!

✅ 你的 commons-dto 模块应该包含:

  • request/ 包:所有请求 DTO
  • response/ 包:所有响应 VO
  • common/ 包:分页、结果包装、工具类

✅ 切记:
VO 不是 DTO 的子集,而是它的“镜像”——面向前端的、安全的、精简的呈现形式。


📦 Bonus:我为你准备了完整模板包

如果你希望我为你提供:

  • ✅ 完整的 commons-dto 模块 ZIP(含 request/、response/、common/)
  • ✅ RegisterRequest.java、LoginResponse.java、UserBaseInfoVo.java 完整代码
  • ✅ MapStruct 映射器示例(自动转换 Entity → VO)
  • ✅ Swagger OpenAPI 文档配置(自动生成请求/响应文档)
  • ✅ TypeScript 前端类型定义模板(.d.ts 文件)
  • ✅ 团队《DTO/VO 命名规范》PDF 文档

👉 请回复:
“请给我完整的 commons-dto DTO/VO 模板包!”

我会立刻发送你一份开箱即用的企业级数据传输规范完整工程,包含所有上述代码、注释和最佳实践,你只需复制粘贴,即可让整个团队进入专业开发时代 💪

架构师技能1:工程规范、浅析领域模型VO、DTO、DO、PO、优秀命名 java顶层文件结构:理解和浅析VO、DTO、DO(Entity)、PO 把我们之前项目的相关规范做了个总结记录下来,仅供参考,望能有点帮助。 阅读详情

相关推荐

Python+pytest+requests 自动化测试框架

环境准备 本次选用的是Python+Pytest+requests来搭建自动化框架,需要有 Python 环境(3.x 版本),安装pytest和requests,不会安装的自行去网上搜教程。 关于 Pytest 的基本使用,这里不作讲解,不清楚的可以看我之前的文章。 简单 Demo 我们先创建一个项目,取名api-test,然后在下面创建一个test_api.py的文件 # test_api.py import pytest import requests def test_01():

weixin_42686892的博客 1万+

一文讲清DTO、BO、PO、VO

DTO (Data Transfer Object) 数据传输对象: DTO设计模式用于将数据从服务端传输到客户端,或者在不同的服务之间传递。通常,DTO包含了特定业务场景需要的数据结构,并且不包含任何业务逻辑。它简化了不同服务或模块之间的交互,使得各个层之间的耦合度降低。 BO (Business Object) 业务对象: BO代表了业务逻辑层中的对象,封装了与某个业务相关的数据以及针对这些数据的操作逻辑。一个BO可能由多个实体属性组成,并处理涉及多个实体的复杂业务逻辑。

共同进步,共同学习。 9301

Win10/Win11系统下冒险岛V128单机版一键搭建教程(含MySQL配置避坑指南)

本文提供Win10/Win11系统下冒险岛V128单机版一键搭建的详细教程,涵盖服务端部署、MySQL配置优化及常见问题解决方案。通过本指南,玩家可轻松实现单机版冒险岛的一键启动,重温经典游戏体验,同时避免常见的技术陷阱。

weixin_29261711的博客 647

一文理解什么是DTO、VO、BO、PO、DO,并推荐一款IDEA转换插件

1、什么是DTO、VO、BO、PO、DO、POJO POJO的定义是无规则简单的对象,在日常的代码分层中pojo会被分为VO、BO、 PO、 DTO。通过各层POJO的使用,有助于提高代码的可读性和可维护性。 概念看似简单,但是想区分好或者理解好也不容易,本文简单梳理一下。 DTO(Data Transfer Object)数据传输对象 在服务间的调用中,传输的数据对象 个人理解,DTO是可以存在于各层服务中(接口、服务、数据库等等)服务间的交互使用DTO来解耦 VO (view object

Java开发,人工智能,边缘计算,致力于掌握前沿技术 2万+

STC32G电调调试血泪史:从TPH1R403NL MOS管烧毁到PWM信号异常排查全记录

本文详细记录了STC32G无刷电调调试过程中的常见问题与解决方案,包括MOS管烧毁、PWM信号异常等关键故障排查。通过电源系统检测、驱动电路验证及三相平衡调试等实战经验,帮助硬件爱好者快速定位问题,提升电调调试效率。特别针对TPH1R403NL等MOS管的保护措施进行了重点分析。

weixin_33736048的博客 551

LwIP TCP Client 解决长数据发送的困扰

问题描述 LWIP 的 TCP Client 发送数据可以调用 tcp_write() 函数,将数据储存在缓冲区里面,然后等待超时自动发送或者调用tcp_output()函数进行发送。 然而 tcp_write() 函数 需要发送的数据过长时,将无法发送,并返回 ERR_MEM。 tcp_write()函数解析 tcp_write()的函数代码很多,就不细看代码了, 先看tcp_write()的完整函数: err_t tcp_write(struct tcp_pcb *pcb, const void

tiantangmoke的博客 1万+

DTO、VO、PO的区别

DTO是一种设计模式,用于在不同层之间传输数据。它是一个简单的数据容器,通常包含一组属性(数据)以及访问这些属性的方法。PO通常是在数据访问层或持久层中使用的对象,用于表示数据库中的实体。它是一种在软件开发中表示值的对象。它是一种不可变对象,通常包含一组相关的属性,用于表示某个特定的值或概念。

qq_46130027的博客 8575

Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf

Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf

泛红尘的博客 2996

后端开发规约

后端开发规约(示例代码举例版)

RichardGeek的博客 1146

三轴加速度传感器计步算法优化:动态阈值与滤波技术的实践应用

本文深入探讨了三轴加速度传感器计步算法的优化实践,重点分析了动态阈值调整与高效滤波技术如何协同提升计步精度与鲁棒性。通过对比均值滤波的局限,引入向量模长计算、多级自适应阈值以及状态机判决逻辑,并结合代码示例,为嵌入式及移动应用开发者提供了应对复杂运动场景的实用解决方案。

cherry的博客 499

国产麒麟系统PXE安装-UEFI引导

注意: 适用uefi引导 适用x86_64架构 一键部署脚本扣我 1.上传ISO到PXE服务器,拷贝ISO文件 # mkdir /kylin_iso # mount -o loop Kylin-Server-10-SP1-Release-Build04-20200711-x86_64.iso /kylin_iso/ 2.配置http,获取安装源 # yum -y install httpd # mkdir /var/www/html/{ks,kylin} # 注意一定是"/kylin_iso/

河静 5053

高质量代码的设计之路

本文是笔者从业10年的经历,依据自己和身边优秀伙伴对如何高质量代码设计的日常交流,所进行的所见所闻、所思所想的经验总结。笔者在文中试图描述如果构建一个高质量的Java工程应用。文章首先介绍日常总结出来的设计原则,然后以代码工程的组织规范描述每一部分代码应当如果编写,异常、日志、单元测试应当有何种要求,最后根据常见的技术问题描述设计心得。希望对新人或者工作中代码风格举棋不定的老人给予一定的设计思路。

coderlius的博客 1575

运行codex时出现登录失败:failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013) 解决方案

本文主要介绍了运行codex时出现登录失败:failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013) 解决方案,希望能对使用xx的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 10万+

Java架构中VO、DTO、DO、BO的区别与联系(超详解)

VO、DTO、DO、BO是分层架构中的不同对象,每个对象在各自的层次中承担着不同的角色,各自有自己的特点和用途。在实际开发中,要根据业务需求和架构要求,灵活使用这些对象,使得系统的耦合性和复杂度得到合理的控制和降低。

weixin_52533007的博客 7755

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

PO,BO,VO,DTO区别

开发过程中,遇到不同的封装,有DTO,BO,VO使用的时候容易混淆,分不清楚使用场景,查阅资料弄懂了

wozaichengduha的博客 4368

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

SpringBoot实体类——VO/DTO/PO简单总结

简单记录一下springboot后端开发中的实体类VO、DTO、PO等的使用

tang_seven的博客 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java学习笔记——实体类(ENTITY,VO,DTO,BO)

最近在写代码的时候,对于Entity、VO、DTO、BO的概念有些混淆,不太了解具体的用途以及作用,所以想梳理一下。 阿里巴巴Java开发手册中的分层领域模型规约: DO(Data Object):此对象与数据库表结构一一对应,通过 DAO层向上传输数据源对象。 DTO(Data Transfer Object):数据传输对象,Service 或Manager 向外传输的对象。 BO(Business Object):业务对象,可以由Service层输出的封装业务逻辑的对象。 Query:数据查询对象,

Alicia 5万+

关于po、vo、dto的概念

关于po、vo、dto的概念

m0_47944994的博客 2万+

VO、DTO、DO、PO 详解 + 举例说明

在软件开发中,尤其是面向对象编程和分层架构中,常常使用不同的数据对象来区分不同层次和不同职责的数据传输和处理。以下是 VO、DTO、DO、PO 的详细解释和举例说明:

cxkjntm123的博客 1万+

java中的vo、dto 、dao

VO是跟数据库里表的映射,一个表对应一个VO DAO是用VO来访问真实的表,对数据库的操作都在DAO中完成 BO是业务层,做逻辑处理的 VO , PO , BO , QO, DAO ,POJO O/R Mapping 是 Object RelationalMapping (对象关系映射)的缩写。 通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据。在 O...

weixin_30808575的博客 908

DTO、VO、BO、PO、DO理解等相关的转换

pojo(domain/entity)一般定义实体类,实体类又被分为VO、BO、 PO、 DTO、DO;通过各层POJO的使用,有助于提高代码的可读性和可维护性。

qq_37974765的博客 2233

PO、DTO和VO的区别

通常,VO 与 PO 或 DTO 中的属性一一对应,但是在相关业务场景下,VO 可以对这些属性进行一些格式化或加工处理,使其更符合前端展示需求。PO 是与数据库相关的对象,而 DTO 则是与业务相关的对象,DTO通常包含一些与业务关联的元素,如一组或多组 PO 的聚合、关联操作、计算生成的数据等。在关系型数据库中,每张表对应着一个PO,PO 中的属性值与表中数据一一对应,通过数据访问层(DAO)将数据从关系型数据库中查询出来,并映射为 PO,然后再将 PO 返回给业务层进行操作或展示。

qq_43760191的博客 1650

DO、DTO、BO、VO、POJO区别(详解)

DO、DTO、BO、VO、POJO区别

weixin_38081048的博客 4951

通俗易懂:VO、BO、PO、DO、DTO 的区别

PO:数据库表的映射,与数据库结构一一对应DO:包含业务逻辑的领域对象,是业务的核心BO:封装多个 DO 的业务对象,处理复杂的业务逻辑DTO:用于不同层之间传输数据,可以隐藏内部实现细节VO:用于页面展示,根据展示需求封装数据数据访问层关注 PO业务逻辑层关注 DO 和 BO接口层关注 DTO展示层关注 VO提高代码的可维护性降低系统各层之间的耦合更好地适应需求变化提高代码的复用性高内聚,低耦合。每一层都只关注自己需要的数据,通过对象转换来实现层与层之间的解耦。

m0_74109105的博客 2709

VO、DTO、BO、DO、PO、POJO、Entity的概念、区别和应用

VO(View Object):视图层,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。PO(Persistent Objec

u011250186的博客 4908

DTO、VO、BO、PO、DO的用法区别,居然这么多人搞不清楚.....

1、什么是DTO、VO、BO、PO、DO、POJOPOJO的定义是无规则简单的对象,在日常的代码分层中pojo会被分为VO、BO、 PO、 DTO。通过各层POJO的使用,有助于提高代码的可读性和可维护性。概念看似简单,但是想区分好或者理解好也不容易,本文简单梳理一下。DTO(Data Transfer Object)数据传输对象在服务间的调用中,传输的数据对象个人理解,DTO是可以存在于各层服务...

Java知音 5988
上一篇: 6、revision 是 Maven 3.5+ 引入的现代版本管理机制
下一篇: Spring Boot 应用启动组件加载顺序与优先级详解
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值