Hibernate 实现分页查询 [转]

原创 2004年09月01日 16:24:00

Hibernate 可以实现分页查询,

例如:
从第2万条开始取出100条记录

      代码:
      Query q = session.createQuery("from Cat as c");
      q.setFirstResult(20000);
      q.setMaxResults(100);
      List l = q.list();


那么Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在
net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底
搞清楚。

Hibernate2.0.3的Loader源代码第480行以下:

      代码:
      if (useLimit) sql = dialect.getLimitString(sql);
      PreparedStatement st = session.getBatcher().prepareQueryStatement(sql,
scrollable);



如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语
句。

然后来看net.sf.hibernate.dialect.MySQLDialect:

      代码:
      public boolean supportsLimit() {
        return true;
      }
      public String getLimitString(String sql) {
        StringBuffer pagingSelect = new StringBuffer(100);
        pagingSelect.append(sql);
        pagingSelect.append(" limit ?, ?");
        return pagingSelect.toString();
      }


这是MySQL的专用分页语句,再来看net.sf.hibernate.dialect.Oracle9Dialect:

      代码:
      public boolean supportsLimit() {
        return true;
      }

      public String getLimitString(String sql) {
        StringBuffer pagingSelect = new StringBuffer(100);
        pagingSelect.append("select * from ( select row_.*, rownum rownum_
from ( ");
        pagingSelect.append(sql);
        pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
        return pagingSelect.toString();
      }


Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,
如果只是一层或者两层的查询语句的rownum不能支持order by。

除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里
面,大家自行参考。

如果数据库不支持分页的SQL语句,那么根据在配置文件里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable
result来实现分页,看Loader第430行以下:


      代码:
      if ( session.getFactory().useScrollableResultSets() ) {
        // we can go straight to the first required row
        rs.absolute(firstRow);
      }
      else {
        // we need to step through the rows one row at a time (slow)
        for ( int m=0; m<firstRow; m++ ) rs.next();
      }



如果支持scrollable result,使用ResultSet的absolute方法直接移到查询起点,如果
不支持的话,使用循环语句,rs.next一点点的移过去。

可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会
首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采
用rset.next()移动的办法。

在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保
证了代码在不同的数据库之间的可移植性。

Hibernate之底层原理的7点整理和总结

开心一笑【老婆想减肥,让老公帮她买减肥药,老公:吃药伤身,现在挺好,多有肉感啊。儿子:其实真有点胖,老公立刻瞪了儿子一眼:小孩子不知道别乱讲,你妈妈这身材我喜欢。然后,趁老婆不注意狠狠的教训了儿子:以...
  • huangwenyi1010
  • huangwenyi1010
  • 2017年03月31日 16:09
  • 3185

Hibernate与Mybatis对比(转)

概述 Hibernate:Hibernate是当前最流行的ORM框架之一,对JDBC提供了较为完整的封装。Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及...
  • worthliu
  • worthliu
  • 2016年06月05日 20:35
  • 437

Hibernate执行原生sql将查询结果直接转为VO

Hibernate原生sql查询将查询结果直接转换为VO,不必非要指定属性大写
  • Mungo
  • Mungo
  • 2015年09月16日 11:41
  • 2719

Hibernate与Jpa的关系,终于弄懂

原文链接:http://blog.sina.com.cn/s/blog_5f1619e80100yoxz.html 我知道Jpa是一种规范,而Hibernate是它的一种实现。除了Hiberna...
  • caiyanzhi123
  • caiyanzhi123
  • 2016年03月08日 15:53
  • 4698

hibernate一些底层实现的解析

一、SessionFactory.openSession() 这里会通过调用hibernate的ConnectionProvider接口的getConnection()获取Connection,而实际...
  • luenxin
  • luenxin
  • 2015年12月17日 10:59
  • 1374

Hibernate Session操纵的对象状态转换图

Session 的 save() 方法 Session 的 save() 方法使一个临时对象转变为持久化对象 Session 的 save() 方法完成以下操作: 把 News 对象加入到 ...
  • u013510614
  • u013510614
  • 2016年01月16日 14:29
  • 391

Timestamp utils 在使用这个的时候,经常涉及到和Hibernate时间的转换

前台传送过来的数据始终都是String涉及到转换,我们更加方便去操作,这样的效果也是比较的不错的。 import java.sql.Timestamp; import java.text.Simple...
  • u012881904
  • u012881904
  • 2016年07月12日 15:00
  • 553

深入理解hibernate中持久化和序列化

虽然平时经常用hibernate的持久化类DO,但是仅限于随手逆向工程生成相应数据库表的持久化类,然后拿来用,根本就没有深入的去了解hibernate的持久化和类的序列化的具体用法原理。闲来没事查查资...
  • dreamrealised
  • dreamrealised
  • 2013年06月18日 19:11
  • 1983

Hibernate多表联查时,手动将结果集转化成JSON

今晚踩了一个坑,在此记录一下: 先看数据库,我们一共用3张表: 1、taone: 2、tatwo: 3、tathree: 我们的目标是: select a.age,b.name,c.s...
  • qq_24531461
  • qq_24531461
  • 2017年04月09日 01:18
  • 581

菜鸟学SSH(十五)——简单模拟Hibernate实现原理

之前写了Spring的实现原理,今天我们接着聊聊Hibernate的实现原理,package com.tgb.hibernate; import java.lang.reflect.Method; ...
  • liushuijinger
  • liushuijinger
  • 2014年07月25日 08:02
  • 4389
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate 实现分页查询 [转]
举报原因:
原因补充:

(最多只允许输入30个字)