Spring Boot 在这里。当在实现复杂查询的上下文中使用时,我试图将我的头围绕在 JpaRepositoriesSpecifications 上,并且我正在努力在几个项目上看到“穿过树林的森林”。
Specification 的规范示例如下:

public class PersonSpecification implements Specification<Person> {
    private Person filter;

    public PersonSpecification(Person filter) {
        super();
        this.filter = filter;
    }

    public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq,
            CriteriaBuilder cb) {
        Predicate p = cb.disjunction();

        if (filter.getName() != null) {
            p.getExpressions()
                    .add(cb.equal(root.get("name"), filter.getName()));
        }

        if (filter.getSurname() != null && filter.getAge() != null) {
            p.getExpressions().add(
                    cb.and(cb.equal(root.get("surname"), filter.getSurname()),
                            cb.equal(root.get("age"), filter.getAge())));
        }

        return p;
    }
}

在这个 toPredicate(...) 方法中,Root<Person>CriteriaQuery 代表什么?最重要的是,听起来您需要为要应用的每种类型的过滤器创建一个 Specification impl,因为每个规范都被翻译成一个且只有一个谓词……例如,如果我想找到所有有姓氏的人“Smeeb”的年龄大于 25 岁,听起来我需要写一个 LastnameMatchingSpecification<Person> 以及一个 AgeGreaterThanSpecification<Person> 。有人可以为我确认或澄清这一点吗?!

最佳答案



Root 是您查询的根,基本上是您要查询的内容。在 Specification 中,您可以使用它对此做出动态 react 。例如,这将允许您构建一个 OlderThanSpecification 来处理 Car s 与 modelYearDrivers 使用适当的类型 0.1343141 检测 0.1343141

类似的 dateOfBirth 是完整的查询,您可以再次使用它来检查它并根据它调整您正在构建的 Predicate。



我认为你错了。接受 CriteriaQuery 的 Spring Data 接口(interface)只接受单个 Specification 。因此,如果您想找到具有特定名称和特定年龄的所有 Specification ,您可以创建一个 Person 。类似于您引用的示例,它也结合了两个约束。

但是您可以创建单独的 Specification s,然后创建另一个组合这些,如果您想单独使用每个,但也组合使用。

关于spring-boot - JPA 规范示例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48647847/

10-13 09:53