我有一个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>在我从用户获得的代码中.我想找到所有包含此集合中任何标记的消息.例如,如果我们有以下消息:
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 =数组比较是做什么的.
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>标记).这在查询中替换了last = with.
我得到了结果,但还有另一个问题:对于每个匹配的标记重复结果,因为可能会从查询中猜到.例如,使用上面的示例消息搜索[2,7]将返回消息1,消息2返回两次,消息3返回两次.
据我所知,添加某种GROUP BY子句可能对此有所帮助.
predefined query method keywords似乎没有任何与此相关的功能,所以我认为我必须使用@Query或其他东西编写自己的功能.
我似乎无法找出一个可以工作的查询,而且我在H2中不是很有经验,所以我真的不想猜测一个人如何工作.
我不想编写一个方法来查找具有单个标记的所有消息,为每个标记调用它并组合结果,因为这将是丑陋的,并且,如果输入很多标记,则非常慢.我该如何编写查询方法?
解决方法:
List findByTags(Set 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);