JPA 规范 - 检查多行中的值
JPA Specification - Check values in multiple rows
我的数据库中有一个一对多关系,加入后如下所示:
Person id | Attribute id
--------------------------
A | 1
A | 2
A | 3
我想做的是 return 一个人,如果它有一个我作为参数传递的属性列表,使用 JPARepository 过滤规范,但同一个人有多个行给我带来了一些麻烦,我不知道该怎么做。
作为规范的一些代码示例:
public static Specification<Person> hasAllAttributes(List<Long> attr) {
return (root, query, cb) -> {
Root<Attribute> rootA = query.from(Attribute.class);
root.alias("p");
rootA.alias("at");
Predicate samePerson = cb.equal(root.get(Person_.ID), rootA.get(Attribute_.PERSON));
Predicate hasAttribute = rootA.get(Attribute_.ID).in(attr);
return cb.and(samePerson, hasAttribute);
};
}
这使它像 or 一样工作,如果它具有其中一个属性,它 return 是 Person,如果它包含列表中的多个属性,则 return 多次使用它.所以这实际上不是我要找的,我想它是不完整的,但我不知道如何添加这个限制。
解决了,我只需要了解子查询,然后使用一个将属性与列表匹配并计算匹配项以检查是否返回了列表中的所有项:
public static Specification<Person> hasAllAttributes(List<Long> attr) {
return (root, query, cb) -> {
Subquery<Long> subquery = query.subquery(Long.class);
Root<Attribute> subRoot = subquery.from(Attribute.class);
subquery.select(cb.count(subRoot));
Predicate samePerson = cb.equal(root.get(Person_.ID), subRoot.get(Attribute_.PERSON));
Predicate attributeInList = subRoot.get(Attribute_.ID).in(attr);
subquery.where(cb.and(samePerson, attributeInList));
return cb.equal(subquery, attr.size());
};
}
我的数据库中有一个一对多关系,加入后如下所示:
Person id | Attribute id
--------------------------
A | 1
A | 2
A | 3
我想做的是 return 一个人,如果它有一个我作为参数传递的属性列表,使用 JPARepository 过滤规范,但同一个人有多个行给我带来了一些麻烦,我不知道该怎么做。
作为规范的一些代码示例:
public static Specification<Person> hasAllAttributes(List<Long> attr) {
return (root, query, cb) -> {
Root<Attribute> rootA = query.from(Attribute.class);
root.alias("p");
rootA.alias("at");
Predicate samePerson = cb.equal(root.get(Person_.ID), rootA.get(Attribute_.PERSON));
Predicate hasAttribute = rootA.get(Attribute_.ID).in(attr);
return cb.and(samePerson, hasAttribute);
};
}
这使它像 or 一样工作,如果它具有其中一个属性,它 return 是 Person,如果它包含列表中的多个属性,则 return 多次使用它.所以这实际上不是我要找的,我想它是不完整的,但我不知道如何添加这个限制。
解决了,我只需要了解子查询,然后使用一个将属性与列表匹配并计算匹配项以检查是否返回了列表中的所有项:
public static Specification<Person> hasAllAttributes(List<Long> attr) {
return (root, query, cb) -> {
Subquery<Long> subquery = query.subquery(Long.class);
Root<Attribute> subRoot = subquery.from(Attribute.class);
subquery.select(cb.count(subRoot));
Predicate samePerson = cb.equal(root.get(Person_.ID), subRoot.get(Attribute_.PERSON));
Predicate attributeInList = subRoot.get(Attribute_.ID).in(attr);
subquery.where(cb.and(samePerson, attributeInList));
return cb.equal(subquery, attr.size());
};
}