Hibernate如何实现分页的?

解决项目中一问题时, 由于涉及到Hibernate的分页功能, 于是打草搂兔子地研究了下Hibernate分页功能的实现。

我们先来看用Hibernate来实现分页的代码片段:
Criteria c = session.createCriteria(Area.class);

c.setFirstResult(10);
c.setMaxResults(20);

List list = c.list();

上面c.list()执行后,就看到了满足条件的十条记录,即第11到20这十条。

那么在Hibernate内部这是怎么实现的呢?

截下了Hibernate生成的sql(如何截,请见另一篇博文:Hibernate初始化时如何生成SQL语句?),它是这样的:
select a.* from

(
select row_.*, rownum rownum_ from
( select this_.id as id0_0_, this_.ALIAS_ID as ALIAS2_0_0_, this_.COMM as COMM0_0_, this_.CREATE_TIME as CREATE4_0_0_, this_.NAME as NAME0_0_ from AREA this_ ) row_
where rownum <= 20
) a

where a.rownum_ > 10
注:为了下文说明方便,上面sql是我又加了些东东,如a和参数(10,20)。
那么这个sql是怎么生成的呢?
Debug过程中,经历了超人般的跨越后,最终在org.hibernate.dialect.Oracle9Dialect中的getLimitString方法中,看到了整个sql的组装过程。


源码就不粘在这了, 看它的原理,发现它巧妙地利用了Oracle数据中的伪列rownum。

这里的sql有两个临时表 row_ 和 a。
l 第一个表row_里包含了满足条件的所有结果, 可能是1000条。
l 第二个表a,这里利用Oracle的伪列rownum, 取前20条, 并把这个伪列rownum(临时值)作为表a的一个真正存在的列保存下来, 这样就能光明正大地用a.rownum_ > 10过滤条件了。


至此,解释并记录完毕, 收队!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值