2020年5月2日 星期六

WHERE條件值使用字面常量(Literal)

字面常量使用字串

使用以下JPQL查詢時:
  1. SELECT e FROM Employee e WHERE e.name = 'Rose'
等價於使用以下Criteria API查詢,且行8顯示否定用法:
  1. @Test
  2. public void Criteria_EqualString() {
  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. Expression expr = cb.equal(emp.get(Employee_.name), "Rose");
  8. // Expression expr = cb.equal(emp.get(Employee_.name), "Rose").not();
  9. sql.select(emp).where(expr);
  10. TypedQuery tq = em.createQuery(sql);
  11. List resultList = tq.getResultList();
  12. resultList.forEach(System.out::println);
  13. assertThat(resultList, containsInAnyOrder(employee2));
  14. }

字面常量使用數字

使用以下JPQL查詢時:
  1. SELECT e FROM Employee e WHERE e.salary > 2000.0
等價於使用以下Criteria API查詢。比較數字使用方法gt()表示greater-than:
  1. @Test
  2. public void Criteria_GreaterNumber() {
  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. Expression expr = cb.gt(emp.get(Employee_.salary), 2000.0);
  8. sql.select(emp).where(expr);
  9. TypedQuery typedQuery = em.createQuery(sql);
  10. List resultList = typedQuery.getResultList();
  11. resultList.forEach(System.out::println);
  12. assertThat(resultList, containsInAnyOrder(employee1, employee2));
  13. }

字面常量使用enum

使用以下JPQL查詢時:
  1. SELECT e FROM Employee e WHERE e.role = entity.Role.IT
等價於使用以下Criteria API查詢。Entity欄位型態為enum可以直接使用equal()方法:
  1. @Test
  2. public void Criteria_EqualEnum() {
  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. Expression expr = cb.equal(emp.get(Employee_.role), Role.IT);
  8. sql.select(emp).where(expr);
  9. TypedQuery tq = em.createQuery(sql);
  10. List resultList = tq.getResultList();
  11. resultList.forEach(System.out::println);
  12. assertThat(resultList, containsInAnyOrder(employee1, employee3));
  13. }

字面常量使用日期

使用以下JPQL查詢時:
  1. SELECT e FROM Employee e WHERE e.joinDate > '2017-05-01'
等價於使用以下Criteria API查詢。比較日期時,無法直接比較日期格式如Timestamp,必須借助CriteriaBuilder的literal()方法轉換為Expression<Timestamp>後再套用到greaterThanOrEqualTo(),如範例程式碼行7~10:
  1. @Test
  2. public void Criteria_GreaterDate() {
  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. Expression timestampExpr =
  8. cb.literal( localToTimeStamp(LocalDate.of(2017, 05, 01)) );
  9. Expression expr =
  10. cb.greaterThanOrEqualTo(emp.get(Employee_.joinDate), timestampExpr);
  11. sql.select(emp).where(expr);
  12. TypedQuery typedQuery = em.createQuery(sql);
  13. List resultList = typedQuery.getResultList();
  14. resultList.forEach(System.out::println);
  15. assertThat(resultList, containsInAnyOrder(employee4, employee2));
  16. }

字面常量使用boolean

使用以下JPQL查詢時:
  1. SELECT e FROM Employee e WHERE e.fullTime = true
等價於使用以下Criteria API查詢。若Entity的Boolean欄位為true,可以使用範例程式碼行9的方法isTrue()或行10直接省略,兩者效果相同;若欄位值要求為false則使用行11的方法isFalse():
  1. @Test
  2. public void Criteria_BooleanField() {
  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. Expression adultExpression = emp.get(Employee_.fullTime);
  8. sql.select(emp)
  9. .where(cb.isTrue(adultExpression));
  10. // .where(adultExpression);
  11. // .where(cb.isFalse(adultExpression));
  12. TypedQuery typedQuery = em.createQuery(sql);
  13. List resultList = typedQuery.getResultList();
  14. resultList.forEach(System.out::println);
  15. assertThat(resultList, hasItems(employee1));
  16. assertThat(resultList, hasItems(employee3));
  17. }

沒有留言:

張貼留言