【Java 规范】Entity、DTO、VO 到底有什么区别?详解 JavaBean 标准写法

在 Java 开发中,我们经常会看到各种各样的 Bean:UserUserDTOUserVO。很多初学者会觉得:这不都是类吗?为什么写得这么复杂?

本文将带你深度解析 JavaBean 的分层架构 以及各自的标准写法。


一、 核心概念:为什么需要分层?

在 MVC 架构中,数据在 数据库 -> 业务层 -> 表现层 之间流动。如果直接将数据库表结构(Entity)直接返回给前端,会产生以下问题:

  1. 隐私泄露:数据库中的 passwordsalt 等字段不应展示给用户。
  2. 数据冗余:前端可能只需要两个字段,你却返回了整张表。
  3. 耦合性高:数据库表一旦修改,前端接口必须跟着改。

二、 各类 Bean 的定义与职能

1. Entity (实体类 / PO)

  • 职能:与数据库表 一 一对应
  • 命名:通常与表名一致,如 UserEntity 或直接叫 User
  • 要求:字段名建议使用驼峰命名,对应数据库的下划线命名。

2. DTO (Data Transfer Object - 数据传输对象)

  • 职能:用于 Service 层 之间,或者 Controller 与 Service 之间的数据传递。
  • 特点:它是 Entity 的“精简版”或“聚合版”。例如,注册时收到的表单数据就是一个 DTO。

3. VO (View Object - 视图对象)

  • 职能:用于 返回给前端展示
  • 特点:数据的格式完全根据页面显示来定。比如数据库存的是 1/0,VO 中可以处理成 男/女

三、 标准代码实现 (实战示例)

假设我们有一个“用户领养宠物”的场景。

1. Entity 层 (映射数据库)

/**
 * 对应数据库 pet 表
 */
public class Pet {
    private Integer id;
    private String name;
    private Integer status; // 0:待领养, 1:已领养
    private LocalDateTime createTime;
    
    // 标准写法:私有属性、无参构造、Getter/Setter、toString
    public Pet() {}
    
    // Getter & Setter ...
}

2. DTO 层 (接收前端申请)

/**
 * 用户提交领养申请时的表单数据
 */
public class AdoptionApplyDTO implements Serializable {
    private Integer userId;
    private Integer petId;
    private String reason; // 领养理由
    
    // 注册或提交时,不需要 id 和 createTime,所以 DTO 极其简洁
}

3. VO 层 (给前端展示)

/**
 * 页面展示宠物详情
 */
public class PetVO {
    private String petName;
    private String statusText; // 将 0/1 转换为 "待领养"/"已领养"
    private String formattedTime; // 将时间格式化为 yyyy-MM-dd
    
    // VO 负责美化数据,让前端直接显示,不处理业务逻辑
}

四、 JavaBean 的编写规范 (Checklist)

无论是哪种 Bean,都应遵循以下 JavaBean 标准规范

  1. 私有属性:所有字段必须使用 private 修饰。
  2. Getter/Setter:提供公共的访问方法(推荐使用 Lombok 注解 @Data 简化)。
  3. 序列化:必须实现 java.io.Serializable 接口(尤其是 DTO,因为可能涉及网络传输)。
  4. 无参构造:必须提供一个默认的空构造函数(反射机制需要)。
  5. 字段封装:禁止使用基本类型,统一使用 包装类型(如用 Integer 代替 int),防止数据库 null 值导致异常。

五、 工具推荐:如何优雅地转换?

在开发中,手动把 Entity 的值赋给 VO(vo.setName(entity.getName()))非常痛苦。推荐使用以下工具:

  • Lombok:使用 @Data 自动生成 Getter/Setter。
  • BeanUtilsBeanUtils.copyProperties(source, target) 快速拷贝。
  • MapStruct:性能最强、最推荐的类型转换框架(编译期生成代码)。

六、 总结

  • Entity 看向数据库。
  • VO 看向用户。
  • DTO 承上启下,负责传输。

分层虽然增加了代码量,但带来了极高的解耦性安全性。在你的《宠物领养系统》中,建议从现在开始将 Pet 类拆分为 PetEntityPetVO,你会发现后续的代码维护变得非常轻松!


作者: [CodeToGym]

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐