一文讲清BO、PO、VO、DTO

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程​​https://www.captainai.net/troubleshooter

BO、PO、VO、DTO是什么?

在后端开发中,比如传统的MVC架构和现在流行的DDD架构,经常会使用到下列几种对象的概念:

BO(Business Object)业务对象:BO代表了业务逻辑层中的对象,封装了与某个业务相关的数据以及针对这些数据的操作逻辑。一个BO可能由多个实体属性组成,并处理涉及多个实体的复杂业务逻辑。

PO(Persistent Object)持久化对象:PO主要用来表示数据库表的一条记录,它的属性和数据库表的字段相对应。通常在持久层(如Hibernate、JPA等ORM框架)中使用,主要用于操作数据库,如保存、更新和查询数据。

VO(Value Object)值对象:VO是视图层的对象,通常用于封装展示给用户的数据,它可以和数据库表对应,也可以根据UI界面需求进行定制。VO的主要目的是在页面展示时只携带必要的数据,从而避免把大量不必要的数据暴露给前端。

DTO(Data Transfer Object)数据传输对象:DTO设计模式用于将数据从服务端传输到客户端,或者在不同的服务之间传递。通常,DTO包含了特定业务场景需要的数据结构,并且不包含任何业务逻辑。它简化了不同服务或模块之间的交互,使得各个层之间的耦合度降低。

举个实际代码的例子,这里暂不给出VO,在最后的总结会讲这个VO。

PO-User

@Data
public class User implements Serializable{
    private Long id;
 
    private String username;
 
    private String password;
 
    private String identityCard;
 
    private String gender;
 
    private String location;
 
    private String userImage;
 
    private String phoneNumber;
 
    private String createTime;
 
    private String updateTime;
 
    @TableLogic
    private int isDelete;
}

DTO-UserDTO

@Data
public class UserDTO implements Serializable{
    private Long id;
 
    private String username;
 
    private String password;
 
    private String identityCard;
 
    private String gender;
 
    private String location;
 
    private String userImage;
 
    private String phoneNumber;
}

BO-UserLoginBO、UserUpdateBO

@Data
public class UserLoginBO implements Serializable{
    private String username;
 
    private String password;
}

@Data
public class UserUpdateBO implements Serializable{
    private Long id;
 
    private String username;
 
    private String password;
 
    private String identityCard;
 
    private String gender;
 
    private String location;
 
    private String userImage;
 
    private String phoneNumber;
}

    从上面这个例子大家能看出来区别不?

    UserDTO是一个大的入口,它可以接收整个模块的参数。

    BO则是在进入Service层之前对UserDTO的数据进行过滤,并且对边界进行控制,最后在进入infra层(基础设施层)之前转为PO。

    其实BO也可以像UserDTO那样,直接一个UserBO包含UserLoginBO和UserUpdateBO,单纯的做模型转换,不做值过滤也可以。

    在后端开发中是怎么用的?

    总结

    为什么我们通篇没有讲关于VO的事情呢?

    我个人的理解是DTO能解决的事情就没有必要再加一个VO,我们可以弄一个全局配置,将DTO里面为null值的字段全都过滤掉。这样就没有必要将数据传给前端的时候再多加一个VO。

    给出代码示例,这样配置就可以把DTO中为null的值过滤掉,不会序列化发给前端。

    @Configuration
    public class GlobalConfig extends WebMvcConfigurationSupport {
    
        @Override
        protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            super.configureMessageConverters(converters);
            converters.add(mappingJackson2HttpMessageConverter());
        }
    
        /**
         * 自定义mappingJackson2HttpMessageConverter
         * 目前实现:空值忽略,空字段可返回
         */
        private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            return new MappingJackson2HttpMessageConverter(objectMapper);
        }
    }
    ### POVODTO 的概念及区别 #### 一、PO (Persistent Object, 持久化对象) PO 是指持久化对象,主要用来表示数据库表结构的对象。它通常是 ORM(Object-Relational Mapping)框架中的实体类,与数据库中的表一一对应。PO 中的属性一般直接映射到数据库表的列。 在 Java 开发中,PO 主要用于业务层和持久层之间的数据交互[^4]。它的设计原则是简单明了,仅包含基本的数据字段及其 getter 和 setter 方法。 ```java public class UserPO { private Long id; private String name; private Integer age; // Getter and Setter methods } ``` --- #### 二、VO (View Object, 视图对象) VO 是视图对象,主要用于前端展示的需求。它是专门为前端页面定制的数据结构,可能由多个 PO 或其他对象组合而成。VO 只保留前端需要显示的信息,不包含多余的内容。 VO 的特点是高度灵活,能够满足复杂的前端展示需求。例如,在某些情况下,VO 需要在原始数据的基础上增加计算字段或格式化的字符串[^1]。 ```java public class UserVO { private String displayName; // 前端展示名称 private int userAge; // 年龄 private List<String> roles;// 用户角色列表 // Getter and Setter methods } ``` --- #### 三、DTO (Data Transfer Object, 数据传输对象) DTO 是数据传输对象,主要用于不同服务或模块间的数据交换。它可以跨越网络边界,将一组相关联的数据打包成一个整体进行传输。相比于 VODTO 更注重性能优化和跨系统的兼容性[^3]。 DTO 不一定完全匹配数据库表结构,而是根据具体业务需求定义其字段。因此,DTO 往往更轻量化,只携带必要的信息。 ```java public class UserDTO { private String username; private String email; // Getter and Setter methods } ``` --- #### 四、POVODTO 的区别 | **对比维度** | **PO** | **VO** | **DTO** | |------------------|-------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------| | **用途** | 表示数据库表结构,用于持久化操作 | 专为前端展示设计,提供适配前端界面的数据 | 跨服务或模块间的高效数据传输 | | **位置** | 持久层 | 接口层至前端 | 各种服务或模块之间 | | **特点** | 映射数据库表结构 | 定制化强,可包含额外计算字段 | 注重性能和简洁性 | | **依赖关系** | 直接关联数据库 | 可能基于 PO 组合生成 | 可来源于 PO 或其他对象 | --- #### 五、使用场景分析 - **PO**: 当需要访问数据库并执行 CRUD 操作时,应优先考虑使用 PO 对象。例如,在 Spring Data JPA 中,Entity 类就是典型的 PO 实现。 - **VO**: 如果目标是构建适合前端渲染的数据,则应该选用 VO。比如在一个电商网站中,商品详情页可能会涉及价格折扣后的金额、库存状态等多种信息,这些都可以通过 VO 来封装。 - **DTO**: 在微服务架构下或者远程调用 API 场景里,推荐采用 DTO 进行参数传递和服务响应。这样不仅可以减少不必要的数据暴露,还能提高通信效率[^2]。 ---
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值