【问题标题】:Spring JpaRepository findBy...In(Collection) returns union not intersectionSpring JpaRepository findBy...In(Collection) 返回联合而不是交集
【发布时间】:2018-05-11 16:12:17
【问题描述】:

我的 JpaRepository 中有一个查询方法

    Page<Course> findDistinctCourseByAttrsInAllIgnoreCase(Set<String> a, Pageable page);

通过实例变量Set&lt;String&gt; attrs 查找Course 对象。给定一个带有“foo”和“bar”的集合a,我想找到Courses,它的attrs同时包含“foo”“bar”,即@987654327的交集带有“foo”的@s 和带有“bar”的@s。上面的这个方法返回一个联合。

有没有办法通过 JpaRepository 查询来做到这一点,还是我必须自己打多个电话才能找到交叉点?

【问题讨论】:

    标签: mysql spring hibernate spring-data-jpa spring-repositories


    【解决方案1】:

    如果您预先知道as 的数量,您可以将多个约束与And 结合使用:

    ...AttrsInAndAttrsIn...
    

    但即使前提条件成立,那也会非常难看。

    因此,下一个最佳选择可能是 Specification 和 factoryMethod,从 Set&lt;String&gt; 或 varargs 构造 Specification。

    您的存储库需要扩展 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)
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      应该是这样的:

      @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);
      

      【讨论】:

        猜你喜欢
        • 2020-05-05
        • 2017-05-08
        • 2018-01-17
        • 2019-03-03
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        • 2012-06-16
        • 1970-01-01
        相关资源
        最近更新 更多