- Published on
「Spring Boot API 開發:從 0 到 1」Day 21 JPA 自定義查詢方法
Spring Data JPA 的自定義查詢方法是一個強大的功能,它允許開發者透過方法名稱來定義查詢邏輯
無需手動編寫 SQL 或 JPQL 查詢語句
這種方式不僅簡化了開發過程,還提高了代碼的可讀性和維護性
相關規則
- 方法名稱必須以特定的關鍵字開頭,如
findBy
、getBy
、queryBy
、countBy
、deleteBy
等 - 接著是實體屬性名稱,可以使用
And
和Or
連接多個條件 - 可以使用一些關鍵字來指定查詢條件,如
GreaterThan
、LessThan
、Between
、Like
、In
等 - 可以在方法名稱結尾添加
OrderBy
來指定排序
範例
- findByTitle(String title)
- 根據標題查找
- findByCompletedTrue()
- 查找已完成的項目
- findByTitleContainingAndCompletedFalse(String keyword)
- 查找標題包含關鍵字且未完成的項目
- findByCreatedAtBetween(Date start, Date end)
- 查找在指定日期範圍內創建的項目
- findByTitleOrderByCreatedAtDesc(String title)
- 根據標題查找並按創建時間降序排序
修改程式碼
修改 Repository
讓我們修改之前的 TodoRepository
,增加一些自定義查詢方法
public interface TodoRepository extends JpaRepository<Todo, Long> {
// 根據標題查找待辦事項
List<Todo> findByTitle(String title);
// 查找所有已完成的待辦事項
List<Todo> findByCompletedTrue();
// 根據標題模糊查詢,並按 ID 降序排序
List<Todo> findByTitleContainingOrderByIdDesc(String keyword);
// 計算未完成的待辦事項數量
long countByCompletedFalse();
}
修改 Controller
讓我們在 TodoController
中使用這些新方法
@RestController
@RequestMapping("/api/todos")
public class TodoController {
// 為了方便,在這裡只展示了修改後,所增加的 DB 操作相關程式碼
@GetMapping("/search")
public ResponseEntity<MyApiResponse<List<Todo>>> searchTodos(@RequestParam String keyword) {
List<Todo> todos = todoRepository.findByTitleContainingOrderByIdDesc(keyword);
return ResponseEntity.ok(new MyApiResponse<>(true, todos, null));
}
@GetMapping("/completed")
public ResponseEntity<MyApiResponse<List<Todo>>> getCompletedTodos() {
List<Todo> completedTodos = todoRepository.findByCompletedTrue();
return ResponseEntity.ok(new MyApiResponse<>(true, completedTodos, null));
}
@GetMapping("/count-incomplete")
public ResponseEntity<MyApiResponse<Long>> getIncompleteCount() {
long count = todoRepository.countByCompletedFalse();
return ResponseEntity.ok(new MyApiResponse<>(true, count, null));
}
}
測試
可以使用之前的 api-test.http
來測試
可以看到相關的測試結果
自定義查詢方法的優缺點
優點
- 簡化代碼:無需手動編寫複雜的 SQL 或 JPQL 查詢,大大減少了樣板代碼
- 提高可讀性:方法名稱直接反映了查詢邏輯,使程式碼更易於理解
- 類型安全:編譯時檢查可以捕獲大多數錯誤,減少運行時錯誤
- 靈活性:可以輕鬆建立各種複雜的查詢,而無需深入了解底層資料庫
- 自動優化:Spring Data JPA 會自動優化產生的查詢,提高性能
- 可測試性:易於為這些方法編寫單元測試
缺點
- 學習曲線:需要熟悉命名約定和規則
- 方法名稱可能變得冗長:對於非常複雜的查詢,方法名稱可能變得難以閱讀
- 性能考慮:對於非常複雜或高度優化的查詢,手動編寫 SQL 可能更有效
- 可能導致過度使用:可能會導致建立過多的特定查詢方法,而不是使用更通用的解決方案
最佳實務
- 保持方法名稱簡潔:避免過長的方法名稱,複雜查詢考慮使用
@Query
註解 - 善用 Spring Data JPA 的關鍵字:如 And、Or、Between、LessThan 等
- 考慮查詢效能:對於頻繁使用的複雜查詢,可能需要手動優化或使用原生 SQL
- 適當使用投影:只選擇需要的欄位,而不是總是返回整個實體
- 利用測試:編寫單元測試確保查詢方法的正確性
- 文件化:為複雜的查詢方法添加註解,說明其用途和任何特殊邏輯
- 避免過度使用:不要為每個可能的查詢都建立方法,保持 Repository 的簡潔
結論
自定義查詢方法是 Spring Data JPA 的一個強大特性,能夠大大提高開發效率和程式碼品質
然而,開發者應該權衡其利弊,確保在簡便性和效能之間找到適當的平衡
對於簡單到中等複雜度的查詢,自定義查詢方法是一個極好的選擇
而對於更複雜的查詢邏輯,可能需要考慮使用 @Query
註解或甚至是 原生 SQL 查詢
同步刊登於 iTHome 鐵人賽 「Spring Boot API 開發:從 0 到 1」Day 21 JPA 自定義查詢方法
圖片來源:AI 產生