浅析Hibernate分页管理

本文向大家介绍Hibernate分页,可能好多人还不了解Hibernate分页,没有关系,看完本文你肯定有不少收获,希望本文能教会你更多东西。

创新互联建站科技有限公司专业互联网基础服务商,为您提供遂宁托管服务器高防主机,成都IDC机房托管,成都主机托管等互联网服务。

Hibernate中,通过对不同数据库的统一接口设计,实现了透明化、通用化的分页实现机制。

通过Criteria.setFirstResult和Criteria.setFetchSize方法设定分页范围,如:

 
 
 
  1. Criteria criteria = session.createCriteria(TUser.class);
  2. criteria.add(Expression.eq("age", "20"));
  3. //从检索结果中获取第100条记录开始的20条记录
  4. criteria.setFirstResult(100);
  5. criteria.setFetchSize(20);

通过Query.setFirstResult和Query.setMaxResults方法也可以设定分页范围,如:

 
 
 
  1. Query query = session.createQuery("from TUser");
  2. query.setFirstResult(100);
  3. query.setMaxResults(20);  // query.setFetchSize(20);
  4. List list = query.list();

Hibernate中,抽象类org.hibernate.dialect.Dialect指定了所有底层数据库的对外统一接口,通过针对不同数据库提供相应的Dialect实现,数据库之间的差异性得以消除,从而为上层机制提供了透明的、数据库无关的存储层基础。对于分页机制而言,Dialect中定义了一个方法如下:

 
 
 
  1. /**
  2.   * Add a LIMIT clause to the given SQL SELECT
  3.   *
  4.   * @return the modified SQL
  5.   */
  6.  public String getLimitString(String querySelect, boolean hasOffset) {
  7.   throw new UnsupportedOperationException( "paged queries not supported" );
  8.  }
  9.  public String getLimitString(String querySelect, int offset, int limit) {
  10.   return getLimitString( querySelect, offset>0 );
  11.  }

此方法用于在现有Select语句基础上,根据各个数据库自身特性,构造对应的记录返回限定子句。如MySQL中对应的记录限定子句为Limit,Oracle中,通过rownum子句实现。MySQLDialect中的getLimitString实现:

 
 
 
  1. public String getLimitString(String sql, boolean hasOffset) {
  2.   return new StringBuffer( sql.length()+20 )
  3.    .append(sql)
  4.    .append( hasOffset ? " limit ?, ?" : " limit ?")
  5.    .toString();
  6.  }

MySQLDialect.getLimitString方法的实现实际上是在给定的Select语句后追加MySQL所提供的专有SQL子句limit来实现。

Oracle9Dialect中的getLimitString实现:

 
 
 
  1. public String getLimitString(String sql, boolean hasOffset) {
  2.   
  3.   sqlsql = sql.trim();
  4.   boolean isForUpdate = false;
  5.   if ( sql.toLowerCase().endsWith(" for update") ) {
  6.    sqlsql = sql.substring( 0, sql.length()-11 );
  7.    isForUpdate = true;
  8.   }
  9.   
  10.   StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
  11.   if (hasOffset) {
  12.    pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
  13.   }
  14.   else {
  15.    pagingSelect.append("select * from ( ");
  16.   }
  17.   pagingSelect.append(sql);
  18.   if (hasOffset) {
  19.    pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
  20.   }
  21.   else {
  22.    pagingSelect.append(" ) where rownum <= ?");
  23.   }
  24.   if ( isForUpdate ) {
  25.    pagingSelect.append( " for update" );
  26.   }
  27.   
  28.   return pagingSelect.toString();
  29.  }

通过Oracle特有的rownum子句来实现数据部分的读取。SQLServerDialect中的getLimitString实现:

 
 
 
  1. public String getLimitString(String querySelect, int offset, int limit) {
  2.   if ( offset > 0 ) {
  3.    throw new UnsupportedOperationException( "sql server has no offset" );
  4.   }
  5.   return new StringBuffer( querySelect.length()+8 )
  6.    .append(querySelect)
  7.    .insert( getAfterSelectInsertPoint(querySelect), " top " + limit )
  8.    .toString();
  9.  }

通过SQLServer特有的top子句实现。HSQLDialect中的getLimitString实现:

 
 
 
  1. public String getLimitString(String sql, boolean hasOffset) {
  2.   return new StringBuffer( sql.length() + 10 )
  3.     .append( sql )
  4.     .insert( sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit ? ?" : " top ?" )
  5.     .toString();
  6.  }

大多数主流数据库都提供了数据部分读取机制,而对于某些没有提供相应机制的数据库而言,Hibernate也通过其他途径实现了分页,如通过Scrollable ResultSet,如果JDBC不支持Scrollable ResultSet,Hibernate也会通过ResultSet的next方法进行记录定位。Hibernate通过底层对分页机制的良好封装,使得开发人员无需关心数据分页的细节实现,将数据逻辑和存储逻辑分离开来,在提高生产效率的同时,也大大加强了系统在不同数据库平台之间的可移植性。

分享名称:浅析Hibernate分页管理
标题网址:http://www.csdahua.cn/qtweb/news20/489170.html

网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网