Spring MVC 標準三層架構:**Controller (控制層) → Service (業務層) → DAO/Mapper (持久層) → Database**。各層職責單一、依賴倒置、便於測試與維護。
| 層級 | 典型類別/註解 | 核心職責 | 不應包含 |
|---|---|---|---|
| 持久層 (DAO/Mapper) | `@Repository`, `Mapper` 接口, `JdbcTemplate`, `MyBatis` XML | **只做 CRUD**:SQL 執行、結果映射、事務邊界 (可選) | 業務邏輯、參數校驗 (除主鍵)、HTTP 概念 |
| 業務層 (Service) | `@Service`, `@Transactional` | **核心業務邏輯**:流程編排、規則驗證、跨表操作、事務管理、異常轉換 | SQL 細節、HTTP 請求/回應、視圖邏輯 |
| 控制層 (Controller) | `@Controller`/`@RestController`, `@RequestMapping` | **HTTP 介面**:參數接收/校驗 (JSR-303)、呼叫 Service、組裝回應 (JSON/View)、異常處理 | 業務邏輯、SQL、資料庫連線 |
// 1. Controller 接收請求
@PostMapping("/orders")
public Result createOrder(@Valid @RequestBody OrderDTO dto) {
Long orderId = orderService.createOrder(dto); // 2. 呼叫 Service
return Result.success(orderId);
}
// 2. Service 業務流程
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderMapper orderMapper;
private final ProductMapper productMapper;
private final InventoryService inventoryService;
@Transactional(rollbackFor = Exception.class)
public Long createOrder(OrderDTO dto) {
// 2.1 參數深度校驗 (庫存、價格、優惠)
// 2.2 鎖定庫存 (調用 InventoryService)
inventoryService.lockStock(dto.getItems());
// 2.3 落單 (調用 DAO)
Order order = dto.toEntity();
orderMapper.insert(order);
// 2.4 發送事件 (MQ) - 可選
return order.getId();
}
}
// 3. Mapper 只做 SQL
@Mapper
public interface OrderMapper {
@Insert("INSERT INTO orders(...) VALUES(#{...})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Order order);
}
大型專案常在 Service 下再分 **Domain Service** (核心領域邏輯)、**Application Service** (用例編排);Controller 上加 **Facade/Assembler** (DTO 轉換);DAO 下加 **Repository** (聚合根存取)。但核心原則不變:**依賴方向向內,業務邏輯不外洩**。
理解三層邊界,是寫出可維護 Spring 應用的基石。