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)