一尘不染

Hibernate-HQL分页

hibernate

我正在尝试使用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


阅读 181

收藏
2020-06-20

共1个答案

一尘不染

根据JPA 2.0规范的第3.8.6节“查询执行”,

将setMaxResults或setFirstResult应用于涉及对集合进行提取联接的查询的效果是不确定的。

它随数据库的不同而变化,以我的经验,结果是Hibernate通常在内存中而不是在数据库查询级别上进行分页。

我通常所做的是使用一个单独的查询来获取所需对象的ID,然后通过访存联接将其传递到查询中。

2020-06-20