休眠-HQL分页

如何解决休眠-HQL分页

这是一个类似于以下问题:HQL-分页的行标识符 我正在尝试使用HQL实现分页。我有一个PostgreSQL数据库。
int elementsPerBlock = 10;
int page = 2; //offset = 2*10

String sqlQuery = \"FROM Messages AS msg \" +
                  \" LEFT JOIN FETCH msg.commands AS cmd \" +   
                  \"ORDER BY msg.identifier ASC\" ;

Query query = session.createQuery( sqlQuery )
                     .setFirstResult( elementsPerBlock * ( (page-1) +1 ) )
                     .setMaxResults( elementsPerBlock );
发生的情况是,Hibernate提取所有消息,并在所有消息加载后返回所需的消息。 因此,Hibernate提取210000个实体,而不是返回的30个实体(每个Messages都有2个命令)。 有没有一种方法可以将开销减少7000倍? 编辑:我尝试添加
.setFetchSize( elementsPerBlock )
。它没有帮助。 编辑2:生成的SQL查询是:
select ... 
from schemaName.messages messages0_ 
left outer join schemaName.send_commands commands1_ 
on messages0_.unique_key=commands1_.message_key 
order by messages0_.unique_identifier ASC
绝对没有LIMIT或OFFSET     

解决方法

        根据JPA 2.0规范的第3.8.6节“查询执行”,   应用setMaxResults的效果   或setFirstResult到涉及以下内容的查询   获取集合的联接是   未定义。 它因数据库而异,根据我的经验,结果是Hibernate通常在内存中而不是在数据库查询级别进行分页。 我通常要做的是使用一个单独的查询来获取所需对象的ID,然后通过访存联接将其传递到查询中。     ,        我正在使用以下解决方案:
/**
 * @param limitPerPage
 * @param page
 * @return
 */
public List<T> searchByPage(int limitPerPage,int page,String entity) {
    String sql = \"SELECT t FROM \" + entity + \" t\";
    Query query = em.createQuery(sql)
            .setFirstResult(calculateOffset(page,limitPerPage))
            .setMaxResults(limitPerPage);
    return query.getResultList();
}

/**
 * @param page
 * @return
 */
private int calculateOffset(int page,int limit) {
    return ((limit * page) - limit);
}
欢迎。     ,        最有可能的是,如果您使用HQL创建自己的查询,则查询生成器方法将无法解析自定义hql查询并对其进行更改。因此,应将“ 4”语句放在HQL查询的末尾,然后绑定偏移量参数。     ,        由于不针对命令实体的某些属性来过滤结果集,因此还可以避免执行SQL连接,并为message的命令配置延迟获取。如果没有加入,Hibernate将使用数据库分页功能。 但是,您必须关心N + 1 seletcs问题,即避免对每个延迟获取的命令属性进行一次选择。您可以通过在休眠映射中设置batch-size属性或在休眠设置中全局设置hibernate.default_batch_fetch_size属性来避免这种情况。 例如:如果您在一个Hibernate会话中获取了100个消息对象,并且将批处理大小设置为10,则当您首次调用消息对象的getCommands()时,Hibernate将获取10个不同消息对象的10个命令关联。查询数量减少到10,再加上原始的消息获取。 在这里看看:http://java.dzone.com/articles/hibernate-tuning-queries-using?page=0,1作者比较了不同的获取策略作为一个简单的示例     ,        我们可以使用Query and Criteria接口实现分页: 使用查询界面的分页: 查询接口有两种分页方法。 1.查询setFirstResult(int startPosition): 此方法采用一个整数,该整数表示结果集中的第一行,从第0行开始。 2.查询setMaxResults(int maxResult): 该方法告诉Hibernate检索固定数量的对象的maxResults。结合使用以上两种方法,我们可以在Web或Swing应用程序中构造一个分页组件。 例:
Query query = session.createQuery(\"FROM Employee\");
query.setFirstResult(5);
query.setMaxResults(10);
List<Employee> list = query.list();
for(Employee emp: list) {            
   System.out.println(emp);
}
使用Criteria接口进行分页: 用于分页的Criteria接口有两种方法。 1.条件setFirstResult(int firstResult): 设置要检索的第一个结果。 2.列出项目条件setMaxResults(int maxResults): 对要检索的对象数设置限制。 例:
Criteria criteria = session.createCriteria(Employee.class);
criteria.setFirstResult(5);
criteria.setMaxResults(10);            
List<Employee> list = criteria.list();
for(Employee emp: list) {            
    System.out.println(emp);
}
    ,        我认为您原来的例外情况是不正确的。   发生的事情是,Hibernate提取所有消息,然后在所有消息全部加载后返回所需的消息。 查询处理期间发生的情况是setFirstResult(calculateOffset(page,limitPerPage))转换为OFFSET而setMaxResults(limitPerPage)转换为LIMIT     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-