Hibernate分页查询原理解读

news/2024/7/9 22:51:53 标签: hibernate, sql, 数据库, postgresql, string, oracle
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  }

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

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

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

 

http://www.niftyadmin.cn/n/602524.html

相关文章

32通过tcp发送数组_基于Socket开发TCP传输客户端

​1、程序界面设计TCP客户端在上位机开发中应用很广&#xff0c;大多数情况下&#xff0c;上位机软件都是作为一个TCP客户端来与PLC或其他服务器进行通信的。TCP客户端的主要功能就是连接服务器、发送数据、接收数据、断开连接&#xff0c;而不同场合的区别在于发送数据和接收数…

构造二叉搜索树java_【算法与数据结构】二叉搜索树的Java实现

为了更加深入了解二叉搜索树&#xff0c;博主自己用Java写了个二叉搜索树&#xff0c;有兴趣的同学可以一起探讨探讨。首先&#xff0c;二叉搜索树是啥&#xff1f;它有什么用呢&#xff1f;二叉搜索树&#xff0c; 也称二叉排序树&#xff0c;它的每个节点的数据结构为1个父节…

word保存时,“文档被保存,但是语音识别的数据丢失………”的解决

转自&#xff1a; http://blog.combust.cn/blog/user1/7/archives/2006/5305.shtml 我用WORD的时候老是出来“文档被保存&#xff0c;但是语音识别的数据丢失&#xff0c;因为没有足够的空间存储这些数据。确保没有录音时关闭麦克风&#xff0c;并检查磁盘上的可用存储空间”…

实现粗糙表面_浙大新型吸盘,液体封闭粗糙面,实现攀爬的“最后一公里”

浙江大学的研究人员提出了一种新型的吸盘&#xff0c;通过液体密封的技术较好的解决了真空泄露的问题&#xff0c;成功的在粗糙的表面实现高效的吸附。1654著名的马德堡半球实验首次展示了由真空引起的巨大吸力&#xff0c;目前这种真空抽吸单元广泛用于各种生产线&#xff0c;…

做产品之前要想的一些事

1、多想下自己是不是真的需要这个产品如果自己的不需要这个产品&#xff0c;那如何去说服别人使用这个产品呢&#xff1f; 2、给产品取一个适当的名字产品的名字尽量不要包含小圈子的文化&#xff08;除非产品的受众仅仅是小圈子的人&#xff09;。有大众文化特性的产品名字有助…

chrome opus 杂音_有哪些鲜为人知却非常有意思、好用的 Chrome 扩展?

我现在用的神插件有&#xff1a;1、OneTab&#xff0c;由于查询资料&#xff0c;多的时候需要开启四五十个tab&#xff0c;有了这个之后&#xff0c;一键轻松了2、Wappalyzer&#xff0c;看到不错的网站&#xff0c;就会查看一下他们的前台使用了什么js&#xff0c;后台用的什么…

《六顶思考帽》摘录(4)

《六顶思考帽》摘录&#xff08;4&#xff09;第六部分 绿帽思路第34章 绿色帽子--创造性和横向思维*绿帽特别地和新思想相关联&#xff0c;它也是观察新事物的新途径&#xff0c;绿帽力图摆脱旧想法&#xff0c;以便找出更好的新想法。绿帽思路涉及到事物的变化&#xff0c;绿…

分区供水条件口诀_某建筑消火栓分区供水实例

项目概况&#xff1a;本工程名称为某财富广场&#xff0c;属于一类综合楼(一类高层公共建筑)&#xff0c;其地上建筑总面积为46796.85㎡&#xff0c;建筑高度为91.55m&#xff0c;总楼层为23层。本工程为负三层地下车库&#xff0c;地下车库建筑面积为17991.30㎡&#xff0c;总…