分頁查詢:
在應(yīng)用系統(tǒng)開發(fā)中,尤其是Web應(yīng)用系統(tǒng)開發(fā)中,數(shù)據(jù)分頁是一項(xiàng)普遍而又非常重要的非功能性的技術(shù)需求。因?yàn)樗鼘τ谔岣呦到y(tǒng)運(yùn)行效率,以及減少客戶端與服務(wù)器間的通信量都有著非常非常重要的作用。但是數(shù)據(jù)分頁在系統(tǒng)實(shí)現(xiàn)中往往會帶來很大的工作量,在基于JDBC的程序中,更是如此,因?yàn)椴煌臄?shù)據(jù)庫提供了不同的數(shù)據(jù)分頁技術(shù)(比如MySQL通過它的Limit字句實(shí)現(xiàn)數(shù)據(jù)分頁,而Oracle通過它的rownum字句實(shí)現(xiàn)數(shù)據(jù)分頁),這不但給實(shí)現(xiàn)帶來了一定的困難,也為系統(tǒng)在不同數(shù)據(jù)間的移植帶來了問題。
Hibernate通過對不同的數(shù)據(jù)庫提供統(tǒng)一的接口設(shè)計(jì),實(shí)現(xiàn)了通用化透明化的數(shù)據(jù)分頁機(jī)制,比如我們可以通過QBC查詢實(shí)現(xiàn)數(shù)據(jù)分頁。如下面代碼所示:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“age”,20));
//從檢索結(jié)果中獲取從第100條開始到第120條結(jié)束的20條記錄
criteria.setFirstResult(100);
criteria.setFetchSize(20);
同樣,在Query接口中也提供了與其一致的方法。
這是Hibernate API提供的數(shù)據(jù)分頁技術(shù),但是有時(shí)候我們需要針對某一個底層數(shù)據(jù)庫,提供應(yīng)用系統(tǒng)統(tǒng)一的數(shù)據(jù)分頁機(jī)制。這時(shí)候我們可以通過實(shí)現(xiàn)Hibernate中的抽象類net.sf.hibernate.dialect.Dialect在Hibernate3中為org.hibernate.dialect.Dialect,這個抽象類是Hibernate提供的本地方言類,在本地方言類中封裝了對各種不同的主流數(shù)據(jù)庫特性的實(shí)現(xiàn),如果需要針對某種數(shù)據(jù)庫提供方言類支持,可以在Hibernate主配置文件中通過配置來指定(配置hibernate.dialect元素),通過對不同的數(shù)據(jù)庫提供相應(yīng)的dialect實(shí)現(xiàn),可以消除不同數(shù)據(jù)庫間的差異,從而在上層提供了一個透明的,數(shù)據(jù)庫無關(guān)的存儲層基礎(chǔ)。在Hibernate中提供的主要dialect實(shí)現(xiàn)見下表:
Hibernate SQL 方言 (hibernate.dialect)
下面我們主要看看通過Oracle的dialect實(shí)現(xiàn)提供的數(shù)據(jù)分頁機(jī)制,對于分頁機(jī)制而言,dialect中定義了一個方法public String getLimitString(String sql,boolean hasoffset),此方法用于現(xiàn)有的select語句基礎(chǔ)上,根據(jù)各數(shù)據(jù)庫自身特性,構(gòu)造對應(yīng)記錄返回限定字句。下面是Oracle9iDialect中的getLimitString實(shí)現(xiàn),在Oracle中實(shí)現(xiàn)數(shù)據(jù)分頁機(jī)制是通過Oracle的rownum字句實(shí)現(xiàn)的數(shù)據(jù)部分提取。
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通過對底層分頁機(jī)制的封裝,使得開發(fā)人員無需關(guān)心數(shù)據(jù)分頁機(jī)制的細(xì)節(jié)實(shí)現(xiàn),在提高了生產(chǎn)效率的同時(shí),也大大提高了數(shù)據(jù)庫間的可移植性。
|
|