【问题标题】:Hibernate: Select entities where collection contains all of the specified valusHibernate:选择集合包含所有指定值的实体
【发布时间】:2012-09-28 21:28:24
【问题描述】:

我需要帮助解决棘手的休眠查询问题。我有以下实体:

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

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

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

我喜欢做以下事情:我想创建一个休眠查询/条件查询,它返回所有具有所有特定标签集的书。起作用的是选择所有具有 any 一组标签的书籍。

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

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

对此的任何帮助将不胜感激,因此在此先感谢您。

【问题讨论】:

    标签: java hibernate collections


    【解决方案1】:

    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)

    【讨论】:

      【解决方案2】:

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

       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/条件查询,例如:

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

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

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

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        您可以使用以下查询:

        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 是标记集中必须匹配的标记数。

        【讨论】:

        • 如果集合可以包含重复项(不在 ID 上),您可能需要添加 count(distinct)
        • 如何将其表示为 Hibernate Criteria 而不是 HQL?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多