Hibernate 高级查询技巧——分页查询

来源:互联网 发布:张国荣谭咏麟粉丝知乎 编辑:程序博客网 时间:2024/06/06 02:22

 

分页查询:
在应用系统开发中,尤其是Web应用系统开发中,数据分页是一项普遍而又非常重要的非功能性的技术需求。因为它对于提高系统运行效率,以及减少客户端与服务器间的通信量都有着非常非常重要的作用。但是数据分页在系统实现中往往会带来很大的工作量,在基于JDBC的程序中,更是如此,因为不同的数据库提供了不同的数据分页技术(比如MySQL通过它的Limit字句实现数据分页,而Oracle通过它的rownum字句实现数据分页),这不但给实现带来了一定的困难,也为系统在不同数据间的移植带来了问题。
Hibernate通过对不同的数据库提供统一的接口设计,实现了通用化透明化的数据分页机制,比如我们可以通过QBC查询实现数据分页。如下面代码所示:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“age”,20));
//从检索结果中获取从第100条开始到第120条结束的20条记录
criteria.setFirstResult(100);
criteria.setFetchSize(20);
同样,在Query接口中也提供了与其一致的方法。
这是Hibernate API提供的数据分页技术,但是有时候我们需要针对某一个底层数据库,提供应用系统统一的数据分页机制。这时候我们可以通过实现Hibernate中的抽象类net.sf.hibernate.dialect.DialectHibernate3中为org.hibernate.dialect.Dialect,这个抽象类是Hibernate提供的本地方言类,在本地方言类中封装了对各种不同的主流数据库特性的实现,如果需要针对某种数据库提供方言类支持,可以在Hibernate主配置文件中通过配置来指定(配置hibernate.dialect元素),通过对不同的数据库提供相应的dialect实现,可以消除不同数据库间的差异,从而在上层提供了一个透明的,数据库无关的存储层基础。在Hibernate中提供的主要dialect实现见下表:
Hibernate SQL 方言 (hibernate.dialect)

RDBMS
方言
DB2
net.sf.hibernate.dialect.DB2Dialect
MySQL
net.sf.hibernate.dialect.MySQLDialect
SAP DB
net.sf.hibernate.dialect.SAPDBDialect
Oracle (所有版本)
net.sf.hibernate.dialect.OracleDialect
Oracle 9
net.sf.hibernate.dialect.Oracle9Dialect
Sybase
net.sf.hibernate.dialect.SybaseDialect
Sybase Anywhere
net.sf.hibernate.dialect.SybaseAnywhereDialect
Progress
net.sf.hibernate.dialect.ProgressDialect
Mckoi SQL
net.sf.hibernate.dialect.MckoiDialect
Interbase
net.sf.hibernate.dialect.InterbaseDialect
Pointbase
net.sf.hibernate.dialect.PointbaseDialect
PostgreSQL
net.sf.hibernate.dialect.PostgreSQLDialect
HypersonicSQL
net.sf.hibernate.dialect.HSQLDialect
Microsoft SQL Server
net.sf.hibernate.dialect.SybaseDialect
Ingres
net.sf.hibernate.dialect.IngresDialect
Informix
net.sf.hibernate.dialect.InformixDialect
FrontBase
net.sf.hibernate.dialect.FrontbaseDialect

下面我们主要看看通过Oracledialect实现提供的数据分页机制,对于分页机制而言,dialect中定义了一个方法public String getLimitString(String sql,boolean hasoffset),此方法用于现有的select语句基础上,根据各数据库自身特性,构造对应记录返回限定字句。下面是Oracle9iDialect中的getLimitString实现,在Oracle中实现数据分页机制是通过Oraclerownum字句实现的数据部分提取。
public String getLimitString(String sql,boolean hasoffset){
 StringBuffer pagesql=new StringBuffer(sql.length()+20);
 if(hasoffset){
    pagesql.append(“select * from (select row_.*,rownum rownum_ from(”);
 }
 else{
    pagesql.append(“select * from(”);
 }
 pagesql.append(sql);
 if(hasoffset){
    pagesql.append(“) row_ where rownum<=?) where rownum_>?”);
 }
else{
 pagesql.append(“) where rownum<=?”);
}
return pagesql.toString();
}
这样Hibernate通过对底层分页机制的封装,使得开发人员无需关心数据分页机制的细节实现,在提高了生产效率的同时,也大大提高了数据库间的可移植性。
原创粉丝点击