引用链接:http://www.uandroid.com/home/space.php?uid=4&do=blog&id=49
Hibernate 可以实现分页查询 如下
Query q = session.createQuery("from Cat as c");
q.setFirstResult(10000);
q.setMaxResults(20);
List l = q.list();
生成的sql 语句为
select top 10000 .... from Cat as c
分析:Hibernate 获取到 10000条记录过后再筛选出符合条件的20条记录。
再来看看Hibernate 的 dialect 对 sql server 怎样分页的
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "sql server has no offset" );
}
return new StringBuffer( querySelect.length() + 8 )
.append( querySelect )
.insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )
.toString();
}
由此可以看出Hibernate对 sql server 分页全是采取 top 方式来处理。如记录有10W条以上的话到后面几页效率会非常低。从getLimitString(String querySelect, int offset, int limit)方法可以看出 sql server 不支持 offset 参数(均为0)!!
然而在sql server2005过后支持ROW_NUMBER() 函数,可用该函数大大提高分页效率。但现有的Hibernate api不支持该函数。我们可以重写public String getLimitString(String querySelect, int offset, int limit)方法来实现 ROW_NUMBER 分页,重写的方法如下:
public String getLimitString(String querySelect, int offset, int limit ){
int lastIndexOfOrderBy = getLastIndexOfOrderBy(querySelect);
// 没有 order by 或第一页的情况下
if(lastIndexOfOrderBy<0 || querySelect.endsWith(")") || offset==0)
return super.getLimitString(querySelect, 0, limit);
else {
//取出 order by 语句
String orderby = querySelect.substring(lastIndexOfOrderBy, querySelect.length());
//取出 from 前的内容
int indexOfFrom = querySelect.toLowerCase().indexOf("from");
String selectFld = querySelect.substring(0,indexOfFrom);
//取出 from 语句后的内容
String selectFromTableAndWhere = querySelect.substring(indexOfFrom, lastIndexOfOrderBy);
StringBuffer sql = new StringBuffer(querySelect.length()+100);
sql.append("select * from (")
.append(selectFld)
.append(",ROW_NUMBER() OVER(").append(orderby).append(") as _page_row_num_hb ")
.append(selectFromTableAndWhere).append(" ) temp ")
.append(" where _page_row_num_hb BETWEEN ")
.append(offset+1).append(" and ").append(limit);
return sql.toString();
}
}
让offset参数有效还应重写 public boolean supportsLimitOffset() 方法
public boolean supportsLimitOffset(){
return true;
}
完整的代码如下:
package org.jac.common;
import org.hibernate.dialect.SQLServerDialect;
public class JacSQLServerDialect extends SQLServerDialect {
static int getLastIndexOfOrderBy(String sql){
return sql.toLowerCase().lastIndexOf("order by ");
}
public String getLimitString(String querySelect, int offset, int limit ){
int lastIndexOfOrderBy = getLastIndexOfOrderBy(querySelect);
// 没有 order by 或第一页的情况下
if(lastIndexOfOrderBy<0 || querySelect.endsWith(")") || offset==0)
return super.getLimitString(querySelect, 0, limit);
else {
//取出 order by 语句
String orderby = querySelect.substring(lastIndexOfOrderBy, querySelect.length());
//取出 from 前的内容
int indexOfFrom = querySelect.toLowerCase().indexOf("from");
String selectFld = querySelect.substring(0,indexOfFrom);
//取出 from 语句后的内容
String selectFromTableAndWhere = querySelect.substring(indexOfFrom, lastIndexOfOrderBy);
StringBuffer sql = new StringBuffer(querySelect.length()+100);
sql.append("select * from (")
.append(selectFld)
.append(",ROW_NUMBER() OVER(").append(orderby).append(") as _page_row_num_hb ")
.append(selectFromTableAndWhere).append(" ) temp ")
.append(" where _page_row_num_hb BETWEEN ")
.append(offset+1).append(" and ").append(limit);
return sql.toString();
}
}
//使offset 参数生效
public boolean supportsLimitOffset(){
return true;
}
最后再 hibernate.cfg.xml 配置 dialect
<property name="dialect">
org.jac.common.JacSQLServerDialect
</property>
测试结果如下:
Query q = session.createQuery("from Cat as c order by c.id asc"); //注意要加 order by 才能用到 ROW_NUMBER分页
q.setFirstResult(10000);
q.setMaxResults(20);
List l = q.list();
生成的sql 语句为
select * from (select ....,ROW_NUMBER() OVER(order by cat0_.id asc) as _page_row_num_hb from
cat as cat0_) temp where _page_row_num_hb BETWEEN 10001 and 10020
分享到:
相关推荐
**Struts、Hibernate和SQL Server 2005 分页小项目详解** 在软件开发中,尤其是Web应用,数据分页是一项重要的功能,它能够帮助用户有效地浏览大量数据,提高用户体验。本项目以"Struts+Hibernate+SQL Server 2005...
综上所述,`Hibernate+sqlserver2000分页`是一个结合了ORM框架和数据库分页策略的技术主题。在实际应用中,开发者需要根据业务需求选择合适的分页方法,并注意性能优化,如避免全表扫描,使用索引来加速查询等。理解...
一个基于Hibernate 和 SQLServer 数据库的分页示例,所有文件和数据库备份都在,只是速度不怎么快,如果加上自动生成下拉框,速度就更慢了,单表、10008条测试数据,如果哪位大侠改进了查询速度望告之:vni2007@163....
通过研究这个项目,开发者可以学习到SSH框架的整合、Spring的bean管理和事务处理、Hibernate的数据库操作,以及SQLServer的分页查询技巧。同时,对于提高Web应用的用户体验,理解分页原理和实现方式也是必不可少的。
SQLServer2008Dialect 优化了原来的分页查询数据方法以及在生成SQL时表后增加了with(nolock)
标题与描述均提到了“Hibernate分页的设计和编码”,这表明文章主要聚焦于如何在Hibernate框架中实现数据分页功能。下面将详细解析这一主题的关键知识点。 ### Hibernate分页概念 Hibernate是Java环境下一个开放源...
Struts2、Hibernate3.2、Spring2.0和SQL Server 2000是Java Web开发中的四个关键组件,它们构成了一个强大的企业级应用框架,通常被称为SSH2(Struts2、Spring2、Hibernate2)集成框架。下面将详细阐述这些技术以及...
本文将深入探讨标题和描述中提到的“com.microsoft.sqlserver.jdbc.SQLServerException: 只进结果集不支持请求的操作”这一异常,以及如何在使用Hibernate、Struts进行分页时避免这一问题。我们将从异常的根本原因...
String a = "jdbc:sqlserver://" + a1 + ";DatabaseName=KQ"; int rowTotal = 0; String sql = "SELECT COUNT(*) FROM basic WHERE deptid='" + data.getId() + "'"; try { Connection con = DriverManager....
SSH框架通过Hibernate与SQLServer2005进行交互,执行SQL语句来实现数据的增删改查及分页查询,确保了数据操作的高效性和一致性。 **其他技术** - **分页**:在大型应用中,分页是必不可少的功能,它可以提高页面...
在Java的持久化框架Hibernate中,分页查询是常见的需求,尤其在处理大量数据时,为了提高用户体验,分页展示数据至关重要。本文将探讨Hibernate中两种主要的分页方式:`query.scroll()`和使用`query.setFirstResult...
远程教育系统是一个基于Java技术栈的在线学习平台,利用了Struts1.2、Hibernate3.1、Spring2.0和Tomcat5.0等组件,搭配SqlServer2005数据库,构建了一个功能完善的系统。这里我们将深入探讨这些技术及其在远程教育...
8. **分页插件和框架**:在开发环境中,许多ORM框架如Hibernate、MyBatis提供了分页插件,可以简化分页操作,避免手动编写复杂的SQL。 9. **分页与排序**:分页通常与排序结合使用,确保每次加载的都是有序的数据。...
标题与描述中的关键词“hibernate SQL Server 2000 存储过程”指出了本文档的主题,即在Hibernate框架下如何与SQL Server 2000的存储过程进行交互。下面将深入探讨这一主题,包括为什么在Hibernate中使用存储过程、...
而真分页,又叫物理分页,它是直接在数据库层面进行分页操作,只加载当前页的数据,对内存压力小,适用于大数据量的场景。 ### Hibernate中的假分页 在Hibernate中,实现假分页通常借助于Criteria API或者HQL...
<property name="hibernate.connection.url">jdbc:sqlserver://127.0.0.1:1433;DatabaseName=Tb_soft <property name="hibernate.connection.username">sa <property name="hibernate.connection.password">...
在JSP中,你可以使用JSTL(JavaServer Pages Standard Tag Library)或者其他标签库来动态生成分页链接,根据当前页码计算出其他页码,并展示数据列表。同时,需要在页面上显示页码和每页记录数的输入框,以便用户...
4. **SQL查询**:在SQL中,我们可以使用`LIMIT`和`OFFSET`(MySQL)或`FETCH NEXT`和`OFFSET`(SQL Server)来实现分页查询。 5. **数据处理**:查询结果返回后,应用需要对数据进行处理,如转换为对应的Java对象,...
1. **Hibernate**: Hibernate是一个开源的Java库,它提供了对象关系映射(ORM)解决方案,允许Java开发者将Java对象与关系数据库的表进行映射,减少了对SQL的直接依赖。在本项目中,Hibernate被用来执行数据库查询,...
**Hibernate** 是一个强大的对象关系映射(ORM)框架,它允许开发者用Java对象来操作数据库,而无需直接编写SQL语句。在分页实现中,Hibernate提供了Criteria API或HQL(Hibernate Query Language)来执行带有分页...