Spring JpaRepository findBy...In(Collection) returns 并集不是交集
Spring JpaRepository findBy...In(Collection) returns union not intersection
我的 JpaRepository 中有一个查询方法
Page<Course> findDistinctCourseByAttrsInAllIgnoreCase(Set<String> a, Pageable page);
通过实例变量 Set<String> attrs
查找 Course
个对象。给定一个包含 "foo" 和 "bar" 的集合 a
,我想找到 Course
的 attrs
包含两个 "foo" 和 "bar",即 Course
与 "foo" 和 "bar" 的交集。这个方法上面returns一个union。
有没有办法使用 JpaRepository 查询来执行此操作,还是我必须进行多次调用并自己找到交集?
在不太可能的情况下,您知道前面 a
的数量,您可以将多个约束与 And
:
结合使用
...AttrsInAndAttrsIn...
但即使前提条件成立,那也很难看。
因此,下一个最佳选择可能是一个规范和一个从 Set<String>
或可变参数构建规范的工厂方法。
您的存储库需要扩展 JpaSpecificationExecutor
。
你可以这样称呼它
Page<Course> findAll(matchesAll(attrs), pageable)
工厂方法看起来像这样:
Specification<Course> matchesAll(Set<String> attrs) {
return (Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
// construct Predicate by combining calls to builder.isMember
// https://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaBuilder.html#isMember(E,%20javax.persistence.criteria.Expression)
}
}
像这样的东西应该可以做到:
@Query("SELECT c FROM Course c JOIN Attribute a WHERE LOWER(a.name) IN (:attributes) GROUP BY c HAVING COUNT(c) = :size")
public Page<Course> findByAllAttributes(@Param("attributes") Set<String> attributes, @Param("size") Integer size, Pageable page);
你这样称呼它:
Page<Course> page = findByAllAttributes(set.stream()
.map(String::toLowerCase)
.collect(Collectors.toSet(),
set.size(), page);
我的 JpaRepository 中有一个查询方法
Page<Course> findDistinctCourseByAttrsInAllIgnoreCase(Set<String> a, Pageable page);
通过实例变量 Set<String> attrs
查找 Course
个对象。给定一个包含 "foo" 和 "bar" 的集合 a
,我想找到 Course
的 attrs
包含两个 "foo" 和 "bar",即 Course
与 "foo" 和 "bar" 的交集。这个方法上面returns一个union。
有没有办法使用 JpaRepository 查询来执行此操作,还是我必须进行多次调用并自己找到交集?
在不太可能的情况下,您知道前面 a
的数量,您可以将多个约束与 And
:
...AttrsInAndAttrsIn...
但即使前提条件成立,那也很难看。
因此,下一个最佳选择可能是一个规范和一个从 Set<String>
或可变参数构建规范的工厂方法。
您的存储库需要扩展 JpaSpecificationExecutor
。
你可以这样称呼它
Page<Course> findAll(matchesAll(attrs), pageable)
工厂方法看起来像这样:
Specification<Course> matchesAll(Set<String> attrs) {
return (Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
// construct Predicate by combining calls to builder.isMember
// https://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaBuilder.html#isMember(E,%20javax.persistence.criteria.Expression)
}
}
像这样的东西应该可以做到:
@Query("SELECT c FROM Course c JOIN Attribute a WHERE LOWER(a.name) IN (:attributes) GROUP BY c HAVING COUNT(c) = :size")
public Page<Course> findByAllAttributes(@Param("attributes") Set<String> attributes, @Param("size") Integer size, Pageable page);
你这样称呼它:
Page<Course> page = findByAllAttributes(set.stream()
.map(String::toLowerCase)
.collect(Collectors.toSet(),
set.size(), page);