采用JPQL检索方式时,在应用程序中需要定义基于字符串形式的JPQL查询语句。QBC API提供了检索对象的另一种方式,它提供了一种更加面向对象的查询方法,应用程序不需要提供查询语句,而是通过QBC API中的相关的接口和类来设定需要检索的数据,包括设定检索条件等。
QBC API位于javax.persistence.criteria包中,主要包括以下接口:
- CriteriaBuilder接口:它是生成CriteriaQuery实例的工厂类。
- CriteriaQuery接口:它是主要的查询接口,通过它来设定需要查询的数据。
- Root接口:指定需要检索的对象图的根节点对象。
- Selection接口:指定查询语句。它有个Expression子接口,指定查询表达式。
- Expression接口:指定查询表达式。它有个Predicate子接口,指定查询条件。
- Predicate接口:指定查询条件。
以下程序代码用于检索年龄大于21的Customer对象:
//创建负责生成CriteriaQuery的工厂
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
//创建CriteriaQuery对象
CriteriaQuery<Customer> criteriaQuery =
criteriaBuilder.createQuery(Customer.class);
//指定需要检索的对象图的根节点对象
Root<Customer> root = criteriaQuery.from(Customer.class );
criteriaQuery.select(root);
//指定查询条件,其中“Customer_”为元数据类
Predicate predicate = criteriaBuilder.gt(
root.get(Customer_.age), 21);
criteriaQuery.where(predicate);
//到数据库中查询数据,返回查询结果
List<Customer> result=entityManager
.createQuery(criteriaQuery)
.getResultList();
以上程序代码中的root.get(Customer_.age)方法访问了元模型类Customer_,root.get(Customer_.age)方法也可以简写为root.get("age")。
对于以上程序代码,当运行Query的getResultList()方法时,Hibernate执行的SQL查询语句为:
select ID,NAME,AGE from CUSTOMERS where AGE>21;
从以上程序代码看出,QBC检索方式包括以下步骤。 (1)创建CriteriaBuilder和CriteriaQuery对象。 (2)通过Root对象指定需要检索的对象图的根节点对象,Hibernate根据它来决定查询语句中的主表。 (3)通过Predicate对象指定查询条件,Hibernate根据它来决定查询语句中where子句的内容。 (4)通过Query接口查询数据。
CriteriaBuilder接口提供了一系列设定查询条件的方法,这些方法都返回Predicate对象:
- 表示“等于”的equal()方法
- 表示“不等于”的notEqual()方法
- 表示“大于”的gt()方法
- 表示“大于等于”的 ge()方法
- 表示“小于”的lt()方法
- 表示“小于等于”的le()方法
- 表示“位于…之间”的between()方法
- 表示“相似”的like()方法
- 表示“不为空”的isNotEmpty()方法
- 表示“与操作”的and()方法
- 表示“或操作”的or()方法
QBC允许指定多个查询条件。以下程序代码用于检索姓名以字符“T”开头,并且年龄为21的Customer对象:
Root<Customer> root = criteriaQuery.from(Customer.class );
criteriaQuery.select(root);
//指定查询条件,其中“Customer_”为元数据类
List<Predicate> predicatesList = new ArrayList<Predicate>();
Predicate predicate1 = criteriaBuilder.like(
root.get(Customer_.name),"T%");
Predicate predicate2 = criteriaBuilder.gt(
root.get(Customer_.age), 21);
predicatesList.add(predicate1);
predicatesList.add(predicate2);
criteriaQuery.where(predicatesList.toArray(
new Predicate[predicatesList.size()]));
//到数据库中查询数据,返回查询结果
List<Customer> result=entityManager
.createQuery(criteriaQuery)
.getResultList();
对于以上程序代码,当运行Query的getResultList()方法时,Hibernate执行的SQL查询语句为:
select ID,NAME,AGE from CUSTOMERS where NAME like 'T%' and AGE=21;
CriteriaQuery也支持方法链编程风格,例如:
criteriaQuery.select(root)
.where(predicate);