JPA 规范示例 [英] JPA Specifications by Example
问题描述
Spring Boot 在这里.当在实现复杂查询的上下文中使用时,我试图围绕 JpaRepositories
和 Specifications
进行思考,并且正在努力在几个项目上看到森林穿过树木".
Spring Boot here. I'm trying to wrap my head around JpaRepositories
and Specifications
when used in the context of implementing complex queries and am struggling to see the "forest through the trees" on several items.
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
和 CriteriaQuery
代表什么?最重要的是,它听起来就像您需要为每种要应用的过滤器类型创建一个Specification
impl,因为每个规范都被翻译成只有一个谓词……例如,如果我想找到所有姓氏Smeeb"且年龄大于 25 岁的人,听起来我需要写一个 LastnameMatchingSpecification
code> 以及 AgeGreaterThanSpecification
.有人可以为我确认或澄清这一点吗?!
In this toPredicate(...)
method, what do the Root<Person>
and CriteriaQuery
represent? Most importantly, it sounds like you need to create one Specification
impl for each type of filter you want to apply, because each spec gets translated into one and only one predicate...so for instance if I wanted to find all people with a surname of "Smeeb" and an age greater than 25, it sounds like I would need to write a LastnameMatchingSpecification<Person>
as well as a AgeGreaterThanSpecification<Person>
. Can someone confirm or clarify this for me?!
推荐答案
Root
和CriteriaQuery
代表什么?
Root
是您查询的根,基本上是您要查询的什么.在 Specification
中,您可以使用它对此做出动态反应.例如,这将允许您构建一个 OlderThanSpecification
来处理带有 modelYear
和 Drivers
的 Car
dateOfBirth
通过检测类型并使用适当的属性.
Root
is the root of your query, basically What you are querying for. In a Specification
, you might use it to react dynamically on this. This would allow you, for example, to build one OlderThanSpecification
to handle Car
s with a modelYear
and Drivers
with a dateOfBirth
by detecting the type and using the appropriate property.
类似的CriteriaQuery
是完整的查询,您可能会再次使用它来检查它并根据它调整您正在构建的 Predicate.
Similiar CriteriaQuery
is the complete query which you again might use to inspect it and adapt the Predicate you are constructing based on it.
如果我想找到所有姓氏Smeeb"且年龄大于 25 岁的人,听起来我需要写一个 LastnameMatchingSpecification
以及一个 AgeGreaterThanSpecification<人>
.有人可以为我确认或澄清这一点吗?!
if I wanted to find all people with a surname of "Smeeb" and an age greater than 25, it sounds like I would need to write a
LastnameMatchingSpecification<Person>
as well as anAgeGreaterThanSpecification<Person>
. Can someone confirm or clarify this for me?!
我认为你错了.接受 Specification
的 Spring Data 接口只接受一个 Specification
.因此,如果您想查找具有特定名称和特定年龄的所有 Person
,您可以创建一个 Specification
.类似于您引用的示例,它也结合了两个约束.
I think you have that wrong. The Spring Data interfaces accepting Specification
s only accept a single Specification
. So if you want to find all Person
s with a certain name and a certain age you would create one Specification
. Similar to the example you quote which also combines two constraints.
但是您可以创建单独的 Specification
,然后创建另一个组合这些,如果您想单独使用它们,但也可以组合使用.
But you may create separate Specification
s and then create another one combining those if you want to use each separately, but also combined.
这篇关于JPA 规范示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!