奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> Java >> 实现Hibernate分页查询原理解读
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • Tomcat5.0.28下AXIS完

  • JSP环境的配置过程(J

  • 用JAVA写一个日志类程

  • Struts + Hibernate 代

  • Hibernate 使用外部 C

  • 利用Eclipse开发Hiber

  • Java开源项目Hibernat

  • 从Hibernate2到3移植的

  • 实现Hibernate分页查询原理解读
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-21

     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这个类里面,仔细阅读该类代码,就可以把问题彻底搞清楚。//小新技术网www.xker.com
      
      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的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。
    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.