在服务器开发中,DTO(Data Transfer Object) 是一种设计模式,它的核心目的是在不同的系统或应用层之间高效、安全地传输数据。
你可以把DTO想象成一个专门用于打包和运送数据的“箱子”或“信封”。
数据库里存放着原始、完整的“货物”(数据)。
你不需要把整个仓库(数据库模型)都发给客户,这既不安全,效率也低。
你根据客户(比如前端、手机App)的需要,挑选出合适的“货物”,放进一个专门定制的“箱子”(DTO)里,然后发送出去。
这个“箱子”本身没有复杂的业务逻辑,它的唯一任务就是承载数据。
不使用DTO,开发者常常会直接使用数据库实体模型(Entity / Model)作为接口的返回对象,这会带来一系列问题:
1、过度暴露信息(安全性)
问题你的数据库用户表可能有20个字段(如user_id,username,password,address,create_time,update_time 等),如果直接返回这个实体,前端就会收到包括password 在内的所有信息,这是极大的安全风险。
DTO解决创建一个UserProfileDTO,只包含需要展示的字段,如username 和address,将敏感信息排除在外。
2、客户端需求与服务器模型不匹配(定制化)
问题一个前端页面可能需要同时展示用户基本信息和订单摘要,直接返回User 和Order 两个实体对象,结构可能很混乱。
DTO解决创建一个UserOrderSummaryDTO,它可能扁平化地包含了来自User 表的username 和来自Order 表的order_count、total_amount 等字段,完美契合前端页面的数据结构。
3、减少不必要的网络传输(性能)
问题实体对象可能包含大量前端不需要的字段(如各种时间戳、状态码等),传输这些数据会消耗额外的带宽。
DTO解决DTO只包含必要的字段,减少了数据包的大小,提升了传输效率。
4、解耦内部结构与外部接口(维护性)
问题如果前端直接依赖你的数据库实体模型,那么一旦你修改了数据库表结构(比如给User 表增加一个字段),前端的代码可能就会意外崩溃。
DTO解决DTO作为内部数据库模型和外部API之间的一个缓冲层,你可以修改数据库结构,但只要保持DTO的稳定,就不会影响前端,这实现了后端服务和前端应用的解耦,使系统更易于维护和演进。
假设我们有一个用户注册的API。
1. 数据库实体(Entity / Model)
// 这是一个与数据库表结构直接映射的实体类
public class User {
private Long id;
private String username;
private String password; // 敏感信息!
private String email;
private Date createTime;
private Date updateTime;
// ... getters and setters
}2. 数据传输对象(DTO)
// 这是一个专门用于创建用户的请求DTO
public class UserCreateRequestDTO {
private String username;
private String password; // 注册时密码是必需的,所以可以包含
private String email;
// 注意:没有 id, createTime, updateTime
// ... getters and setters
}
// 这是一个专门用于响应用户信息的DTO
public class UserResponseDTO {
private Long id;
private String username;
private String email;
// 注意:没有 password!
// ... getters and setters
}3. 控制器(Controller)
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public UserResponseDTO createUser(@RequestBody UserCreateRequestDTO userCreateRequestDTO) {
// 将 DTO 转换为 Entity,然后交给Service层处理
User user = convertToEntity(userCreateRequestDTO);
User savedUser = userService.save(user);
// 处理完成后,将保存后的 Entity 转换为 Response DTO 返回给前端
return convertToResponseDTO(savedUser);
}
// 通常我们会使用像 MapStruct 或 ModelMapper 这样的工具来简化转换过程
private User convertToEntity(UserCreateRequestDTO dto) {
User user = new User();
user.setUsername(dto.getUsername());
user.setPassword(dto.getPassword()); // 这里通常会对密码进行加密
user.setEmail(dto.getEmail());
return user;
}
private UserResponseDTO convertToResponseDTO(User user) {
UserResponseDTO dto = new UserResponseDTO();
dto.setId(user.getId());
dto.setUsername(user.getUsername());
dto.setEmail(user.getEmail());
return dto;
}
}DTO vs VO(Value Object)两者非常相似,都用于承载数据,但VO通常更强调其“值”的特性,即不可变性,且两个VO的所有字段值都相同,则视为同一个对象,DTO更强调“传输”这个动作。
DTO vs Entity / ModelEntity是带有业务行为和持久化能力的领域模型,与数据库紧密绑定,DTO是贫血模型,只有数据,没有行为,用于网络传输。
DTO vs POJO(Plain Old Java Object)POJO是一个更宽泛的概念,指普通的Java对象,DTO是一种特定用途的POJO。
在服务器开发中,DTO是一种专门为网络传输而设计的、只包含数据和getter/setter的简单对象,它的主要作用是:
提高安全性隐藏不必要的敏感字段。
定制数据为不同的客户端或场景提供最合适的数据结构。
提升性能减少不必要的数据传输。
降低耦合隔离内部数据模型和外部API接口,使系统更健壮、更易维护。
在现代后端架构(如MVC、分层架构、微服务)中,DTO是必不可少的一环。
文章摘自:https://idc.huochengrm.cn/js/20489.html
评论
暴惠美
回复DTO是Data Transfer Object的缩写,指用于在服务器与客户端之间传输数据的对象。
藏如曼
回复DTO(Data Transfer Object)指的是在服务器上用于封装数据传输的对象,主要用于简化数据传递和业务逻辑处理。
愚寒梅
回复DTO即数据传输对象,用于服务器和客户端之间传输数据,它将数据封装成对象,方便进行数据处理和传递。
江玲玲
回复DTO(Data Transfer Object)在服务器上是指用于数据传输的对象,用于封装数据并简化数据交互。