Hibernate:选择其中包含所有指定valus的实体

我需要一个棘手的hibernate查询问题的帮助。 我有以下实体:

public class Book { private String bookId; private String author; private String isbn; private Set tags; // getters, setters etc. } 

 public class Tag { private String tagId; private String tagName; // getters, setters, etc. } 

两者之间存在多对多关联,由连接表books_tags_mn以及book_id和tag_id列表示。

我喜欢做的是:我想创建一个hibernate查询/条件查询,它返回所有具有所有特定标记集的书。 选择具有任何一组标签的所有书籍的工作方式是什么。

我一直在搞乱标准API,但并没有真正理解它。 所以我想做什么(在伪HQL中)

 from Book book where book.tags containsAll(:tags) 

对此有任何帮助将非常感谢,所以非常感谢您提前。

您可以使用以下查询:

 select book from Book book where :numberOfTags = (select count(tag.id) from Book book2 inner join book2.tags tag where book2.id = book.id and tag in (:tags)) 

其中numberOfTags是必须匹配的标记集中的标记数。

我建议你创建两个自定义函数或限制为:

  collect(book.tags) -> returns list of tags associated with the book containsAll(bookTagsList, tags) --> validates and returns true if all tags elements are present in bookTagsList returned by the first function "collect" 

一旦定义并注册了函数,您就可以运行HQL / criteria查询,如:

  from Book book where containsAll(collect(book.tags), :tags) 

要么

 session.createCriteria(Book.class).add( Restrictions.add(collect("tags").containsAll(tags)) ).list(); 

请注意:这只是一个分享想法的示例伪代码。

希望这可以帮助!

JB Nizet接受的答案是好的,但是如果你的集合可以包含重复项,那么它将不起作用(可能是一个有效的原因,可能不是标签示例)。

让我们说一些书籍的集合可以包含具有相同名称“MyTag”的重复标签。 然后搜索标签“MyTag”,“YourTag”可以返回具有2个“MyTag”标签但没有“YourTag”标签的书籍。

 select b from Book b where :numberOfTags = (select count(distinct tag.tagName) from Book b2 inner join b2.tags tag where b2.id = b.id and tag.tagName IN (:tagNames)) 

正如我说接受的答案没有错,但是如果你需要支持集合中的重复项,那么你需要添加count(distinct tag.name)