该文翻译自网络,原文地址:
http://www.developer.com/java/ent/article.php/3902911/Querying-in-JPA-2-Typesafe-and-Object-Oriented.htm
抓取连接
当涉及到collection属性时,抓取连接对优化数据访问是非常有帮助的。这是通过预抓取关联对象和减少懒加载开销而达到的。使用 criteria 查询,fetch方法用于指定关联属性
Fetch连接的语义与Join是一样的,因为Fetch操作不返回Path对象,所以它不能将来在查询中引用。在以下例子中,查询Dept对象时employeeCollection对象被加载,这不会有第二次查询数据库,因为有懒加载。
CriteriaQuery<Dept> d = cb.createQuery(Dept.class);
Root<Dept> deptRoot = d.from(Dept.class);
deptRoot.fetch("employeeCollection", JoinType.LEFT);
d.select(deptRoot);
List<Dept> dList = em.createQuery(d).getResultList();
对应SQL: SELECT * FROM dept d,
employee e WHERE d.id = e.deptId
路径表达式
Root实例,Join实例或者从另一个Path对象的get方法获得的对象使用get方法可以得到Path对象,当查询需要导航到实体的属性时,路径表达式是必要的。Get方法接收的参数是在实体元模型类中指定的属性。Path对象一般用于Criteria查询对象的select或where方法。例子如下:
CriteriaQuery<String> criteriaQuery = criteriaBuilder.createQuery(String.class);
Root<Dept> root = criteriaQuery.from(Dept.class);
criteriaQuery.select(root.get(Dept_.name));
参数化表达式
在JPQL中,查询参数是在运行时通过使用命名参数语法(冒号加变量,如 :age)传入的。在Criteria查询中,查询参数是在运行时创建ParameterExpression对象并为在查询前调用TypeQuery,setParameter方法设置而传入的。下面代码片段展示了类型为Integer的ParameterExpression
age,它被设置为24:
ParameterExpression<Integer> age = criteriaBuilder.parameter(Integer.class);
Predicate condition = criteriaBuilder.gt(testEmp.get(Employee_.age), age);
criteriaQuery.where(condition);
TypedQuery<Employee> testQuery = em.createQuery(criteriaQuery);
List<Employee> result = testQuery.setParameter(age, 24).getResultList();
Corresponding SQL: SELECT * FROM Employee WHERE age = 24
排序结果
Criteria查询的结果能调用CriteriaQuery.orderBy方法排序,该方法接收一个Order对象做为参数。通过调用 CriteriaBuilder.asc 或
CriteriaBuilder.Desc,Order对象能被创建。以下代码片段中,Employee实例是基于age的升序排列。
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder .createQuery(Employee.class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.orderBy(criteriaBuilder.asc(employee.get(Employee_.age)));
em.createQuery(criteriaQuery).getResultList();
对应 SQL: SELECT * FROM Employee ORDER BY age ASC
分组
CriteriaQuery 实例的groupBy 方法用于基于Expression的结果分组。查询通过设置额外表达式,以后调用having方法。下面代码片段中,查询按照Employee类的name属性分组,且结果以字母N开头:
CriteriaQuery<Tuple> cq = criteriaBuilder.createQuery(Tuple.class);
Root<Employee> employee = cq.from(Employee.class);
cq.groupBy(employee.get(Employee_.name));
cq.having(criteriaBuilder.like(employee.get(Employee_.name), "N%"));
cq.select(criteriaBuilder.tuple(employee.get(Employee_.name),criteriaBuilder.count(employee)));
TypedQuery<Tuple> q = em.createQuery(cq);
List<Tuple> result = q.getResultList();
对应 SQL: SELECT name, COUNT(*) FROM employeeGROUP BY
name HAVING name like 'N%'
查询投影
Criteria查询的结果与在Critiria查询创建中指定的一样。结果也能通过把查询根传入 CriteriaQuery.select中显式指定。Criteria查询也给开发者投影各种结果的能力。
使用construct()
使用该方法,查询结果能由非实体类型组成。在下面的代码片段中,为EmployeeDetail类创建了一个Criteria查询对象,而EmployeeDetail类并不是实体类型。
CriteriaQuery<EmployeeDetails> criteriaQuery = criteriaBuilder.createQuery(EmployeeDetails.class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.select(criteriaBuilder.construct(EmployeeDetails.class, employee.get(Employee_.name), employee.get(Employee_.age)));
em.createQuery(criteriaQuery).getResultList();
Corresponding SQL: SELECT name, age FROM employee
返回Object[]的查询
Criteria查询也能通过设置值给CriteriaBuilder.array方法返回Object[]的结果。下面的代码片段中,数组大小是2(由String和Integer组成)。
CriteriaQuery<Object[]> criteriaQuery = criteriaBuilder.createQuery(Object[].class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.select(criteriaBuilder.array(employee.get(Employee_.name), employee.get(Employee_.age)));
em.createQuery(criteriaQuery).getResultList();
对应 SQL: SELECT name, age FROM employee
返回元组(Tuple)的查询
数据库中的一行数据或单个记录通常称为元组。通过调用CriteriaBuilder.createTupleQuery()方法,查询可以用于元组上。CriteriaQuery.multiselect方法传入参数,它必须在查询中返回。
CriteriaQuery<Tuple> criteriaQuery = criteriaBuilder.createTupleQuery();
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.multiselect(employee.get(Employee_.name).alias("name"), employee.get(Employee_.age).alias("age"));
em.createQuery(criteriaQuery).getResultList();
对应 SQL: SELECT
name, age FROM employee
结论
Criteria查询是一种以更加面向对象的方式查询数据库的方法、在本文中,我讨论了JPA2中类型安全的Criteria查询,以及对于理解Criteria查询非常重要的元模型的概念。也讨论了Criteria查询中的各种API。
(完)
分享到:
相关推荐
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
JPA包括以下3方面的技术: RM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元...查询语言,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
如果编译器能够对查询执行语法正确性检查,那么对于Java 对象而言该查询就是类型安全的。 Java™Persistence API (JPA) 的2.0 版本引入了Criteria API,这个API 首次将类型安全查询引入到Java 应用程序 中,并为在...
JPA2教程,JPA标准参与者编写,全面接受JPA的方方面面。
包括:解析方法名称以自动生成查询、 NamedQueries、 @Query指定查询、本地查询、命名化参数、更新查询、创建查询的顺序等内容 第四章:客户化扩展JpaRepository 包括:讲述如何在JpaRepository基础上扩展我们自己...
jpa查询 jpql 本地查询 命名查询
JDK1.6的新特性: 注解 其中介绍了JPA框架中的常用注解
Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍.doc
Jpa详细查询实例介绍,教你如何使用JPA,简单,分类实例。
可媲美JDBC的查询能力: JPA的查询语言是面向对象的,JPA定义了独特的JPQL,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。 支持面向对象...
赠送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...
Java:trade_mark:PersistenceAPI(JPA)的2.0版本引入了CriteriaAPI,这个API首次将类型安全查询引入到Java应用程序中,并为在运行时动态地构造查询提供一种机制。本文介绍如何使用CriteriaAPI和与之密切相关的...
Spring Data JPA系列2:SpringBoot集成JPA详细教程,快速在项目中熟练使用JPA.doc
学习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的一本很不错的英文书籍,可以作为一本权威参考。