Hibernate 能够呈现分页查询,例如:
从第2万条开端取出100条记录
[code:1]Query q = session.createQuery("from Cat as c");
q.setFirstResult(20000);
q.setMaxResults(100);
List l = q.list();[/code:1]
那么Hibernate底层问号呈现分页的呢?实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader那个类里面,仔细泛读该类代码Code,就能够把疑难问题彻底搞清楚。
Hibernate2.0.3的Loader源代码Code第480行以下:
[code:1]if (useLimit) sql = dialect.getLimitString(sql);
PreparedStatement st = session.getBatcher().prepareQueryStatement(sql, scrollable);[/code:1]
假如相应的数据库Databnse定义了限定查询记录的sql语句,那么直接应用特定数据库Databnse的sql语句。
然后来看net.sf.hibernate.dialect.Mysql数据库Dialect:
[code:1]public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append(sql);
pagingSelect.append(" limit ?, ?");
return pagingSelect.toString();
}[/code:1]
这是Mysql数据库的专用分页语句,再来看net.sf.hibernate.dialect.Oracle数据库9Dialect:
[code:1]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();
}[/code:1]
Oracle数据库采用嵌套3层的查询语句结合rownum来呈现分页,这在Oracle数据库上是最快的方法,假如只是一层或者两层的查询语句的rownum别支持order by。
除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里面,大部份人自行参考。
假如数据库Databnse不支持分页的SQL语句,那么根据在配置文档里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,假如你不指定为false,那么Hibernate会应用JDBC2.0的scrollable result来呈现分页,看Loader第430行以下:
[code:1]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}[/code:1]
假如支持scrollable result,应用ResultSet的absolute窍门直接移到查询起点,假如不支持的话,应用循环语句,rs.next一点点的移过去。
可见应用Hibernate,在停止查询分页的操作上,是具有非比寻常大的灵活性,Hibernate会首先尝试用特定数据库Databnse的分页sql,假如没用,再尝试Scrollable,假如不行,最后采用rset.next()移动的办法。
在查询分页代码Code中应用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保证了代码Code在不相同的数据库Databnse之间的可移植性。
评论1:
robbin 写道
再来看net.sf.hibernate.dialect.Oracle数据库9Dialect:
[code:1]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();
}[/code:1]
Oracle数据库采用嵌套3层的查询语句结合rownum来呈现分页,这在Oracle数据库上是最快的方法,假如只是一层或者两层的查询语句的rownum别支持order by。
Oracle数据库的这种呈现假如有order by子句依然有疑难问题。某些时候会导致翻页有记录重复或者遗失,很难找到规范,非比寻常奇怪。
后来去谷歌集团公司了一下,有Oracle数据库行家说需求order by的时候必需带上unique的字段,例如主键或者rowid等。
另外,在应用这种采用rownum的查询时,尽管速读相对较量快,但是后台Oracle数据库在内存和CPU的消耗上会渐增许多。其实除非结果集非比寻常庞大(几万以上),并且必需翻倒很后面(skip的记录很多),采用ResultSet.absolute窍门性能还能够,并没有数量级上的差别。
评论2
joachimz 写道
Oracle数据库的这种呈现假如有order by子句依然有疑难问题。某些时候会导致翻页有记录重复或者遗失,很难找到规范,非比寻常奇怪。
后来去谷歌集团公司了一下,有Oracle数据库行家说需求order by的时候必需带上unique的字段,例如主键或者rowid等。
另外,在应用这种采用rownum的查询时,尽管速读相对较量快,但是后台Oracle数据库在内存和CPU的消耗上会渐增许多。其实除非结果集非比寻常庞大(几万以上),并且必需翻倒很后面(skip的记录很多),采用ResultSet.absolute窍门性能还能够,并没有数量级上的差别。
这种情况经常呈现,包括更多有联系数据库Databnse,理由就排序中呈现相同关键字问号处理
唯一是每次分页都重新查询,也就需求重新排序
另唯一是数据库Databnse也许执行稳定排序
首先表有个默认顺序,比如主键递增,对order by:
假如数据库Databnse采取稳定排序,排序关键字相同时,保持默认顺序(主键递增),那么反复查询反复排序得到的结果都是相同的
假如采用不稳定排序,关键字相同时,顺序不确定,那么反复排序时结果就估计不相同,于是就会呈现看似重复、遗漏的情况
办法很简单,就排序时加上唯一主键,对于各个不稳定排序的数据库Databnse操作系统大都因该那样做
分享到:
相关推荐
Hibernate分页查询小结
Hibernate HQL查询 分页查询 模糊查询.docxHibernate HQL查询 分页查询 模糊查询.docxHibernate HQL查询 分页查询 模糊查询.docxHibernate HQL查询 分页查询 模糊查询.docxHibernate HQL查询 分页查询 模糊查询....
hibernate分页查询 数据库连接,不错的分析,可以尝试下载易用。。
Hibernate 多表连接分页查询示范项目 Hibernate Criteria 多表连接 分页
hibernate 分页查询的实现 hibernate 内置的有分页功能 有三个参数 thisnumber一个是当前页数 sumcount是一页显示多少条数据 sql是用来查询的sql语句 public List getPageList(int thisNumber, int sumCount, ...
STRUTS2+HIBERNATE分页 实现代码详细的分页实现代码实现代码详细的分页实现代码实现代码详细的分页实现代码实现代码详细的分页实现代码
Hibernate分页查询原理解读 , 忘记以前在哪看的了, 现在贴出来和大家分享一下。
Struts2+Sprint+Hibernate分页查询功能,实现过程步骤完整。
分页查询就是把数据库中某张表的记录数进行分页查询,在做分页查询时会有一个Page类,下面是一个Page类,我对其做了详细的注解:。。。。。。。。。。。。
这是用Struts+Hibernate实现的分页及查询
hibernate分页Hibernate 分页的设计和编码
ExtJs4.2+Mysql+Struts2+Hibernate3实现分页查询 1.libs目录缺少hibernate核心jar包 2.libs目录缺少struts jar 3.WebRoot目录缺少ExtJs4.2核心类库 以上信息我都在项目里面注明了,因为这些内容的文件太大了,CSDN不...
Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底搞清楚
hibernate通用分页 方便好用 hibernate通用分页 方便好用
使用hibernate实现的分页效果 orm 映射 session 等技能点 带有注释和案例演示 表生成语句
使用Struts + Spring + Hibernate完成分页笔记使用Struts + Spring + Hibernate完成分页笔记使用Struts + Spring + Hibernate完成分页笔记
NULL 博文链接:https://zhouhaitao.iteye.com/blog/1123917
Struts+Hibernate实现分页.
使用hibernate对list等进行分页查询的完整页面代码,希望能帮助大家,同时有什么疑问的话,希望大家多多指正和给出建议或意见。
一个用springmvc+hibernate+spring maven实现的增、删、改、查的例子