春季数据严格段落



请参阅下面的更新问题

我想查询每个元素都必须具有所有给定属性的元素。一个要返回的集合,不仅是一个。

默认弹簧数据JPA查询,其中一个属性就足够了:

findAllByAttributeIn(Set<Attribute> setAttr)

示例问题

对于这些元素(抽象,没有实际表(

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

使用此过滤器:

setAttr:[a,b]

默认查询

findAllByAttributeIn(Set<Attribute> setAttr)

返回所有元素(通过IDS(:

[1,2,3]

所需的结果仅是第二个元素(使用[a,b](。

给定的弹簧数据JPA查询关键字是可能的,还是创建自定义查询的唯一解决方案?

更新的问题:

有两个实体,媒体和标签。他们具有多次多次的关系,该关系已在表Media_has_tags中实现。每个媒体都可以具有任意数量的标签(0 ..*(。因此,在我的春季应用中,媒体具有一组标签作为属性,反之亦然。课程:

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-rules,您的结果是正确且可预期的。您的摘要表的真实结构是什么?

 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

又是 - 在这种情况下,您获得的结果对于任何RDBM都可以。给我们您项目的真实示例,请

更新是因为问题更新

好吧,问题已经澄清。在这种情况下,没有直接的方法可以使用标准的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

在springdata方面,这意味着您必须创建MediaHasTagsRepository接口和适当的查询方法才能获得IDS。之后,您可以轻松找到所需的媒体。但是这种方法看上去并不好恕我直言。我想最好的方法是通过您的初始查询找到所有媒体,而不是通过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);
    }
  }
}

相关内容

  • 没有找到相关文章

最新更新