项目中有三类模型类:DTO数据传输对象、PO持久化对象,DTO用于接口层向业务层之间传输数据,PO用于业务层与持久层之间传输数据;有些项目还会设置V0对象,V0对象用在前端与接口层之间传输数据,当前端有多个平台且接口存在差异时就需要设置V0对象用于前端和接口层传输数据。
1. 概念详解
在软件开发中,尤其是分层架构中,我们经常使用 DTO
(Data Transfer Object)、PO
(Persistent Object)、VO
(Value Object)来分别处理数据在不同层之间的传递和转换。这些模型类各自有明确的职责和作用。
1.1 DTO(Data Transfer Object)数据传输对象
作用:DTO 是用于在不同层(通常是 Service 层和 Controller 层)之间传递数据的对象。它主要用来简化数据传输,通常只包含与传输相关的字段,而不是数据库的直接映射。
使用场景:
- 将客户端传递的数据封装为 DTO 后传递到服务层。
- 服务层处理完业务逻辑后,将结果封装为 DTO 返回给客户端。
1.1.1 示例:
public class UserDTO {
private String username;
private String email;
private int age;
// getters and setters
}
1.1.2 在 Controller 中使用:
@RestController
@RequestMapping("/users")
public class UserController {
@Resource
private UserService userService;
@PostMapping
public ResponseEntity<String> createUser(@RequestBody UserDTO userDTO) {
userService.createUser(userDTO);
return ResponseEntity.ok("User created successfully");
}
}
1.1.3 在 Service 层使用:
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public void createUser(UserDTO userDTO) {
UserEntity userEntity = new UserEntity();
BeanUtil.copyProperties(userDTO, userEntity);
userMapper.insert(userEntity);
}
}
1.2 PO(Persistent Object)持久化对象
作用:PO 是与数据库表直接映射的对象,用于持久化数据。通常会在数据访问层(Mapper 层)使用,代表数据库中的一条记录。
使用场景:
- 从数据库中查询到的数据会被映射为 PO 对象。
- 需要将数据保存到数据库时,会将 PO 对象传递到数据访问层。
1.2.1 示例:
@TableName("users")
public class UserEntity {
private Long id;
private String username;
private String email;
private int age;
// getters and setters
}
1.2.2 在 Mapper 层使用:
@Mapper
public interface UserMapper extends BaseMapper<UserEntity> {
// 定义数据库操作的方法
}
1.2.3 在 Service 层使用:
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public UserEntity getUserById(Long id) {
return userMapper.selectById(id);
}
}
1.3 VO(Value Object)值对象
作用:VO 是用于展示层的数据对象,通常用于向前端返回数据。它可能包含组合的数据,通常是为了封装复杂的数据结构,使前端更容易消费。
使用场景:
- 将多个数据源的数据组合后封装为 VO 对象返回给前端。
- 用于返回处理后的数据给客户端,通常比 DTO 更加复杂。
1.3.1 示例:
public class UserVO {
private String username;
private String email;
private String profileUrl; // 可能是从其他服务获取的头像URL
// getters and setters
}
1.3.2 在 Service 层使用:
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public UserVO getUserVO(Long id) {
UserEntity userEntity = userMapper.selectById(id);
UserVO userVO = new UserVO();
BeanUtil.copyProperties(userEntity, userVO);
// 假设还有其他服务获取用户的头像URL
userVO.setProfileUrl("http://example.com/profile/" + id);
return userVO;
}
}
1.3.3 在 Controller 中使用:
@RestController
@RequestMapping("/users")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserVO> getUser(@PathVariable Long id) {
UserVO userVO = userService.getUserVO(id);
return ResponseEntity.ok(userVO);
}
}
2. 总结
2.1 总结与层次使用
- DTO(数据传输对象) 用于不同层之间的数据传递,轻量化,字段通常为业务逻辑所需。
- PO(持久化对象) 是直接与数据库表对应的实体类,负责数据库操作。
- VO(值对象) 是用于前端展示的数据封装,通常包含组合或处理后的数据。
2.2 在项目中,通常的流程是:
- Controller 层接收前端传来的 DTO,将其传递给 Service 层。
- Service 层将 DTO 转化为 PO,与数据库交互,并可能会将结果处理后封装为 VO。
- Mapper 层直接操作 PO,执行 CRUD 操作。
- Service 层在处理完业务逻辑后,将结果封装为 VO,由 Controller 层返回给前端。
这种分层架构使得数据传递清晰明确,层与层之间职责分明,便于维护和扩展。