java - 查找集合字段包含任何给定项目的所有条目

标签 java spring spring-data-jpa h2

我有一个 Spring Boot 应用程序,它包含这样一个实体(为了紧凑而删除了一些字段):

@Entity
public class Message extends AbstractPersistable<Long> {
    @ManyToMany(targetEntity = Tag.class, fetch = FetchType.EAGER)
    private Set<Tag> tags;
    // getter and setter for tags here
}

Tag只是一个带有名称字段的简单实体。


现在,我有另一个 Set<Tag>在我从用户那里获得的代码中。我想找到所有 Message具有此集合中任何标签的。例如,如果我们有以下消息:

ID    TAGS
1     1, 2, 3
2     2, 5, 7
3     2, 4, 7

然后查询应该给定集合 [3, 4]返回消息 1 和 3。


我尝试编写这个存储库:

public interface MessageRepository extends JpaRepository<Message, Long> {
    List<Message> findByTags(Set<Tag> tag);
}

我启用了 query logging我的代码生成了一个查询,我在这里做了一些清理。在我尝试的情况下,查询没有产生任何结果,我不知道 scalar = array 是什么比较正在做。

SELECT message.id AS id FROM message
LEFT OUTER JOIN message_tags ON message.id = message_tags.message_id
LEFT OUTER JOIN tag ON message_tags.tags_id = tag.id
WHERE tag.id = (1,2,3,4,5) -- this is the input set

按照@AliDehghani 的建议,我尝试将方法编写为 findByTagsIn(Set<Tag> tag) .这取代了最后一个 =in在查询中。

我得到了结果,但还有另一个问题:每个匹配标签的结果都重复了,正如人们可能从查询中猜测的那样。例如,搜索 [2, 7]使用上面的示例消息将返回消息 1、消息 2 两次和消息 3 两次。

据我所知添加某种 GROUP BY子句在这里可能会有所帮助。


predefined query method keywords似乎也没有与此相关的任何功能,所以我想我必须使用 @Query 编写自己的功能或其他东西。

我似乎也想不出一个可行的查询,而且我在 H2 方面也不是很有经验,所以我也不想猜测一个可能如何工作。

我不想编写一种方法来查找所有带有单个标签的消息,为每个标签调用它并合并结果,因为那样会很丑陋,而且如果输入大量标签,速度会非常慢。我应该如何编写我的查询方法?

最佳答案

List findByTags(Set tag);

从查询日志中可以看出,这种查询方法只会查找在给定的 tag 参数中标记了所有标签的邮件,这不是您想要的。

为了查找带有这些标签的邮件,您可以使用以下查询方法:

List<Message> findByTagsIn(Set<Tag> tag);

I got results, but there was another problem: the results were repeated for each matching tag as one might guess from the query.

为了摆脱那些重复的消息,您可以只获取不同的值:

List<Message> findDistinctByTagsIn(Set<Tag> tag);

关于java - 查找集合字段包含任何给定项目的所有条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41910464/

相关文章:

java - 我的电脑无法安装 Java

java - sonarqube 5.x 差分 View KO(JSON 解析异常)

java - 使用 maven 为 spring-boot web 应用程序生成工作 war 文件

spring - 获取错误-java.lang.NoClassDefFoundError : javax/faces/component/behavior/ClientBehaviorHolder

java - 如何使用java在Repository Spring Boot中执行将由特定符号分隔的查询

java - 使用jpa规范时如何在排序中应用合并表达式

java - X-Frame-Options 支持同一域的不同子域

java - 没有本地生成的身份值

java - 自定义查询方法返回 Object[] 而不是实体列表

java - EntityManager (Hibernate + MySQL) 在更新时截断空白处的字符串