2017-08-25 20 views
1

前言

我使用Spring數據/ JPA /休眠等和實體(與javax.persistence.Entity註釋),它們通過擴展org.springframework.stereotype.CrudRepository庫檢索。CrudRepository的findAll()通過列表包含子表

我有一個實體,我們將其稱爲Bob,它包含另一種類型的實體列表Tom。該列表被稱爲List<Tom> toms;。這是我的數據庫中的多對多關係。

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

這是自動實現的方法是春季需要照顧,我只要我正確命名之一。

我的問題

我需要獲取所有鮑勃在湯姆斯提供的名單是一個子集存儲在每個鮑勃湯姆斯的。也就是說,我提供給該方法的列表是存儲在Bob實體中的列表的子集。

現在,通過上面的代碼,我得到了Toms列表中每個項目的Bob結果。所以如果我的一個鮑勃有這些湯姆斯(「湯姆一」,「湯姆二」,「湯姆藍」},我查詢{「tom-one」,「tom_two」}我得到兩個匹配的同樣的湯姆。同樣,如果我添加一個不匹配鮑勃列表的額外湯姆,第一個匹配的湯姆仍然會這樣做,並返回。像這樣的查詢應該與所有列出的Toms或更多的Bobs匹配。

什麼是我的方法(當前findAllByTomsContains),如果這是可能的適當的命名約定?我目前的解決方法是列表中每個Tom的許多查詢,合併結果的交集(緩慢,痛苦)。

+0

狀況的一個非常混亂的描述))你能簡化它,請?或者提供一個說明性的例子?.. – Cepr0

+0

@ Cepr0我不知道如何進一步簡化它...一個實體包含另一個實體類型的列表。只有當我提供的列表是存儲在實體中的列表的子集/列表時,我才需要從我的數據庫中獲取所有第一個實體類型。你可能需要熟悉Spring來回答這個問題,因爲你命名函數的方式會改變它的功能。 –

回答

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()); 
} 
+0

這聽起來不錯,但它不起作用。它只適用於列表桶只包含一個項目。只要我添加一秒,我就返回0個實體,無論它們是否匹配。 –

+0

@BitFracture檢查更新... – Cepr0

+0

這個非唯一版本的結果是任何匹配列表中任何標籤組合的東西。因此,如果我的查詢中有4個項目,那麼匹配項目中的1,2,3或4將生成匹配實體的響應。 'distinct'避免了重複項,但是不能解決在查詢中少於全部項目的情況下進行匹配的問題。返回的實體必須匹配查詢中的所有項目,但可能會有其他項目。如果我用{「hi」,「cat」}查詢{「hi」,「cat」,「moose」}對Bob,它應該失敗。反過來會成功。 –