`
yiliner
  • 浏览: 214823 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

实现在Hibernate中的分页查询原理解读

阅读更多

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分页查询原理解读

    #### 三、Hibernate分页查询实现原理 ##### 3.1 使用SQL LIMIT实现分页 对于支持LIMIT关键字的数据库(例如MySQL),Hibernate会通过特定的方言(Dialect)来生成包含LIMIT关键字的SQL语句。具体实现如下: ```...

    JQuery,ajax,hibernate+spring,分页查询.rar

    至于“Hibernate分页查询原理解读”,这可能是一个深入解析Hibernate分页机制的文档,包括`FirstResult`和`MaxResults`参数的使用,以及如何有效地缓存查询结果以提高性能。 综合来看,这个压缩包包含了一系列关于...

    ssh框架分页案例,简单易懂

    4. **分页实现原理**:在SSH框架中,分页通常涉及以下步骤: - 计算总页数:根据总记录数和每页显示条数进行计算。 - 查询当前页数据:使用Hibernate的Criteria或Query API,结合LIMIT和OFFSET关键字(或对应的HQL...

    spring3+hibernate3+spring3MVC框架解读

    在`action="&lt;c:url value='/j_security_check'/&gt;"`的例子中,我们看到Spring MVC如何处理请求转发,结合`&lt;fmt:message&gt;`标签实现国际化,提供动态生成URL的能力。 在实际应用中,数据的传递是一个重要环节。在d)...

    java分页代码下载

    ### Java分页原理 分页是一种在数据量较大的情况下对数据进行分割展示的技术手段。它通过限制每页显示的数据数量来提高用户体验,同时降低服务器的压力。在Java Web开发中,通常采用以下几种方式实现分页: 1. **...

    Hibernate开发指南___夏昕

    “Hibernate in Spring”章节讨论了如何将Hibernate集成到Spring框架中,实现更高效、模块化和可维护的应用程序开发。Spring框架提供了强大的依赖注入和AOP(面向切面编程)支持,与Hibernate结合可以简化企业级应用...

    韩顺平2011hibernate3.3视频教程ppt、笔记

    【标题】"韩顺平2011hibernate3.3视频教程ppt、笔记" 涉及的是关于Hibernate框架的深入学习资料,由知名IT讲师韩顺平在2011年推出的系列教程。这个教程通过PPT演示和笔记的形式,详细讲解了Hibernate 3.3版本的相关...

    hibernate经典习题

    **标题解析:**“hibernate经典习题”意味着我们将探讨...通过这些习题,学习者可以深入理解Hibernate的工作原理,并提升在实际项目中使用Hibernate的能力。结合博文链接提供的解答,可以更好地解决实践中遇到的问题。

    hinernate 源代码

    在这个压缩包中,"examples"可能包含了多个示例项目,用于演示Hibernate的各种功能和用法。 首先,Hibernate的核心概念是将Java类映射到数据库表,通过XML或注解定义这种映射关系。这使得开发者可以使用Java对象来...

    喝喝茶编编程(使用dorado基础技术进行Web应用开发)

    - **多层开发模式**:在这种模式中,dorado不仅通过JDBC连接数据库,还会集成其他的业务逻辑框架(如Struts、Spring、Hibernate等),适用于复杂的应用场景。 ### 第一杯茶:单表展现 #### 2.1 页面效果 这部分...

    1000道 互联网Java工程师面试题 485页.pdf

    - 分页插件通过拦截StatementHandler实现,自动解析SQL语句,并生成相应的分页SQL。 11. **结果映射**: - MyBatis通过`&lt;resultMap&gt;`元素来指定SQL执行结果与Java对象之间的映射关系。 - 映射形式包括简单映射...

    Crud-Project-源码.rar

    在Java Spring Boot中,这可能使用JPA(Java Persistence API)或Hibernate等ORM(对象关系映射)工具来完成。在Node.js中,可能会使用Express框架和Mongoose等库操作MongoDB。 2. **读取(Retrieve)**:读取数据...

    快速熟悉Javaweb项目步骤

    - **树形菜单的构建**:如果项目中有树形菜单功能,那么了解其实现原理和数据传递方式是非常必要的。 #### 九、典型页面分析 - **处理和响应形式**:通过分析几种典型的页面,如列表页、详情页等,可以总结出页面...

Global site tag (gtag.js) - Google Analytics