Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 休眠使用条件选择顶部和底部n行_Java_Hibernate - Fatal编程技术网

Java 休眠使用条件选择顶部和底部n行

Java 休眠使用条件选择顶部和底部n行,java,hibernate,Java,Hibernate,假设我有两张桌子,书和评论。Reviews有一个名为stars的列,其值可以介于1和5之间。一本书可以有很多评论 我如何选择所有书籍,以便使用Criteria API仅返回每本书的前3篇和后3篇评论(而不是所有评论) 如果Criteria API不可用,我会考虑其他建议,如HQL、SQL等。我不认为您可以使用一个查询来做您想做的事情。但是,您当然可以通过两种方式完成(使用带有命名参数的EJBQL): 当然,您可以编写一个简单的helper方法来进行这两个调用,并将结果整理到您喜欢的任何数据结构中

假设我有两张桌子,书和评论。Reviews有一个名为stars的列,其值可以介于1和5之间。一本书可以有很多评论

我如何选择所有书籍,以便使用Criteria API仅返回每本书的前3篇和后3篇评论(而不是所有评论)


如果Criteria API不可用,我会考虑其他建议,如HQL、SQL等。

我不认为您可以使用一个查询来做您想做的事情。但是,您当然可以通过两种方式完成(使用带有命名参数的EJBQL):


当然,您可以编写一个简单的helper方法来进行这两个调用,并将结果整理到您喜欢的任何数据结构中。

这通常是通过类似union的方法来完成的,而在HQL中是无法做到的

不过,您可以在HQL中执行此操作

WHERE id in ([SELECT top 3]) or id in ([SELECT bottom 3])
我没有办法测试这个,但这可能也行

DetachedCriteria topN = [ your criteria ] 
DetachedCriteria bottomN = [ your criteria ] 

session.createCriteria(..._
    .add( Property.or(Property.forName("id").in(topN),Property.forName("id").in(bottomN) )
    .list();

如何将Review和Book作为多对多进行映射,然后在Book的reviews集合上指定:order by=“rating desc”和lazy=“true”


假定使用延迟抓取方法,仅当要从集合中抓取对象时才会抓取数据,但我不确定这一点。要确认,您可以打开Hibernate SQL日志记录并监视在运行时进行了哪些查询。

请尝试此操作,并告诉我它是否适用于您:

  // 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();
//您应该拥有包含此查询的DAO类
//扩展HibernateDaoSupport
List topList=getSession().createQuery(“来自评论r,其中r.book=”
+book+“ORDER BY r.stars asc”).setMaxResults(3.list();
List bottomList=getSession().createQuery(“来自评论r,其中r.book=”
+book+“ORDER BY r.stars desc”).setMaxResults(3.list();

回答我自己的问题

我真的很惊讶这有多困难。所有涉及图书查询的解决方案,以及每本书的顶部和底部评论列表,都会导致在某些数据库上对每本书进行N次查询,特别是对我的(MySql)而言,需要3N次查询。当然,有人可能会想出一个聪明的方法来解决这个问题,但我玩代码、原始SQL、研究其他人所做的事情、数据库限制等等,似乎总是回到这个问题上来

所以。。。我最后把这个问题翻了个遍。当我查询书籍时(这是一个非常频繁的查询-仅供参考的书籍/评论为例-实际域不同),我不计算顶部和底部评论,而是在提交新评论时计算顶部/底部评论。这将提交评论从一个“查询”更改为三个查询,但与查询书籍相比,提交评论的频率相当低

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


我愿意接受其他建议。这里的大多数答案都在大致范围内,但没有找到问题,或者由于数据库限制或需要太多查询而无法工作。

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

例:


不确定它在效率方面的地位。我假设它是在触发一个
Select*
后进行过滤的?

使用org.springframework.data.domain.Pageable的两个HQL查询,如:

在中间层服务中创建可分页和调用repo之前:

Pageable pageableTop = new PageRequest(0, 3, Direction.ASC, "yourFieldToSortBy");
yourRepository.findTopOrderByYourEntity(pageableTop);

Pageable pageableBottom = new PageRequest(0, 3, Direction.DESC, "yourFieldToSortBy");
yourRepository.findTopOrderByYourEntity(pageableBottom);
回购协议:

public interface YourRepository extends CrudRepository<YourEntity, String> {

    @Query("FROM YourEntity")
    List<YourEntity> findTopOrderByYourEntity(Pageable pageable);
}
公共接口YourRepository扩展了Crudepository{
@查询(“来自您的实体”)
列出FindToporByYourEntity(可分页);
}

限制是特定于RDMS的。不要用它。使用
setMaxResults
@Alex-限制也是其中的一部分。你是对的。我从来没用过。不过,他想要的是条件查询,问题似乎也略有不同。他要的是书而不是评论。我暂时撤回了我的答案,因为我不相信我回答的是正确的问题。@Alex-好的观点,他想“选择所有的书,以便每本书只返回最上面和最下面的3个评论”,我认为这是不可能的。通常,当我希望一个实体提供对其他实体集合的“自动”自定义筛选时,我会向第一个实体添加一个
@Transient
方法,该方法对支持集合执行所需筛选,然后返回结果(在新集合实例中)。谢谢。我很确定我不能使用您的Criteria建议,因为DetachedCriteria没有setMaxResults()方法,我需要该方法才能将结果限制在上/下3个(Hibernate的JIRA站点中实际上有一个添加此功能的请求)。不过,我会尝试一下您的HQL。看来您的建议,以及一般来说,我想要的,在标准HQL中是不可能的,就我所知,即使是SQL(至少在MySQL上)。我可能会扭转这个问题,并在保存评论时进行一些预处理,以便将每本书的顶部/底部评论保存在一个特殊的表中。我非常确定这在MySQL中是可能的,发布您的查询,我认为所有ookMySQL都不支持:-(嘎,很好的回答。大多数其他方言都支持这一点,我在MSSQL中尝试过。一个讨厌的解决方案是临时表。如果你发现更好的东西,请发帖子。我需要顶部和底部的评论,所以这不太管用。请看我的答案。谢谢!谢谢。是的,我最后在我的评论DAO中添加了类似的东西,但我更喜欢Criteria API,所以我使用了问题是,我正在查询与cer匹配的所有书籍
Pageable pageableTop = new PageRequest(0, 3, Direction.ASC, "yourFieldToSortBy");
yourRepository.findTopOrderByYourEntity(pageableTop);

Pageable pageableBottom = new PageRequest(0, 3, Direction.DESC, "yourFieldToSortBy");
yourRepository.findTopOrderByYourEntity(pageableBottom);
public interface YourRepository extends CrudRepository<YourEntity, String> {

    @Query("FROM YourEntity")
    List<YourEntity> findTopOrderByYourEntity(Pageable pageable);
}