VO、DTO、POJO?
POJO
操作数据库需要数据模型,因此,定义一种实体类,与数据库表字段一一对应。
如 users 表,字段有 username、password、age、id。所以,我们定义的实体类也要有 username、password、age、id。数据库中的数据类型基本上都可以找到代替的 Java 类型。
tip:[start]
实体类有很多叫法,很多项目定义的名字都不一样,我见过的有:domain、pojo、entity。
tip:[end]
DTO
file:[UserDTO.java]
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private List<User> userList;
private List<Article> articleList;
}
file:[UserService.java]
@Service
public class UserService {
@Resource
private UserMapper mapper;
public UserDTO queryAll() {
List<User> userList = mapper.queryAll();
List<Article> articleList = mapper.queryArticles();
add:[return new UserDTO(userList, articleList);]:add
}
}
从数据库中获取了两种列表,需要将其一同返回出去,返回出去的结果不是一个与数据库表对应的实体类,这时可能需要新建一个 DTO 类。
tip:[start]
DTO 与 POJO 不一样,POJO 必须与数据库的表字段保持一致,DTO 不需要与数据库表保持一致,DTO 封装来自 Service 的数据给 Controller 层。
tip:[end]
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);
}
}
tip:[start]
同样的,DTO 和 VO 都和 POJO 不一样,VO 不需要和数据库的表字段保持一致,VO 封装来自 视图层(前端)传递过来的数据给 Controller 层、Service 层、Mapper 层(DAO 层)。
tip:[end]
总结
VO、DTO、POJO 本质上都是 Java 普通类,从实际开发和业务的角度出发,我们把 POJO 拆分了 VO、DTO。功能上都是一样的,封装数据、传输数据。根据你的实际业务出发,并不需要每次都定义 VO、DTO,但是 POJO 要有。
实际上 VO、DTO 可以通过 Map 来代替,Map 非常强大,在 Controller 可以作为 Parameter 的接收者,也可以作为 Body Data 的接收者。唯一不好的地方在于 Map 通过 get 获取,其类型需要强转,不安全,并且也容易写错 Key,不能提前知道获得的内容长什么样子,对于多人开发来说很模糊,容易出错。