该文翻译自网络,原文地址:
http://www.developer.com/java/ent/article.php/3902911/Querying-in-JPA-2-Typesafe-and-Object-Oriented.htm
使用criteria 查询
为了更好的理解criteria 查询,考虑拥有Employee实例集合的Dept实体,Employee和Dept的元模型类的代码如下:
//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
构建CriteriaQuery 实例
CriteriaQuery 对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。它通过调用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery 获得。CriteriaBuilder就像CriteriaQuery 的工厂一样。CriteriaBuilder工厂类是调用EntityManager.getCriteriaBuilder 或 EntityManagerFactory.getCriteriaBuilder而得。 Employee实体的 CriteriaQuery 对象以下面的方式创建:
CriteriaBuilder criteriaBuilder = emf.getCriteriaBuilder();
CriteriaQuery<Employee> criteriaQuery = cb.createQuery(Employee.class);
QueryRoot
AbstractQuery是CriteriaQuery 接口的父类。它提供得到查询根的方法。Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似。
Root实例也是类型化的,且定义了查询的FROM子句中能够出现的类型。查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。Criteria查询,可以有多个查询根。Employee实体的查询根对象可以用以下的语法获得:
Root<Employee> employee = criteriaQuery.from(Employee.class);
过滤Queries
过滤条件应用到SQL语句的FROM子句中。在criteria 查询中,查询条件通过Predicate 或Expression 实例应用到CriteriaQuery 对象上。这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。CriteriaBuilder 也是作为Predicate 实例的工厂,Predicate 对象通过调用CriteriaBuilder 的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建。Predicate 实例也可以用Expression 实例的 isNull, isNotNull 和 in方法获得,复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
下面的代码片段展示了Predicate 实例检查年龄大于24岁的员工实例
Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24);
criteriaQuery.where(condition);
通过Employee_元模型类age属性,称之为路径表达式。若age属性与String文本比较,编译器会抛出错误,这在JPQL中是不可能的。
执行查询与获取元模型实例
当EntityManager.createQuery(CriteriaQuery)方法调用时,一个可执行的查询实例会创建,该方法返回指定从 criteria
查询返回的实际类型的TypedQuery 对象。TypedQuery 接口是javax.persistence.Queryinterface.的子类型。在该片段中, TypedQuery 中指定的类型信息是Employee,调用getResultList时,查询就会得到执行
TypedQuery<Employee> typedQuery =
em.createQuery(criteriaQuery);
List<Employee> result =
typedQuery.getResultList();
元模型实例通过调用 EntityManager.getMetamodel 方法获得,EntityType<Employee>的元模型实例通过调用Metamodel.entity(Employee.class)而获得,其被传入 CriteriaQuery.from 获得查询根。
Metamodel metamodel = em.getMetamodel();EntityType<Employee>
Employee_ = metamodel.entity(Employee.class);
Root<Employee> empRoot = criteriaQuery.from(Employee_);
也有可能调用Root.getModel方法获得元模型信息。类型 EntityType<Dept>的实例Dept_和name属性可以调用getSingularAttribute 方法获得,它与String文本进行比较:
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root<Dept> dept = criteriaQuery.from(Dept.class);
EntityType<Dept> Dept_ = dept.getModel();
Predicate testCondition = criteriaBuilder.equal(dept.get(Dept_.getSingularAttribute("name", String.class)), "Ecomm");
对应的 SQL:
SELECT * FROM dept WHERE name = 'Ecomm'
Expression
Expression对象用在查询语句的select,where和having子句中,该接口有 isNull, isNotNull 和 in方法,下面的代码片段展示了Expression.in的用法,employye的年龄检查在20或24的。
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder .createQuery(Employee.class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.where(employee.get(Employee_.age).in(20, 24));
em.createQuery(criteriaQuery).getResultList();
对应的SQL: SELECT
* FROM employee WHERE age in (20, 24)
复合谓词
Criteria Query也允许开发者编写复合谓词,通过该查询可以为多条件测试下面的查询检查两个条件。首先,name属性是否以M开头,其次,employee的age属性是否是25。逻辑操作符and执行获得结果记录。
criteriaQuery.where(criteriaBuilder.and(criteriaBuilder.like(employee.get(Employee_.name), "M%"), criteriaBuilder.equal(employee.get(Employee_.age), 25)));
em.createQuery(criteriaQuery).getResultList();
对应 SQL: SELECT
* FROM employee WHERE name LIKE 'M%' AND
age = 25
连接查询
在SQL中,连接跨多张表以获取查询结果,类似的实体连接通过调用 From.join 执行,连接帮助从一个实体导航到另一个实体以获得查询结果。
Root的join方法返回一个 Join<Dept, Employee>类型(也可以是SetJoin,,ListJoin,MapJoin 或者 CollectionJoin类型)。默认情况下,连接操作使用内连接,而外连接可以通过在join方法中指定JoinType参数为LEFT或RIGHT来实现。
CriteriaQuery<Dept> cqDept = criteriaBuilder.createQuery(Dept.class);
Root<Dept> deptRoot = cqDept.from(Dept.class);
Join<Dept, Employee> employeeJoin = deptRoot.join(Dept_.employeeCollection);
cqDept.where(criteriaBuilder.equal(employeeJoin.get(Employee_.deptId).get(Dept_.id), 1));
TypedQuery<Dept> resultDept = em.createQuery(cqDept);
对应的SQL: SELECT
* FROM employee e, dept d WHERE e.deptId
= d.id and d.id = 1
分享到:
相关推荐
JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询JPA分页查询与条件分页查询...
Pro JPA2中文版:精通Java持久化API 优秀博文读书笔记: http://www.cnblogs.com/sunshine-as-before/tag/java jpa/ 随书pdf文档和源码下载地址: http://download.csdn.net/download/vcfriend/10251462 相关学习博文...
jpa入门案例:单表查询,包括分页查询 使用springboot来整合实现
相关文章: JPA标注 EJB的资料辅导(7) EJB的资料辅导(6) 推荐圈子: Database圈子 更多相关推荐 1.@Entity
JPA2教程,JPA标准参与者编写,全面接受JPA的方方面面。
如果编译器能够对查询执行语法正确性检查,那么对于Java 对象而言该查询就是类型安全的。 Java™Persistence API (JPA) 的2.0 版本引入了Criteria API,这个API 首次将类型安全查询引入到Java 应用程序 中,并为在...
第三章:JpaRepository的查询 包括:解析方法名称以自动生成查询、 NamedQueries、 @Query指定查询、本地查询、命名化参数、更新查询、创建查询的顺序等内容 第四章:客户化扩展JpaRepository 包括:讲述如何在Jpa...
JPA包括以下3方面的技术: RM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元...查询语言,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
JDK1.6的新特性: 注解 其中介绍了JPA框架中的常用注解
jpa查询 jpql 本地查询 命名查询
Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍.doc
可媲美JDBC的查询能力: JPA的查询语言是面向对象的,JPA定义了独特的JPQL,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。 支持面向对象...
Spring Data JPA系列2:SpringBoot集成JPA详细教程,快速在项目中熟练使用JPA.doc
Java:trade_mark:PersistenceAPI(JPA)的2.0版本引入了CriteriaAPI,这个API首次将类型安全查询引入到Java应用程序中,并为在运行时动态地构造查询提供一种机制。本文介绍如何使用CriteriaAPI和与之密切相关的...
Jpa详细查询实例介绍,教你如何使用JPA,简单,分类实例。
赠送jar包:spring-data-jpa-2.0.9.RELEASE.jar; 赠送原API文档:spring-data-jpa-2.0.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-jpa-2.0.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-data-jpa...
学习hibernate必读,包括JPA2新特征和JPA2映射的神秘之旅两个pdf。
赠送jar包:hibernate-jpa-2.1-api-1.0.2.Final.jar; 赠送原API文档:hibernate-jpa-2.1-api-1.0.2.Final-javadoc.jar; 赠送源代码:hibernate-jpa-2.1-api-1.0.2.Final-sources.jar; 赠送Maven依赖信息文件:...
介绍JPA2的一本很不错的英文书籍,可以作为一本权威参考。