理清楚 VO、DTO、POJO(实体类)

发布时间 2023-08-31 15:26:17作者: Himmelbleu

POJO(实体类)

操作数据库需要有一个数据模型,去接收数据、传输数据。因此,定义一种 POJO(实体类)与数据库表一一对应,如 users 表,字段有 username、password、age、id。所以,我们定义的 POJO 也要有 username、password、age、id。

POJO 就是 Java 普通类,数据库中的字段类型与实体类的属性类型基本上保持一致,不一样的类型也基本上可以替代,如数据库中字段 varchar 类型,实体类的属性类型就是 String。

DAO 层

我们在使用 mybatis 这类框架操作数据库时,或者其他 Dao 层框架,基本上都要定义实体类,比如,筛选 users 表。

file:[UserMapper.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.buchstadt.mapper.UserMapper">

    <select id="queryAll" resultType="User">
        SELECT *
        FROM users;
    </select>

</mapper>
file:[UserMapper.java]
@Mapper
public interface UserMapper {

    List<User> queryAll();

}

获取到的数据返回给 Service 层,这一层拿到的实体类就可以处理业务了。如果说,这个业务处理完,再次使用了一次数据库查询,得到一个新的 POJO。此时,就有了两个 POJO,假如前端需要者两个 POJO,我们要返回给 Controller 层,该如何封装数据?

DTO

就如上面说到的问题,返回上一层可能还需要进行封装一次,可以创建一个 DTO 类,把这个 DTO 返回给 Controller 层。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {

    private User user;
    private Student student;

}

在 Service 层中,结束返回时通过 UserDTO 封装我们两次获取的 POJO 给 Controller 层,并返回给前端(视图层)。

VO

前端(视图层)传递的数据可能与我们 POJO 不一致,也就是说传递的数据与数据库字段不是一一对应的。这就出现了 VO。

假如,前端传递一个用户数据,其中字段包含,username、password、id,但是没有 age、sex 等其他字段。我们可以额外定义一个 VO 类。

在 Controller 层,Spring Boot 中,@RequestBody 接收的类就是 UserVO。

@GlobalUrl("/user")
public class UserController {

    @Resource
    private UserService service;

    @PostMapping("/delete")
    public Integer delete(@RequestBody UserVO userVo) {
        return service.delete(userVo);
    }

}

总结

VO、DTO、POJO 本质上都是 Java 普通类,从实际开发和业务的角度出发,我们把 POJO 拆分了 VO、DTO。功能上都是一样的,封装数据、传输数据。

根据你的实际业务出发,并不需要每次都定义 VO、DTO,但是 POJO 要有。