CrudRepository findAll()按列表包含子列表

时间:2017-08-25 18:56:02

标签: java hibernate spring-data spring-data-jpa

前言

我正在使用通过扩展javax.persistence.Entity的存储库检索的Spring Data / JPA / Hibernate等和实体(注释为org.springframework.stereotype.CrudRepository)。

我有一个实体,我们称之为Bob,它包含另一种类型的实体Tom的列表。此列表称为List<Tom> toms;。这是我的数据库中的多对多关系。

@Repository
public interface BobRepository extends CrudRepository<Bob, String> {
    public Iterable<Bob> findAllByTomsContains(List<Tom> toms);
}

这是Spring为我提供的自动实现的方法之一,只要我正确命名它。

我的问题

我需要获取所有Bobs,其中提供的Toms列表是存储在每个Bob中的toms的子集。也就是说,我向该方法提供的列表是存储在Bob实体中的列表的子集。

现在,通过上面的代码,我得到了Toms列表中每个项目的Bob结果。因此,如果我的一个Bobs有这些Toms {&#34; tom-one&#34;,&#34; tom-two&#34;,&#34; tom-blue&#34;}并且我查询{&# 34; tom-one&#34;,&#34; tom_two&#34;}我得到同一个汤姆的两场比赛。同样,如果我添加一个与bob列表不匹配的额外Tom,则第一个匹配的Tom仍会执行,并返回。像这样的查询应该匹配Bobs与所有列出的Toms或更多。

我的方法(当前为findAllByTomsContains)的适当命名约定是什么,如果可能的话?我目前的解决方法是列表中每个Tom的许多查询,合并一个结果的交集(缓慢,痛苦)。

1 个答案:

答案 0 :(得分:1)

@Query("select b from Bob b join b.toms t where t in (?1) group by b having count(t) >= (select count(t2) from Tom t2 where t2 in (?1))")
Iterable<Bob> findIfSubsetOfTomsExists(List<Tom> toms);

或者:

@Query("select b from Bob b join b.toms t where t in (?1) group by b having count(t) >= ?2")
Iterable<Bob> findIfSubsetOfTomsExists(List<Tom> toms, int tomsCount);

default Iterable<Bob> getIfSubsetOfTomsExists(List<Tom> toms) {
    return findIfSubsetOfTomsExists(toms, toms.size());
}