什么是条件、谓词和规范的区别?

28
2个回答

41

标准

标准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());

4
非常清楚易懂。谢谢。 - Varun Singh

5

这并不是来自API文档,而是我对它的理解:

Criteria 是一个抽象概念,类似于 Predicates 的集合。所有的 Criteria 都被设置为 Predicate

由于 CriteriaCriterion 的复数形式,可以说 Predicate 等同于 Criterion

Spring的 Specification 旨在提供实现,以便在构建 CriteriaQueries 时使用规范模式

如果有需要,欢迎通过API文档进行更正。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接