QQA: Spring Data 如何查詢屬性是否在列表中
阿新 • • 發佈:2018-12-31
每篇文章有多個標籤,選中多個標籤,要求找出含有該標籤的文章。同時如果選中標籤為空,則返回所有文章。Spring Data/JPA 如何實現?
可以使用 Spring Data Specification 動態建立查詢語句,最終結果如下:
public interface PostRepository extends JpaRepository<Post, Long>, |
上面程式碼的注意點:
- 實現
JpaSpecificationExecutor
findAll(Specification<T> spec)
等使用 Specification 的查詢方法。 - 這裡使用 Java 8 的 Lambda 表示式。等價於實現一個
Specification
例項。 - 返回結果為
List
,可能會出現重複的結果,加上distinct
來去重。 cb.conjunction()
等價於where 1=1
。- 重要:呼叫
join
來定位多對多的(或其它的關聯)屬性。
實體類定義
文章類,其中一篇文章可以有多個標籤 Tag
:
|
標籤類,一個標籤可以被賦給多篇文章:
|
生成的 SQL
實際查詢時生成的 SQL 如下:
select |
為什麼用 Specification
上面介紹的 Spring Specification 看起來比較複雜,其實如果只需要查詢一個屬性,可以直接定義 Spring Data 的 Query Method:
public interface PostRepository extends JpaRepository<Post, Long> { |
當然,① 處的方法不能處理 tags
為空時返回所有文章的需求,所以需要 ② 處的方法進行包裝。
那麼 Specification 還有什麼用呢?考慮多個查詢條件的組合,例如文章有多名作者,要根據作者和標籤共同查詢,則需要像這樣實現:
public interface PostRepository extends JpaRepository<Post, Long> { |
這種實現方式需要增加指數級的方法數量,因此更合適用 Specification 動態生成 Query。