Hibernate实现分页查询的简要分析

本文向大家介绍Hibernate查询分页,可能好多人还不了解Hibernate查询分页,没有关系,下面有一个例子,从第2万条开始取出100条记录看完本文你肯定有不少收获,希望本文能教会你更多东西。

Java代码

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行以下:

Java代码

if (useLimit); sql = dialect.getLimitString(sql);;
PreparedStatement st = session.getBatcher();.prepareQueryStatement(sql, scrollable);;

如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语句。

然后来看net.sf.hibernate.dialect.MySQLDialect:

Java代码

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:

Java代码

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行以下:

Java代码

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查询分页的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。

时间: 2022-12-21

Hibernate实现分页查询的简要分析的相关文章

hibernate+struts2分页查询的问题

问题描述 struts.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEstrutsPUBLIC"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd"><struts><packag

实现在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这个类里面,仔细阅读该类代码,就可以把问题彻

hibernate中带查询条件的分页

所谓分页,从数据库中分,则是封装一个分页类.利用分页对象进行分页. 但,分页往往带查询条件.   分页类的三个重要数据:[当前页码数],[数据库中的总记录数],[每页显示的数据的条数] 原理:select * from  [表名] where   [字段名]  like   ['%条件%']    limit  [开始查询的索引],[每页显示的数据]   带查询条件的分页分两步 (1)第一步:查询出符合条件的数据的总条数  ---->select count(*) from [表名] where

Hibernate查询,返回new对象(注意这个新定义的类要有构造函数),使用sql带条件分页查询并且把结果显示到一个对象的集里面的解决方案

 IIndexDao package com.ucap.netcheck.dao; import com.ucap.netcheck.combination.beans.IndexCombinationBean;import com.ucap.netcheck.common.Page;import com.ucap.netcheck.common.dao.GenericDao;import com.ucap.netcheck.entity.Site; /**    * @Title: IIn

用MyEclipse开发的Hibernate + JSP分页代码

下载后导入项目到 MyEclipse , 然后修改数据库连接参数即可测试. 我这用 的是 MySQL 数据库. 用 JSP 是因为 Hibernate 可以配合各种框架, 因此在代 码里我已经尽量的把页面和后台的直接变量耦合分隔开了. 部分代码显示: 相关 SQL: CREATE TABLE `user` ( `id` int(11) NOT NULL, `username` varchar(200) NOT NULL, `password` varchar(20) NOT NULL, `age

详解Oracle的几种分页查询语句

分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= 40 ) WHERE RN >= 21 其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句.ROWNUM <= 40和RN >= 21控制分页查询的每页的范围. 上面给出的这个分页查询语句,在大多数情况拥有较高的效率.分页的目的就是控制输出结果集大小,

浅析Hibernate Struts分页

Hibernate有很多值得学习的地方,这里我们主要介绍Hibernate Struts分页,包括介绍Hibernate查询等方面. 在进行web应用开发的时候经常要对Hibernate Struts分页处理,经常看到一些人在问Hibernate Struts分页处理的问题,现在我把自己的处理方法写在这儿,希望能对需要进行Hibernate Struts分页处理的朋友有所帮助. 一.在Hibernate Struts分页有两种结构: 1. 在Action中通过DAO查询出所有的记录,然后加到se

Oracle、 Mysql 、 SQLserver 分页查询

MYSQL 分页最简单了. SELECT * FROM Account  WHERE (usertype='base' or usertype='home' or usertype='salse')  and logindate is not null order by logindate desc LIMIT 起始行, 每页多少行 LIMIT 接受一个或两个数字参数. 参数必须是一个整数常量. 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量, 第二个参数指定返回记录行的最大数目. 初

hibernate进行分页时,sessionFactory为null报空指针异常

问题描述 hibernate进行分页时,sessionFactory为null报空指针异常 从网上查了许都,都没能解决,不知道是配置文件有问题,还是方法写的有问题 解决方案 dao层实现类: /** @ClassName: BaseDaoImpl @Description: 基础dao实现 @author john @date 2015年2月26日 下午3:27:15 */ @SuppressWarnings("unchecked") public abstract class Bas