Spring Boot 教學:Entity、DTO、RequestDTO、ResponseDTO 與資料流
目錄
隨便點選下方其中一個主題便能快速跳到該主題的教學區
前言
本文件整理自一段我和ChatGPT的討論,內容包含:
- Entity 與 DTO 的差異
- DTO 是否會自動連結 Entity?
- 轉換邏輯應該放在哪裡(Controller?Service?)
- RequestDTO / ResponseDTO / DTO 的用途區分
- 整體資料流示意圖
1. Entity 與 DTO 的差別
Entity 是什麼?
Entity 是後端用來對應資料庫的物件(例如 JPA/Hibernate)。其欄位通常與資料表一致,並包含關聯設定。
DTO 是什麼?
DTO(Data Transfer Object)是傳給前端的資料格式。
DTO ≠ Entity,它們是兩個完全獨立的物件。
DTO 會自動連接 Entity 嗎?
不會。Spring Boot / JPA 不會自動將 Entity 與 DTO 做轉換。
2. Entity 與 DTO 如何轉換?
必須透過人工或工具進行轉換:
- 手動 mapping
- 使用 MapStruct(推薦)
- ModelMapper
Mapper 範例(MapStruct):
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDto toDto(User entity);
User toEntity(UserDto dto);
}
3. 轉換邏輯應該放在哪?Controller?Service?
Controller 的職責
- 定義 API
- 接收 RequestDTO
- 回傳 ResponseDTO
- 呼叫 Service
Controller 不應負責 DTO ↔ Entity 的轉換。
Service 的職責
- 處理商業邏輯
- 使用 Repository 存取資料庫
- 負責 DTO ↔ Entity 的轉換
因此,如果你的程式碼是由 Service 負責轉換,那是符合業界最佳實踐的。
有些 AI 或新手教學會把轉換寫在 Controller,但這不是理想做法。
4. RequestDTO、ResponseDTO、DTO:各自用途與區分
RequestDTO(輸入)
- 接收前端傳來的資料
- 用於 @Valid 驗證
- 不應包含 ID、createdTime、passwordHash 等後端欄位
public class CreateUserRequestDTO {
@NotBlank
private String username;
@Email
private String email;
private String password;
}
ResponseDTO(輸出)
- 回傳給前端的資料
- 過濾掉敏感資訊(例如 password)
- 是乾淨、安全的輸出格式
public class UserResponseDTO {
private Long id;
private String username;
private String email;
private LocalDateTime createdAt;
}
EntityNameDTO(一般的 DTO)
這類 DTO 用途較彈性,通常用於 Service 層或內部使用,
或作為多系統間傳遞資料的格式。
5. 完整資料流(最正確版本)
以下是標準 Spring Boot 業界資料流:
[前端 / 後台管理系統]
↓ (送資料)
RequestDTO
↓
Controller
↓
Service
(DTO → Entity)
↓
Repository
↓
Database
↓
Repository
↓
Service
(Entity → ResponseDTO)
↓
Controller
↓
[前端 / 後台管理系統]
總結:
前端送 RequestDTO → 後端處理成 Entity → 後端產生 ResponseDTO → 回送給前端。
6. 最後結語
你的後端程式碼架構(Service 做轉換)是正確的。
而 HTML 教學文件如果寫成 Controller 做轉換,功能上不會錯,但架構上不佳。
本文件已修正為業界最佳實踐,適合放在你的專案教學中。