【发布时间】:2018-05-08 06:24:59
【问题描述】:
在Spring Data JPA - Reference Documentation 中,标准由以下内容定义:
编写条件实际上是定义域类查询的 where 子句。
规范和谓词似乎具有相同的作用。
criteria、predicate 和 specification 之间有什么区别?
【问题讨论】:
在Spring Data JPA - Reference Documentation 中,标准由以下内容定义:
编写条件实际上是定义域类查询的 where 子句。
规范和谓词似乎具有相同的作用。
criteria、predicate 和 specification 之间有什么区别?
【问题讨论】:
Criteria API 是在 JPA 2.0 中添加的。根据Java Persistence wikibook:
Java Persistence Criteria API 用于通过构建基于对象的查询定义对象来定义动态查询,而不是使用 JPQL 的基于字符串的方法。
CriteriaBuilder 用于构建 CriteriaQuery 对象,然后用于执行查询,例如在此示例中来自 Java persistence wikibook:
// Query for a List of objects.
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root employee = criteriaQuery.from(Employee.class);
criteriaQuery.where(criteriaBuilder.greaterThan(employee.get("salary"), 100000));
Query query = entityManager.createQuery(criteriaQuery);
List<Employee> result = query.getResultList();
Predicate 类是 Criteria API 的一部分,用于构造 where 子句。比如这个修改后的例子取自Java EE 7 documentation:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Predicate predicate1 = cb.equal(pet.get(Pet_.name), "Fido");
Predicate predicate2 = cb.equal(pet.get(Pet_.color), "brown");
cq.where(predicate1.and(predicate2));
Specification 接口由Spring Data JPA project 定义。根据 Oliver Gierke 的以下博客文章 Advanced Spring Data JPA - Specifications and Querydsl:
为了能够定义可重用的谓词,我们引入了 规范接口,该接口源自 Eric Evans 的 Domain Driven Desig book 中引入的概念。 规范可以定义为:
public static Specification<Customer> customerHasBirthday() {
return new Specification<Customer> {
public Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb) {
return cb.equal(root.get(Customer_.birthday), today);
}
};
}
然后在JpaSpecificationExecutor中使用。
List<Customer> customers = customerRepository.findAll(customerHasBirthday());
【讨论】:
不是来自 API Docs,而是在我看来:
Criteria 是一个抽象概念,是Predicates 的集合。 CriteriaQuery 将所有Criteria 设置为Predicates。
由于Criteria 是Criterion 的复数形式,可能会说Predicate 等于Criterion。
Spring Specification 旨在提供在构造 CriteriaQueries 时使用 specification pattern 的方法。
请随时使用 - 最好是 API - 文档来纠正我。
【讨论】: