2020年7月19日 星期日

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

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

BETWEEN數字區間

當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e WHERE e.salary BETWEEN 2000 AND 4000
對應的Criteria API用法如下:
  1. @Test
  2. public void Criteria_BetweenLiteralNumbers() {
  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.between(emp.get(Employee_.salary), 2000.0, 4000.0));
  9. List resultList = em.createQuery(sql).getResultList();
  10. resultList.forEach(System.out::println);
  11. em.close();
  12. assertThat(resultList, containsInAnyOrder(employee1, employee2, employee4));
  13. assertThat(resultList, hasSize(3));
  14. }

BETWEEN數字欄位與數字

當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e
  2. INNER JOIN e.supervisor s
  3. WHERE e.salary BETWEEN s.salary AND 4000
  4. ORDER BY e.salary
對應的Criteria API用法如下:
  1. @Test
  2. public void Criteria_BetweenLiteralNumberAndJoinedColumn() {
  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. Join empSupervisor= emp.join(Employee_.supervisor);
  8. sql.select(emp)
  9. .where( cb.between(emp.get(Employee_.salary),
  10. empSupervisor.get(Employee_.salary), // start
  11. cb.literal(4000.0)) ); // end
  12. List resultList = em.createQuery(sql).getResultList();
  13. resultList.forEach(System.out::println);
  14. em.close();
  15. assertThat(resultList, contains(employee1, employee2));
  16. assertThat(resultList, hasSize(2));
  17. }
【說明】
行7:
因為要between()起始邊界為self Join 類別Employee,因此必須宣告Join<Employee, Employee> empSupervisor指向join()方法呼叫後的回傳物件。 
行9-11:
使用CriteriaBuilder的between()方法時,第1個參數指定要查詢的欄位,第2個參數為區間起始邊界,第3個參數為區間結束邊界。

BETWEEN日期區間命名變數 

當JPQL使用以下查詢時:
  1. SELECT e FROM Employee e
  2. WHERE e.joinDate BETWEEN :startDate AND :endDate
  3. ORDER BY e.joinDate
對應的Criteria API用法如下:
  1. @Test
  2. public void Criteria_BetweenNamedParams() {
  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. // prepare parameters
  8. ParameterExpression startDate =
  9. cb.parameter(Timestamp.class, "myStart");
  10. ParameterExpression endDate =
  11. cb.parameter(Timestamp.class, "myEnd");
  12. // create query
  13. sql.select(emp)
  14. .where(cb.between(emp.get(Employee_.joinDate), startDate, endDate))
  15. .orderBy(cb.desc(emp.get(Employee_.joinDate)));
  16. // run query and set parameter values
  17. TypedQuery typedQuery = em.createQuery(sql);
  18. typedQuery.setParameter("myStart",
  19. localToTimeStamp(LocalDate.of(1990, 1, 1)));
  20. typedQuery.setParameter("myEnd",
  21. localToTimeStamp(LocalDate.of(2011, 1, 1)));
  22. List resultList = typedQuery.getResultList();
  23. resultList.forEach(System.out::println);
  24. em.close();
  25. assertThat(resultList, contains(employee3, employee1));
  26. assertThat(resultList, hasSize(2));
  27. }
【說明】
行8-10:
以ParameterExpression<Timestamp>建立欄位joinDate的命名變數:myStart。
行10-11:
以ParameterExpression<Timestamp>建立欄位joinDate的命名變數:myEnd。
行18-19:
以TypedQuery的setParameter()方法指定命名變數myStart並傳入參數值。

行20-21:
以TypedQuery的setParameter()方法指定命名變數myEnd並傳入參數值。

沒有留言:

張貼留言