Spring data jpa 多表查詢(三:多對多關係動態條件查詢)
上一章說了,一對多關係,動態條件查詢,這章開始說多對多關係模型
1.A 和 B (n : n)意思就是多對多,下面開始在模型中,建立關係
@Entity
class A
{
@Column("唯一性標識,主鍵等等")
String id;
@Column("name = name")
String name;
@ManyToMany(mappedBy="aList")
List<B> bList;
}
@Entity
class B
{
@Column("唯一性標識,主鍵等等")
String id;
@Column("name = name")
String name;
@ManyToMany()
@JoinTable(name="a2b" ,joinColumns=@JoinColumn(name="b_id"),inverseJoinColumns=@JoinColumn(name="a_id"))
List<A> aList;
}
建好之後,解釋下,:A 模型中定義了mappedBy,意思是,A 是 A和B多對多的維護段,新增,刪除,修改,一般針對A 模型操作即可,當然也可以從B,只不過,稍微複雜些,此處不再多說。
B 模型中,定義了 中間維護表,指定了表名叫 a2b,並且在 表中,定義了a_id ,b_id, 來標識 A和B多對多關係維護表。
前兩張動態條件查詢,也適用於現在,因此不再多謝,
只需要一條語句來表名他們之間的關係:
Join<A,B> BJoin = root.join(root.get("bList",JoinType.Left);
這條關係,就已經包含了,把a2b 中間表的查詢,包含在裡面,大家可以,junit時候,斷點檢視列印的sql語句
當然,我當時遇到的,是在這基礎上,還得加上一層關係,即,C -> A ->B 即:C 和 A 是一對多。A 和B 多對多、
建立的關係如下:
主體是C
因此root 代表的就是C
Join<C,A> aJoin = root.join(root.get("aList"),JoinType.Left);
Join<A,B> bJoin = aJoin.join("bList",JoinType.Left);
此時,關係就建立好,想帶C 。A。B的引數都可以帶進來
root 接 C 的引數
aJoin 接 A 的引數
bJoin 接 B 的引數
再次宣告一點,JPA ,不支援右連線查詢,當然這只是我調研的結果,因為JPA 認為沒有父哪來的子,必須從左開始,當然除了內連線。
因此,如果某些業務 需要查詢從子開始,JPA 直接查詢不到,但是可以換個思路去解決。例如以下需求
更換下上面的模型關係
A ->B -> C
1->n ->n
針對A 傳入一個id,查出B 和 C,並且是分頁查詢,加 動態條件
對於我們來說,只要關係建立好了,動態條件也就好寫了。
一般分頁,針對 最小單元進行分頁,也就是我們的C 做分頁
條件如下:a_id 是固定的引數,其次B中的name,c中的name 都是 動態的
因此我的思路是這樣的:
1.根據a_id ,查出多個 B
2.根據多個B 查出 B和C 關聯表中的C中的id,
3.最後 把C 中的id 查出來作為條件帶入C中,即可查出 關聯的C
實現的虛擬碼如下:
Page<C> findC(Pageable pageable,ParamDTO dto ,String a_id)
{
此時主體是C,因此root代表的是C
//Specification ,此處省略,可以參考前兩章內容
//1.根據a_id 查出多個B
CriterQuery<B> bQuery = criteraBuilder.createQuery(B.class);
Root<B> root1 = bQuery.from(B.class);
predicateList.add(criteriaBuilder.equal(root1.get("a"),a_id));
//如果有B中的動態引數,即在這裡寫
if(null != bName)
{
predicateList.add(criteriaBuilder.equal(root1.get("name"),bName));
}
bQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicate.size()])));
//查出了B 的集合
List<B> bList = em.createQuery(bQuery).getResultList();
//上面的criteraBuilder,criteriaQuery,em, root,都已經省略,在上一章可以找到。
下面將List<B> 轉換下 B 的id
List<String> ids = new ArrayList<String>();
for(B b:bList)
{
ids.add(b.get(id))
}
這時候,再建立 B 和C 的關係
Join<C,B> bJoin = root.join("bList");
predicateList.add(bJoin.get("id").in(ids));
意思就是 B 和C 建立了 內連線,然後,B 的id 帶入,就查出了 C
這裡用到了 in 方法,不需要用到criterialBuilder, 到此,jpa的查詢,基本上結束,有問題可以留言
}
總結:JPA如果把模型關係理清,sql 的確不怎麼需要我們去維護,還是很方便的。還有JPA中的模型之間的懶載入,我還沒說,
下一章,開始 說說懶載入
相關文章
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- spring data jpa 多對一聯表查詢Spring
- Spring Data JPA 實現多表關聯查詢Spring
- SpringBoot Jpa多條件查詢Spring Boot
- Spring Data Jpa 的簡單查詢多表查詢HQL,SQL ,動態查詢, QueryDsl ,自定義查詢筆記SpringSQL筆記
- jpa動態查詢與多表聯合查詢
- jpa一對多查詢
- JPA多表關聯查詢
- linq to sql的多條件動態查詢SQL
- Laravel 多條件查詢Laravel
- SQL多條件查詢SQL
- spring data jpa查詢Spring
- gorm 關係一對一,一對多,多對多查詢GoORM
- 多條件查詢---ssh版本
- 34. 過濾條件、多表查詢、子查詢
- EntityFramework動態多條件查詢與Lambda表示式樹Framework
- 關於Hibernate多層1對多關係查詢
- mysql帶AND關鍵字的多條件查詢MySql
- Spring-Data-JPA criteria 查詢Spring
- .NET 通用多條件動態引數查詢方法 - SqlSugar ORMSqlSugarORM
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- mysql多條件過濾查詢之mysq高階查詢MySql
- spring-data-jpa一對多、多對多雙向關聯,查詢操作的時候進入死迴圈問題Spring
- Spring Data Jpa 複雜查詢總結 (多表關聯 以及 自定義分頁 )Spring
- C#動態查詢:巧用Expression組合多條件表示式C#Express
- JPA 之 多表聯合查詢
- JPA的多表複雜查詢
- mysql like查詢 - 根據多個條件的模糊匹配查詢MySql
- Spring Data JPA 實現聯表查詢Spring
- jsp+servlet+mysql多條件模糊查詢JSServletMySql
- mybatis多條件的模糊查詢解決方案MyBatis
- SQL中多條件查詢括號的用途SQL
- Spring Boot中使用JPA構建動態查詢Spring Boot
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- 03 註解:多對多查詢
- where語句中多條件查詢欄位NULL與NOT NULL不確定性查詢Null
- 由一個博問學到的SQL查詢方法 (一道多對多關係查詢的面試題)SQL面試題
- 在EFCore中多對多關係的設計資料插入與查詢