1. DTO
數據傳輸對象(DTO, Data Transfer Object)是一種設計模式,用于在不同系統或應用層之間封裝和傳輸數據。它通常用于解耦領域模型(如數據庫實體)和外部接口(如API請求/響應),避免直接暴露內部數據結構,同時優化網絡傳輸效率。
?1. DTO的核心作用
- 數據封裝:將多個數據字段組合成一個對象,減少網絡請求次數。
- 安全性:隱藏領域模型的敏感字段(如數據庫ID、密碼等)。
- 適配接口:為不同場景定制數據結構(如不同的API版本或客戶端需求)。
- 性能優化:減少傳輸數據量,避免傳輸冗余字段。
2. DTO的結構特點
- 簡單無邏輯:僅包含字段、Getter/Setter方法,沒有業務邏輯。
- 序列化支持:通常可序列化為JSON/XML等格式,方便網絡傳輸。
3. DTO vs 實體類(Entity)
特性 | DTO | 實體類 |
---|---|---|
用途 | 數據傳輸 | 映射數據庫表結構 |
生命周期 | 短生命周期(僅用于傳輸) | 長生命周期(與數據庫交互) |
字段暴露 | 僅暴露必要字段 | 包含完整數據庫字段 |
校驗邏輯 | 包含接口層校驗注解(如@Email) | 包含業務邏輯校驗 |
4. DTO的典型使用場景
- API請求參數:接收前端提交的表單或JSON數據。
- API響應結果:返回給前端的結構化數據(排除敏感字段 )。
- 微服務間通道:服務間通過DTO傳遞數據,而非直接暴露領域模型。
- 批量操作:封裝批量處理的數據集合。
5. DTO設計示例
場景:用戶注冊接口
- 請求DTO:接收用戶名、密碼、郵箱
- 響應DTO:返回用戶ID、用戶名、注冊時間(排除密碼字段)
代碼示例:
// 請求DTO:接收用戶注冊數據(包含校驗注解)
public class UserRegisterRequest {@NotBlank(message = "用戶名不能為空")@Size(min = 3, max = 20, message = "用戶名長度需在3-20位")private String username;@NotBlank(message = "密碼不能為空")@Size(min = 6, max = 20, message = "密碼長度需在6-20位")private String password;@Email(message = "郵箱格式不正確")private String email;// Getters and Setters
}// 響應DTO:返回注冊結果
public class UserRegisterResponse {private Long userId;private String username;private LocalDateTime registerTime;// Getters and Setters
}
2. 常見問題
1. DTO與Entity字段不一致怎么辦?
通過轉換工具或手動代碼映射字段,例如:
public class UserMapper {public static UserRegisterResponse toResponse(User user) {UserRegisterResponse response = new UserRegisterResponse();response.setUserId(user.getId());response.setUsername(user.getUsername());return response;}
}
2. DTO需要實現序列化嗎?
如果用于網絡傳輸(如RPC調用),建議實現Serializable接口。
3. 如何復用DTO?
- 通過繼承:定義基礎DTO擴展出具體場景的DTO
- 通過組合:將公共字段封裝為獨立的DTO類,再通過引用組合使用。