831 字
4 分钟
Entity、DTO和VO
2025-05-30
2025-05-31

最近在写一个新的项目,因为打算做的正式点,不能像之前那样只是个自娱自乐的玩具,所以安全性这方面就需要注意一下。

Entity 实体类#

对应数据库表的领域模型,包含完整的业务属性和关系。简单来说,它与数据库表的属性一一对应,包括这些属性的 get 和 set 方法都在其中定义。

综上,它的核心特点就是数据持久化

我之前为了省事,都是直接通过 entity 来操作数据库的,那么这就带来了一个问题,使用 entity 会将数据库中所有的字段一并返回给前端,那如果我要实现修改用户信息,这样在前后端之间进行数据交换的操作时,就会很容易暴露 entity 类,进而导致密码等重要参数的暴露。

为了解决这种安全性问题,那我们就要借助 DTO 和 VO 来对 Entity 进行解耦,只返回所需的字段。

DTO 和 VO 的区别主要是:DTO 用于数据交换,VO 用于展示数据

DTO#

DTO 是一种用于在不同层次(如前端与后端、服务层与数据访问层)之间传输数据的对象,通常包含简单的字段和 getter/setter 方法,不包含业务逻辑。这里的业务逻辑指的是与业务规则、流程直接相关的代码,即数据的校验、处理。

DTO 的核心职责是数据传输。在 DTO 中可以将 Entity 类中的我们想操作的字段单独拿出来,防止其他字段的泄露。比如我想实现一个展示用户信息的接口,那为了避免密码这种重要字段的泄露,我们就可以在 DTO 中单独将用户信息的部分进行定义。

UserDTO
public class UserDTO {
private Long id;
private String username;
private String email;
}

当然,虽然原则上 DTO 只能进行数据传输,但实际上现在还有很多的注解,可以帮助我们进行数据的校验,比如 @NotNull

VO#

VO 是一种专门为前端视图展示设计的数据对象,它将后端的业务数据转换为前端易于处理的格式。VO 通常包含从多个领域模型或 DTO 组合而来的数据,不包含业务逻辑。

VO 的核心特点是视图展示。虽然它不能用于数据传输,但是在展示数据这方面更加友好。

UserVO
public class UserVO {
@Schema(description = "用户ID")
private Long id;
@Schema(description = "用户名")
private String username;
@Schema(description = "昵称")
private String nickname;
@Schema(description = "手机号")
private String phone;
@Schema(description = "邮箱")
private String email;
@Schema(description = "简介")
private String introduction;
@Schema(description = "头像URL")
private String avatarUrl;
@Schema(description = "角色:ADMIN(管理员),USER(普通用户)")
private String role;
@Schema(description = "状态:0-禁用,1-启用")
private Integer status;
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;
@Schema(description = "最后活跃时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastActiveAt;
}

实践#

在实践中,我是将 DTO 和 VO 组合起来使用的,就比如说上面的,我先用 DTO 获取前端的传来的字段,再根据此字段数据进行处理,将结果以定义好的 UserVO 返回。

Entity、DTO和VO
https://www.blueke.top/posts/894321/
作者
蓝珂
发布于
2025-05-30
许可协议
CC BY-NC-SA 4.0
阅读量: --
评论数:--