項目中使用jpa ,第一次見查詢起來一臉蒙,這就去查下jpa查詢的方式,和概念。java
概念
建立使用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… }
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; }
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 查詢,考慮擁有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; }
下面的代碼片斷展現了一個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();
對應的SQL: SELECT * FROM employee WHERE age > 24
CriteriaBuilder 安全查詢建立工廠,,建立CriteriaQuery,建立查詢具體具體條件Predicate 等。
CriteriaBuilder是一個工廠對象,安全查詢的開始.用於構建JPA安全查詢.能夠從EntityManager 或 EntityManagerFactory類中得到CriteriaBuilder。
好比: CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
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);
過Employee_元模型類age屬性,稱之爲路徑表達式。若age屬性與String文本比較,編譯器會拋出錯誤,這在JPQL中是不可能的。這就是元模型的做用嗎??
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
寫博客是爲了記住本身容易忘記的東西,另外也是對本身工做的總結,文章能夠轉載,無需版權。但願盡本身的努力,作到更好,你們一塊兒努力進步!
若是有什麼問題,歡迎你們一塊兒探討,代碼若有問題,歡迎各位大神指正!