该文翻译自网络,原文地址:
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
分享到:
相关推荐
1. **JPA是什么**:JPA是一种ORM(对象关系映射)框架,它允许Java开发者以面向对象的方式处理数据,将Java对象映射到数据库中的表,从而简化数据库操作。 2. **JPA起源**:JPA最初由Sun Microsystems开发,作为EJB...
JPA通过JPQL(Java Persistence Query Language)提供了一种面向对象的查询语言,使得开发者可以使用类似SQL的语法查询实体,而无需关心底层数据库的具体实现细节。 4. 准则API(Criteria API) 第九章“Criteria ...
Criteria API则提供了一个更强大且类型安全的查询构建方式。 5. **事务管理(Transaction)**: 在JPA中,事务是通过`EntityManager`进行管理的。你可以使用`begin()`, `commit()`和`rollback()`方法来控制事务的...
在JPA 1.0中,JPQL是一种非常强大的查询语言,它允许开发者以面向对象的方式来构造查询。然而,JPQL查询是以字符串形式存在的,这就意味着即使语法错误也会被编译器忽略,只有在运行时才会抛出异常。如清单1所示: ...
JPA还提供了Criteria API,一种类型安全的查询方式,允许在编译时检查查询语法。Criteria API允许构建复杂的查询条件,动态组合查询,避免了字符串拼接引起的潜在错误。 3. **命名查询** 命名查询是在实体类的元...
- **Querydsl 扩展**:介绍了一个用于查询构建的类型安全查询构建器框架。 - **Web 支持**:提供了集成 Web 层与 Repository 层的方法。 - **Repository 填充器**:描述了填充 Repository 数据的策略。 - **遗留...
5. **查询语言(JPQL)**:介绍了Java Persistence Query Language,一种面向对象的查询语言,类似于SQL。 6. ** Criteria API**:提供了一种类型安全的方式来构建动态查询,避免了字符串拼接造成的错误。 ### 第二...
4. **继承支持**: 支持单表继承、联合继承和多表继承,允许在数据库设计中实现面向对象的继承结构。 5. **事务管理**: JPA与JTA(Java Transaction API)结合,可以方便地进行事务控制,确保数据的一致性。 ### ...
通过JPA,开发者可以使用面向对象的方式来处理数据库操作,而不是直接编写SQL语句。 2. **实体(Entity)**: 在JPA中,实体类是Java对象,它们代表数据库表中的记录。通过在类上使用`@Entity`注解,JPA知道这个类是...
Criteria API提供了一种更动态和类型安全的方式来构建查询。 7. **分页查询**:在描述中提到了分页查询,这通常通过`javax.persistence.Query`的`setFirstResult()`和`setMaxResults()`方法实现。这两个方法分别...
3. **JPA 查询**:JPA 支持两种主要的查询类型:原生 SQL 查询和 JPQL 查询。 - **Query 接口**:提供了执行查询的基础方法。 - **简单查询**:可以使用 Query 接口执行基本的查询操作。 - **使用参数查询**:...
Querydsl是一个类型安全的查询语言,它可以与JPA、JDO、Hibernate等持久层技术配合使用,通过代码生成工具,将查询表达式转换为对应的SQL语句。Specification接口则是Spring Data JPA自带的一种动态查询方式,开发者...
**JPQL(Java Persistence Query Language)**是JPA中的查询语言,类似于SQL,但它是面向对象的,用来查询和操作持久化实体。与SQL不同的是,JPQL主要处理对象,而不是数据库表。在本课程"09_传智播客JPA详解_使用...
JPA通过提供对象/关系映射(ORM)功能,使得开发人员可以使用面向对象的方式来操作数据库,而无需直接编写SQL语句。JPA简化了数据访问,并且支持事务管理,使得在Java应用中处理数据库变得更加方便。 在描述的场景...
SpringBoot简化了Spring应用的初始设置和配置,而Java Persistence API (JPA) 是Java平台上的一个标准,用于对象关系映射(ORM),使得Java开发者能够以面向对象的方式处理数据库操作。 在"SpringBoot+JPA.zip"这个...
9. ** Criteria API**:除了JPQL,JPA还提供了Criteria API,这是一种更强大且类型安全的查询方式,允许在运行时动态构建查询。 10. **命名查询(Named Queries)**:预先在实体类或persistence.xml文件中定义的...
- **元模型**:元模型是JPA 2.0引入的新特性,它允许开发者使用类型安全的方式进行查询操作。通过反射机制自动生成对应的元模型类,使得查询更加直观易读。 ##### 2. 查询 - **JPQL (Java Persistence Query ...
3. **Querydsl**:Spring Data JPA可以与Querydsl结合使用,提供更强大的类型安全的查询能力。Querydsl允许开发者用Java对象表达复杂的查询语句,避免了SQL注入问题。 4. **Specifications**:Spring Data JPA的`...
**JPA(Java Persistence API)**是Java平台上用于对象关系映射(ORM)的一个标准API,它为开发者提供了一种方便的方式来将Java类与数据库表进行对应,使得开发者可以使用面向对象的方式处理数据库操作,而无需过多...
同时,Criteria API提供了一种类型安全的编程式查询方式。 **Hibernate特色功能:** 1. **HQL(Hibernate Query Language)**:Hibernate的扩展查询语言,比JPQL更强大,支持更多复杂的查询操作。 2. ** Criteria...