簡體   English   中英

嚴格的條款內的Spring數據

[英]Spring Data with strict In-clause

請參閱下面的更新的問題

我想查詢元素,其中每個元素都必須具有所有給定的屬性,例如要返回的一組屬性,而不僅僅是一個。

默認的Spring Data Jpa查詢,其中一個屬性就足夠了:

findAllByAttributeIn(Set<Attribute> setAttr)

示例問題

對於這些元素(抽象,無實際表)

id | attr
----------
1  | A
2  | A,B
3  | A,B,C

使用此過濾器:

setAttr:[A,B]

默認查詢

findAllByAttributeIn(Set<Attribute> setAttr)

返回所有元素(按ID):

[1,2,3]

所需的結果只是第二個元素(帶有[A,B])。

使用給定的Spring Data Jpa查詢關鍵字是否有可能,還是創建自定義查詢的唯一解決方案?

更新的問題:

有兩個實體,媒體和標簽。 它們具有多對多關系,該關系在表Media_has_tags中實現。 每個媒體可以具有任意數量的標簽(0 .. *)。 因此,在我的Spring應用程序中,媒體具有一組標簽作為屬性,反之亦然。 這些課程:

Media = {
id: string,
Set<Tag> tags,
...
}

Tag = {
id: string,
Set<Media> medias,
...
}

相應的表是:

Media
-------
id | ...

Tag
-------
id    | ...
title | ...

Media_has_tags
-------
media_id | tag_id

現在,我有了一組標簽,我想用它們來獲取所有包含該標簽的每個標簽的媒體。 他們當然可以具有更多標簽,但是他們需要具有我提供的集合中的每個標簽。

具體示例:

Media
-------
id | ...
-------
1  |
2  |

Tag
-------
id | title | ...
1  | A     |
2  | B     |

Media_has_tags
-------
media_id | tag_id
1        | 1
2        | 1
2        | 2

給定一組標簽[A,B],我只想要ID為2的媒體,因為ID為1的媒體沒有標簽'B'。

我可以使用關鍵字來實現嗎?是否,如何或必須建立自己的查詢?

抱歉,您的問題最初是不正確的。

findAllByAttributeIn(Set<Attribute> setAttr)

產生這樣的SQL請求:

select * from <table_name> t where t.attribute in (?,?,?...?)

因此,根據RDBMS規則,您的結果是正確且可預期的。 您的抽象表的實際結構是什么?

 id | attr
----------
 1  | A
 2  | A,B
 3  | A,B,C

在現實生活中,可能是這樣的:

 id | attr
----------
 1  | A
 2  | A
 2  | B
 3  | A
 3  | B
 3  | C

再一次-在這種情況下,對於任何RDBMS來說,您得到的結果都是可以的。 請給我們您項目的真實例子

由於問題更新而更新

好的,問題已經解決。 在這種情況下,沒有使用標准CrudRepository語法解決它的直接方法。 但是您可以嘗試編寫@Query請求以設法達到目標。 在清晰的SQL中,必須通過使用group byhaving來解決此問題。 就像這樣:

select media_id 
From media_has_tags
Where tag_id in(1,2 3)
Group by media_id
Having count(*)=3

MediaHasTagsRepository而言,這意味着您必須創建MediaHasTagsRepository接口和適當的查詢方法來獲取MediaHasTagsRepository ID。 之后,您可以輕松找到所需的媒體。 但是這種方法看起來不好恕我直言。 我想最好的方法是通過您的初始查詢找到所有媒體,然后按照Java中的給定條件過濾它們。 例如,您有一個List<Media> ,其中每個元素至少都有一個您要查找的標簽。 然后,我們可以循環查找包含所有已查看標簽的媒體:

List<Media> list; // here is a filled list of medias
Set<String> titles; // here is a set of title interseptions we a looking for 
final List<Media> result = new ArrayList<>();
for (Media media: list) {
  if (!list.getTags().isEmpty()){
    Set<String> tagTitles = list.getTags().stream().map(item -> item.getTitle()).filter(title -> titles.contains(title)).distinct().collect(Collectors.toSet());
    if (tagTitles.size() == titles.size()) {
      result.add(media);
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM