2020年7月19日 星期日

在WHERE敘述使用比較(Comparision)關鍵字:MEMBER OF

本文為【Spring Boot情境式網站開發指南:使用Spring Data JPA、Spring Security、Spring Web Flow】一書的【 第4章 Criteria API入門】延續,完整範例程式碼可至出版社下載

使用CriteriaBuilder的isMember()方法和isNotMember()方法決定關聯的「集合物件」內是否有特定成員。以isMember()為例:
【語法】
<E, C extends Collection<E>>
 Predicate isMember(Expression<E> elem, Expression<C> collection);
泛型E:代表集合物件成員型態。
泛型C:代表集合物件型態。
回傳型態Predicate。
方法參數:
1. Expression<E> elem:型態為E的Expression物件參考,輸入成員物件。
2. Expression<C> collection:型態為C的Expression物件參考,輸入集合物件欄位物件。

使用 MEMBER OF 

當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e WHERE '777' MEMBER OF e.phoneNumbers
對應的Criteria API用法如下:
  1. @Test
  2. public void Criteria_MemberOf() {
  3. EntityManager em = emf.createEntityManager();
  4. CriteriaBuilder cb = em.getCriteriaBuilder();
  5. CriteriaQuery sql = cb.createQuery(Employee.class);
  6. Root emp = sql.from(Employee.class);
  7. sql.select(emp)
  8. .where(cb.isMember(cb.literal("777"), emp.get(Employee_.phoneNumbers)));
  9. TypedQuery typedQuery = em.createQuery(sql);
  10. List resultList = typedQuery.getResultList();
  11. resultList.forEach(System.out::println);
  12. em.close();
  13. //assertThat(resultList, IsEmptyCollection.empty());
  14. assertThat(resultList, containsInAnyOrder(employee1, employee3));
  15. assertThat(resultList, hasSize(2));
  16. }
行8:
查詢欄位Employee_.phoneNumbers內含字串777者。藉由CriteriaBuilder 的literal()方法將String轉換為Expression<String>。

使用 NOT MEMBER OF 

當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e WHERE '777' NOT MEMBER OF e.phoneNumbers
對應的Criteria API用法如下:
  1. @Test
  2. public void Criteria_NotMemberOf() {
  3. EntityManager em = emf.createEntityManager();
  4. CriteriaBuilder cb = em.getCriteriaBuilder();
  5. CriteriaQuery sql = cb.createQuery(Employee.class);
  6. Root emp = sql.from(Employee.class);
  7. sql.select(emp)
  8. .where(cb.isNotMember("777", emp.get(Employee_.phoneNumbers)));
  9. TypedQuery typedQuery = em.createQuery(sql);
  10. List resultList = typedQuery.getResultList();
  11. resultList.forEach(System.out::println);
  12. em.close();
  13. assertThat(resultList, containsInAnyOrder(employee2, employee4));
  14. assertThat(resultList, hasSize(2));
  15. }
行8:
使用CriteriaBuilder的isNotMember()方法。第1個參數直接使用String型態,此為Expression<String>的overloading版本。
方法isMember()或isNotMember()的第1個參數也可以是另一個「一般型態」的欄位。當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e
  2. WHERE e.primaryPhoneNumber
  3. NOT MEMBER OF e.phoneNumbers
對應的Criteria API用法如下,注意行8程式碼:
  1. @Test
  2. public void Criteria_NotMemberOf2() {
  3. EntityManager em = emf.createEntityManager();
  4. CriteriaBuilder cb = em.getCriteriaBuilder();
  5. CriteriaQuery sql = cb.createQuery(Employee.class);
  6. Root emp = sql.from(Employee.class);
  7. sql.select(emp)
  8. .where(cb.isNotMember(emp.get(Employee_.primaryPhoneNumber),
  9. emp.get(Employee_.phoneNumbers)));
  10. TypedQuery typedQuery = em.createQuery(sql);
  11. List resultList = typedQuery.getResultList();
  12. resultList.forEach(System.out::println);
  13. em.close();
  14. assertThat(resultList, containsInAnyOrder(employee4, employee2));
  15. assertThat(resultList, hasSize(2));
  16. }

沒有留言:

張貼留言