编写criteria实际上是为领域类定义查询的where子句。
规范和谓词似乎具有相同的作用。
Criteria,predicate和specification之间有什么区别?
编写criteria实际上是为领域类定义查询的where子句。
规范和谓词似乎具有相同的作用。
Criteria,predicate和specification之间有什么区别?
标准API是在JPA 2.0中添加的。根据Java Persistence wikibook:
Java持久性标准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文档中的示例:
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 项目 定义。根据 Oliver Gierke 的博客文章《高级 Spring Data JPA - 规范和 Querydsl》:
为了能够定义可重用的谓词,我们引入了从 Eric Evans 的领域驱动设计快速指南中引入的概念派生出的规范接口。 可以这样定义 Specification:
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文档,而是我对它的理解:
Criteria
是一个抽象概念,类似于 Predicates
的集合。所有的 Criteria
都被设置为 Predicate
。
由于 Criteria
是 Criterion
的复数形式,可以说 Predicate
等同于 Criterion
。
Spring的 Specification
旨在提供实现,以便在构建 CriteriaQueries
时使用规范模式
。
如果有需要,欢迎通过API文档进行更正。