java-jpa-criteriaBuilder使用入門

項目中使用jpa ,第一次見查詢起來一臉蒙,這就去查下jpa查詢的方式,和概念。java

 

 

jpa


概念 
建立使用Java Persistence API的存儲庫是一個繁瑣的過程,須要大量時間並須要大量樣板代碼。一種推薦的方式是使用python

元模型

概念 
在JPA中,標準查詢是以元模型的概念爲基礎的,元模型是爲具體持久化單元的受管實體定義的.這些實體能夠是實體類,嵌入類或者映射的父類.提供受管實體元信息的類就是元模型類. 
簡單的說就是元模型是實體類對應的一個「受管實體 
舉個例子: 
實體類 Employee(com.demo.entities包中定義)安全

@Entity @Table public class Employee{ private int id; private String name; private int age; @OneToMany private List<Address> addresses; // Other code… }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Employee類的標準元模型類的名字是 Employee_ui

import javax.annotation.Generated; import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.ListAttribute; import javax.persistence.metamodel.StaticMetamodel; @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Integer> id; public static volatile SingularAttribute<Employee, Integer> age; public static volatile SingularAttribute<Employee, String> name; public static volatile ListAttribute<Employee, Address> addresses; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Employee的每個屬性都會使用在JPA2規範中描述的如下規則在相應的元模型類中映射:this

  • 元模型類的屬性所有是static和public的。
  • 元模型類的屬性所有是static和public的。Employee的每個屬性都會使用在JPA2規範中描述的如下規則在相應的元模型類中映射:spa

  • 對於Addess這樣的集合類型,會定義靜態屬性ListAttribute< A, B> b,這裏List對象b是定義在類A中類型B的對象。其它集合類型能夠是SetAttribute, MapAttribute 或 CollectionAttribute 類型。.net

看到這應該會有個疑問,這麻煩,爲何要使用這個元模型?有啥好處? 
好處確定是有的,畢竟是標準jpa定義的東西。我這網上查了下,好處不少:code

  • 查詢更加類型安全

好吧,我暫時就查到這個。對象

criteria 查詢

爲了更好的理解criteria 查詢,考慮擁有Employee實例集合的Dept實體,Employee和Dept的元模型類的代碼以下:blog

//All Necessary Imports @StaticMetamodel(Dept.class) public class Dept_ { public static volatile SingularAttribute<Dept, Integer> id; public static volatile ListAttribute<Dept, Employee> employeeCollection; public static volatile SingularAttribute<Dept, String> name; } //All Necessary Imports @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Integer> id; public static volatile SingularAttribute<Employee, Integer> age; public static volatile SingularAttribute<Employee, String> name; public static volatile SingularAttribute<Employee, Dept> deptId; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

下面的代碼片斷展現了一個criteria 查詢,它用於獲取全部年齡大於24歲的員工:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class); Root<Employee> employee = criteriaQuery.from(Employee.class); Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24); criteriaQuery.where(condition); TypedQuery<Employee> typedQuery = em.createQuery(criteriaQuery); List<Employee> result = typedQuery.getResultList();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

對應的SQL: SELECT * FROM employee WHERE age > 24

CriteriaBuilder 安全查詢建立工廠

CriteriaBuilder 安全查詢建立工廠,,建立CriteriaQuery,建立查詢具體具體條件Predicate 等。 
CriteriaBuilder是一個工廠對象,安全查詢的開始.用於構建JPA安全查詢.能夠從EntityManager 或 EntityManagerFactory類中得到CriteriaBuilder。 
好比: 
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery 安全查詢主語句

  • 它經過調用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery 得到。
  • CriteriaBuilder就像CriteriaQuery 的工廠同樣。
  • CriteriaQuery對象必須在實體類型或嵌入式類型上的Criteria 查詢上起做用。
  • Employee實體的 CriteriaQuery 對象如下面的方式建立:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
  • 1
  • 2

Root

  • Root 定義查詢的From子句中能出現的類型
  • Criteria查詢的查詢根定義了實體類型,能爲未來導航得到想要的結果,它與SQL查詢中的FROM子句相似。
  • Root實例也是類型化的,且定義了查詢的FROM子句中可以出現的類型。
  • 查詢根實例能經過傳入一個實體類型給 AbstractQuery.from方法得到。
  • Criteria查詢,能夠有多個查詢根。
  • Employee實體的查詢根對象能夠用如下的語法得到 :
Root<Employee> employee = criteriaQuery.from(Employee.class);
  • 1

Predicate 過濾條件

  • 過濾條件應用到SQL語句的FROM子句中。
  • 在criteria 查詢中,查詢條件經過Predicate 或Expression 實例應用到CriteriaQuery 對象上。
  • 這些條件使用 CriteriaQuery .where 方法應用到CriteriaQuery 對象上。
  • Predicate 實例也能夠用Expression 實例的 isNull, isNotNull 和 in方法得到,複合的Predicate 語句能夠使用CriteriaBuilder的and, or andnot 方法構建。
  • CriteriaBuilder 也是做爲Predicate 實例的工廠,Predicate 對象經過調用CriteriaBuilder 的條件方法( equal,notEqual, gt, ge,lt, le,between,like等)建立。
  • 這些條件使用 CriteriaQuery .where 方法應用到CriteriaQuery 對象上。
  • 下面的代碼片斷展現了Predicate 實例檢查年齡大於24歲的員工實例:
Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24); criteriaQuery.where(condition);
  • 1
  • 2

過Employee_元模型類age屬性,稱之爲路徑表達式。若age屬性與String文本比較,編譯器會拋出錯誤,這在JPQL中是不可能的。這就是元模型的做用嗎??

Predicate[] 多個過濾條件




OR語句(可怕)
predicatesList.add(criteriaBuilder.or(criteriaBuilder.equal(root.get(RepairOrder_.localRepairStatus), LocalRepairStatus.repairing),criteriaBuilder.equal(root.get(RepairOrder_.localRepairStatus), LocalRepairStatus.diagnos)));

忽略大小寫(全大寫)
predicatesList.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(RepairShop_.shopName)), StringUtils.upperCase(StringUtils.trim(this.shopName)) + "%"));


List<Predicate> predicatesList = new ArrayList<Predicate>(); predicatesList.add(.....Pridicate....) criteriaQuery.where(predicatesList.toArray(new Predicate[predicatesList.size()]));

引用原文:http://blog.csdn.net/id_kong/article/details/70225032

 

寫博客是爲了記住本身容易忘記的東西,另外也是對本身工做的總結,文章能夠轉載,無需版權。但願盡本身的努力,作到更好,你們一塊兒努力進步!

若是有什麼問題,歡迎你們一塊兒探討,代碼若有問題,歡迎各位大神指正!

相關文章
相關標籤/搜索