我需要做很多條件連接和where子句的條件查詢,在這種情況下,代碼往往變得複雜並且可能會產生重複的連接。JPA標準查詢 - 如何避免重複連接
例如我有表和JPA實體的結構如下:
ACCOUNT
ACCOUNT_ID
ACCOUNT_TYPE
PERSON
NAME
AGE
ACCOUNT_ID (FK TO ACCOUNT)
ADDRESS_ID (FK TO ADDRESS)
ADDRESS
ADDRESS_ID
LOCATION
COUNTRY
所以假設讀音字使用靜態元模型執行用於施加標準的查詢。
這是實施例的錯誤代碼,可以產生重複的聯接:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Account> cq = cb.createQuery(Account.class);
cq.select(accountRoot).where(
cb.and(
cb.equal(accountRoot.join(Account_.person).get(Person_.name),"Roger"),
cb.greaterThan(accountRoot.join(Account_.person).get(Person_.age),18),
cb.equal(accountRoot.join(Account_.person)
.join(Person_.address).get(Address_.country),"United States")
)
)
TypedQuery<Account> query = entityManager.createQuery(cq);
List<Account> result = query.getResultList();
上面的代碼將生成具有mutiples一個SQL連接在同一個表中:
Select
account0_.account_id as account1_2_,
account0_.account_type as account2_2_
from
account account0_
inner join
person person1_
on account0_.account_id=person1_.account_id
inner join
address address2_
on person1_.address_id=address2_.address_id
inner join
person person3_
on account0_.account_id=person3_.account_id
inner join
person person4_
on account0_.account_id=person4_.account_id
inner join
person person5_
on account0_.account_id=person5_.account_id
inner join
address address6_
on person5_.address_id=address6_.address_id
where
person3_.name=?
and person4_.age>18
and address6_.country=?
一個簡單的解決方案是以保持連接的實例在多重謂詞中重複使用:
Root<Account> accountRoot = cq.from(Account.class);
Join<Account,Person> personJoin= accountRoot.join(Account_.person);
Join<Person,Address> personAddressJoin = accountRoot.join(Person_.address);
cq.select(accountRoot).where(
cb.and(
cb.equal(personJoin.get(Person_.name),"Roger"),
cb.greaterThan(personJoin.get(Person_.age),18),
cb.equal(personAddressJoin.get(Address_.country),"United States")
)
)
好吧,它的工作原理,但與一個真正複雜的代碼與幾個表和條件連接的代碼往往會變成一個意大利麪代碼!相信我 !
有什麼更好的方法來避免它?
您有多個連接的SQL,因爲你的代碼必須'join'許多重複的調用。你期望會發生什麼?爲實際需要的每個連接調用一次'join',並重用返回的'Join'實例。您已經創建了您需要的兩個'Join'實例 - 只需使用它們即可! – Rob
@Rob對不起,tx您的評論,我昨天只發布了不完整的問題,我修正了它。我知道這是錯誤的,在我的第一次使用標準查詢和加入的經歷中,我犯了這個錯誤,我應該發佈兩個錯誤的代碼並修復。問題已修復!然而,我不認爲答案是錯的,這只是一個建議,以避免它在一個複雜的標準查詢中,我有一個很好的經驗,在我的工作這個戰略,所以我想分享這個解決方案,但好吧,如果它是你的意見。 –