`

hibernate分页处理

阅读更多
分页在任何系统中都是非常头疼的事情,有的数据库在语法上支持分页,而有的数据库则需要使用可滚动游标来实现,并且在不支持可滚动游标的系统上只能使用单向游标逐步接近要取得的数据。
Hibernate提供了一个支持跨系统的分页机制,这样无论底层是什么样的数据库都能用统一的接口进行分页操作。比如下面的代码就是从第500条开始取出100条记录:
Query q = session.createQuery("from FooBar as f");   
q.setFirstResult(500);   
q.setMaxResults(100);   
List l = q.list();  

那么Hibernate底层如何实现分页的呢?Hibernate根据Query拼装SQL语句的地方是在org.hibernate.loader.Loader类的prepareQueryStatement方法中,对分页支持的代码在这一段中可以发现:
if (useLimit)   
{  
sql = dialect.getLimitString(   
     sql.trim(), //use of trim() here is ugly?  
     useOffset ? getFirstRow(selection) : 0,   
     getMaxOrLimit(selection, dialect)   
    );  
}  

此处调用Dialect的getLimitString方法来得到不同平台的分页语句。
在MySQLDialect中是如下实现getLimitString方法的:
public String getLimitString(String sql, boolean hasOffset)   
{  
return new StringBuffer( sql.length()+20 )  
.append(sql)  
.append( hasOffset ? " limit ?, ?" : " limit ?")  
.toString();  
}  

这是MySQL的专用分页语句,再来看Oracle9Dialect:
public String getLimitString(String sql, boolean hasOffset) {  
   
sql = sql.trim();  
boolean isForUpdate = false;  
if ( sql.toLowerCase().endsWith(" for update") ) {  
  sql = sql.substring( 0, sql.length()-11 );  
  isForUpdate = true;  
}  
   
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );  
if (hasOffset) {  
  pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");  
}  
else {  
  pagingSelect.append("select * from ( ");  
}  
pagingSelect.append(sql);  
if (hasOffset) {  
  pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");  
}  
else {  
  pagingSelect.append(" ) where rownum <= ?");  
}  
 
if ( isForUpdate ) {  
  pagingSelect.append( " for update" );  
}  
   
return pagingSelect.toString();  
}   

Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最好的方式,因为如果只是一层或者两层的查询语句的rownum不能支持order by。
此外Interbase,PostgreSQL,HSQL等也在语法级别上支持分页,具体实现可以查看相应的Dialect实现。如果数据库不支持分页的SQL语句,那么如果数据库支持可滚动游标,那么Hibernate就会采使用ResultSet的absolute方法直接移到查询起点;否则使用循环语句,通过rs.next一步步移动到要查询的数据处:
final int firstRow = getFirstRow( selection );  
if ( firstRow != 0 )   
{  
if ( getFactory().getSettings().isScrollableResultSetsEnabled() )   
{  
// 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();  
}  
}  

可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不支持Scrollable再采用rset.next()移动的办法。这样既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。
分享到:
评论

相关推荐

    hibernate分页Hibernate 分页的设计和编码

    Hibernate分页功能的设计与编码涉及多个方面,包括参数处理、数据库查询优化、前端显示逻辑等。正确实施分页不仅可以提升用户体验,还能显著提高应用程序的性能和响应速度,特别是在处理大数据量的情况下。理解并...

    Hibernate分页查询原理解读

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

    STRUTS2+HIBERNATE详细的分页实现代码详细的分页实现代码

    根据提供的标题、描述、标签及部分内容,我们可以了解到这篇文章主要探讨的是如何在Struts2与Hibernate框架结合下实现分页功能。接下来将详细解析Struts2与Hibernate如何协作完成这一任务。 ### Struts2与Hibernate...

    hibernate分页查询

    让我们深入探讨Hibernate分页查询的相关知识点。 一、Hibernate分页原理 Hibernate分页查询基于SQL的LIMIT和OFFSET子句,通过Session的createQuery或createSQLQuery方法创建查询,并设置FirstResult和MaxResults...

    hibernate分页查询 数据库连接

    此外,优化查询,避免N+1查询问题,合理设计实体关系,都能有效提升Hibernate分页查询的效率。 总结起来,Hibernate的分页查询和数据库连接管理是其强大功能的重要组成部分。正确理解和使用这些特性,能够帮助...

    struts2+spring+hibernate分页显示完整代码

    在Web开发中,分页显示是一项常见的需求,尤其是在处理大量数据时,为了提高用户体验和系统性能,分页显得尤为重要。本篇文章将详细讲解如何在基于Struts2、Spring和Hibernate的项目中实现分页功能。 首先,我们从...

    使用struts、hibernate进行分页处理

    使用struts、hibernate进行分页处理 使用struts、hibernate进行分页处理 使用struts、hibernate进行分页处理 使用struts、hibernate进行分页处理 使用struts、hibernate进行分页处理

    Struts + Hibernate 分页实现

    Struts作为MVC(模型-视图-控制器)架构的一部分,主要用于处理用户请求和控制应用程序流程,而Hibernate则是一个对象关系映射(ORM)工具,它简化了数据库操作,使得开发者可以使用Java对象来操作数据库。...

    hibernate分页代码

    总结起来,"hibernate分页代码"是一个关于如何在Hibernate中进行分页查询的实践示例,适用于在MyEclipse环境下运行。通过Criteria API或HQL,开发者能够方便地实现分页功能,提升应用性能,为用户提供更好的体验。...

    spring+hibernate 分页 +mysql

    在IT行业中,分页是数据库查询的一个重要特性,特别是在处理大量数据时,它可以显著提高系统的性能和用户体验。这里我们讨论的是结合Spring、Hibernate和MySQL实现的分页功能,这是一个常见的技术栈组合,广泛应用于...

    Struts和Hibernate分页及查询

    在"Struts+Hibernate分页及条件查询练习"这个项目中,开发者可能采用了以下步骤: 1. **配置Struts和Hibernate**:首先,需要在项目中引入Struts和Hibernate的相关库,配置Struts的struts-config.xml文件和...

    hibernate实现分页

    ### Hibernate分页基础 1. **Criteria API**:Hibernate的Criteria API允许我们创建动态查询,同时也支持分页。通过设置`setFirstResult()`和`setMaxResults()`方法,可以实现分页效果。例如: ```java Criteria ...

    用户Hibernate实现的一个分页

    一、Hibernate分页基础 1. Hibernate的Query和Criteria API都提供了分页功能。使用`setFirstResult()`方法设置查询开始的位置,即第几条记录,以及`setMaxResults()`方法设置一次返回的最大记录数,这两者结合即可...

    使用hibernate分页查询

    1. **配置Hibernate分页**: 在Hibernate中,我们通常使用`Criteria`或`Query` API进行分页查询。`Criteria`提供了一种更面向对象的方式来执行SQL查询,而`Query` API则对应于原生的SQL语句。在这些API中,我们可以...

    Struts+Hibernate实现分页

    当执行分页查询时,Hibernate会自动处理与数据库的交互,包括SQL的生成和执行。 总结一下,实现Struts+Hibernate的分页功能主要包括以下步骤: 1. 创建实体类并配置ORM映射。 2. 编写Action类,处理分页请求,执行...

    struts+hibernate分页

    综上所述,"struts+hibernate分页"涉及到的主要是如何在Struts的控制层和Hibernate的数据层之间协调处理分页请求,以及在DAO层利用Hibernate的特性实现数据库查询的分页。理解并掌握这两个框架的分页机制,对于开发...

    关于Hibernate分页类和jdbc的sql分页完美融合

    本主题将探讨如何在Hibernate分页类和JDBC的SQL分页方法之间实现完美的融合,以提高性能并提供更好的用户体验。 首先,让我们了解一下Hibernate的分页功能。Hibernate提供了一种方便的方式来处理分页查询,通过...

    Struts2+HIBERNATE实现分页(完整讲解)

    【Struts2+Hibernate实现分页详解】 在Java Web开发中,Struts2和Hibernate是两个非常重要的框架,它们分别负责MVC模式中的控制层和持久层。Struts2提供了强大的Action类和拦截器,使得业务逻辑处理更加简洁;而...

    hibernate分页查询功能

    本示例中,我们看到如何利用Struts2、Spring和Hibernate这三个流行框架来实现分页查询功能。下面我们将详细讲解这个实现过程。 1. **UserDao接口**: UserDao接口定义了分页查询的方法,通过`getUser(int offset, ...

    hibernate 通用分页

    "hibernate 通用分页"是Hibernate框架中一个重要的实用功能,主要用于处理大数据量的查询场景,避免一次性加载过多数据导致内存压力。在这个组件中,`Pagehelp.java`、`Page.java`和`tag.tld`是实现分页的关键文件。...

Global site tag (gtag.js) - Google Analytics