Hibernate选择具有条件的顶部和底部n行

Sin*_*hot 21 java hibernate

假设我有两个表,书籍和评论.评论有一个列,星星,可以有1到5之间的值.一本书可以有很多评论.

我如何选择所有书籍,以便使用Criteria API返回每本书的最高和最低3评论(而不是所有评论)?

如果Criteria API不具备,我可以使用其他建议,如HQL,SQL等.

小智 19

您始终可以设置排序asc/desc,然后限制结果.

例如:

criteria.addOrder(Order.desc("id"));
criteria.setMaxResults(1);
Run Code Online (Sandbox Code Playgroud)

不确定它在效率方面的立场.我假设它Select *已经被解雇了之后它正在进行过滤?


Mat*_* B. 14

试试这个,让我知道它是否适合你:

  // you should have the DAO class containing this queries 
  // extend HibernateDaoSupport

  List<Tag> topList = getSession().createQuery("FROM Reviews r WHERE r.book = " 
          + book + " ORDER BY r.stars asc").setMaxResults(3).list();

  List<Tag> bottomList = getSession().createQuery("FROM Reviews r WHERE r.book = " 
          + book + " ORDER BY r.stars desc").setMaxResults(3).list();
Run Code Online (Sandbox Code Playgroud)

  • 不要将 sql 写为字符串连接。这极易受到注入攻击。考虑有人将此作为变量书输入:“任何;删除表评论” (2认同)

Sin*_*hot 5

回答我自己的问题......

我真的很惊讶这是多么困难.所有涉及查询书籍的解决方案和每本书的顶部和底部评论列表都会导致某些数据库中每本书的N个查询,特别是我的(MySql)需要3N.当然,有人可能能够找到一个聪明的方法,但我玩代码,原始SQL,研究其他人做了什么,数据库限制等似乎总是回到那一点.

所以...我最终解决了这个问题.每当我查询书籍时(这是一个非常频繁的查询 - 仅供参考的FYI书籍/评论 - 实际域名不同),我不计算顶部和底部评论.我会在提交新评论时计算顶部/底部.这会将一个"查询"中的"审核"提交为三个查询,但与查询"书籍"相比,提交"审核"的次数相当少.

为此,我在Book,topReviews和bottomReviews中添加了两个新属性,并将它们映射为Review上的一对多列表.然后,我更新了保存新评论的代码,以查询相关图书的顶部和底部评论(2个查询),设置图书上的顶部/底部评论属性(覆盖前一个),并保存图书.任何书籍查询现在返回这些"缓存"的顶部和底部评论.我仍然有一个懒惰的"评论"属性,如果需要,将包含所有评论(不仅仅是顶部/底部) - 另一个一对多映射.

我对其他建议持开放态度.这里的大多数答案都在球场,但由于数据库限制或需要太多查询而错过了问题或无法正常工作.