本文為【Spring Boot情境式網站開發指南:使用Spring Data JPA、Spring Security、Spring Web Flow】一書的【 第4章 Criteria API入門】延續,完整範例程式碼可至出版社下載
INNER JOIN FETCH
當JPQL使用以下語句時:SELECT DISTINCT e FROM Employee1 e INNER JOIN FETCH e.tasks t對應的Criteria API用法如下:
@Test public void Criteria_InnerJoinFetch() { EntityManager em = emf.createEntityManager(); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuerysql = cb.createQuery(Employee1.class); Root emp1 = sql.from(Employee1.class); Fetch task = emp1.fetch(Employee1_.tasks, JoinType.INNER); sql.select(emp1) .distinct(true); TypedQuery typedQuery = em.createQuery(sql); List resultList = typedQuery.getResultList(); resultList.forEach(System.out::println); assertThat(resultList, containsInAnyOrder(employee1, employee2, employee3)); assertThat(resultList, hasSize(3)); assertEquals(1, keyWordCount(out.getLog(), "Hibernate:")); }
- 行7-8
使用Root<Employee1> emp1的fetch()方法並指定:
1. 聯結「欄位」,本例為Employee1_.tasks。
2. 聯結「型態」,本例為JoinType.INNER。
可以得到Fetch<Employee1, Task>物件,和先前Join<Employee1, Task>物件參考相似。本例並無使用該物件參考,實際上並不需要特別宣告物件參考指向方法執行後的回傳結果,只是單純讓讀者了解fetch()方法回傳型態為Fetch物件。
- 行9
使用sql.select(emp1)看似只查詢Employee1類別,但使用fetch()方法已經一次取回Employee1類別與其關聯的Task類別的所有欄位資料,因此呼叫emp1.getTasks()將可以直接由本地端JVM取得資料,不需要依賴
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Task> tasks;
的宣告逐筆至遠端資料庫中取回資料。優點是可以減少資料庫的shared lock狀況並提升效能,但必須衡量是否有需要這些資料,以及記憶體使用狀況。
LEFT JOIN FETCH
概念與INNER JOIN FETCH相同,只是改用LEFT JOIN。當JPQL使用以下語句時:SELECT DISTINCT e FROM Employee1 e
LEFT JOIN FETCH e.tasks t
對應的Criteria API用法如下。注意行8使用fetch()方法並指定聯結型態為JoinType.LEFT:@Test
public void Criteria_LeftJoinFetch() {
EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery sql = cb.createQuery(Employee1.class);
Root emp1 = sql.from(Employee1.class);
Fetch task =
emp1.fetch(Employee1_.tasks, JoinType.LEFT);
sql.select(emp1)
.distinct(true);
TypedQuery typedQuery = em.createQuery(sql);
List resultList = typedQuery.getResultList();
resultList.forEach(System.out::println);
assertThat(resultList,
containsInAnyOrder(employee1, employee2, employee3, employee4));
assertThat(resultList, hasSize(4));
assertEquals(1, keyWordCount(out.getLog(), "Hibernate:"));
}
沒有留言:
張貼留言