JDBC2.0實現數據分頁
分頁操作在我們生成數據表格中是一個必不可少的步驟。不同于.net程序的封裝,在java程序中,我們必須要通過代碼實現或者通過某些提供這個功能的類庫。這次進行PDM Report的實現中對直接使用JDBC進行分頁進行了一些學習,把這些東西寫下來,希望對大家會有一些幫助。
一、實現方法
在JDBC2.0中對於Oracle和Sql Server都有三種方式實現分頁操作。分別是:
1、使用針對特定數據庫的SQL語句。
例如在Oracle中的
select ida2a2 from (select rownum r ,ida2a2 from phase) ss where ss.r > 54084 and ss.r <= 54134
在Sql Server中的
select top 50 * from (select top 54134 ida2a2 from phase order by ida2a2) as a order by ida2a2 desc
2、使用ResultSet中的Next()方法。這個方法適用于所有的DB。
for(int i=0;i<54084;i++)
{
rs.next();
}
for(int i=0;i<50;i++)
{
rs.next();
}
3、使用由JDBC2.0開始提供的absolute()方法,這個方法只有在
rs.absolute(54084);
for(int i=0;i<50;i++)
{
rs.next();
}
二、數據比較
使用這三種方法我分別對Sql server和Oracle的數據庫進行了一下簡單測試。對應于兩台DB上數據行數相同的兩張表(phase),使用不同的分頁方法,分別取前50筆數據和最後五十筆數據,操作結束后計算所用時間。該表共有54134行數據,兩台DB運行于同一台pc。結果如下:
Sql for Oracle
Next for Oracle
Absolute for Oracle
Sql for Sql Server
Next for Sql Server
Absolute for Sql Server
First 50 row
0
0
32
78
78
703
Last 50 row
32
1515
1985
203
109
13875
First 50 row
0
0
31
78
94
468
Last 50 row
31
1703
2078
234
109
16719
First 50 row
0
0
31
78
78
453
Last 50 row
32
1578
2063
219
110
16813
從上面得粗率數據可以看出來使用特定的Sql語句在Oracle數據庫中進行分頁操作時最快的而且基本上不受數據行數大小的影響。之所以在表中的數據前50行顯示時間為零,估計主要是受了cache的影響。其他兩種方式的時間差距明顯。
對於Sql Server情況有些不同,使用Next的方式竟然是最快的,讓人難以理解。採用特定的Sql語句排序會受到行數的影響當時速度還可以忍受。
對於兩种DB來説,absolute方法的代價都是難以接受的,大家以後還少用為妙。
另外,Sql Server好像並不支持把top 後面的參數作爲prepare statement的參數,這個地方也請大家注意一下(如果哪位發現其實並不是如此,請告訴我一聲)。
PS:關於Hibernate
在Hibernate中優先使用的是absolute方法。代碼如下
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();
}
對於可以直接使用Sql語句進行分頁操作的DB來説沒有問題,但是Sql Server在Hibernate中並不支持偏移操作,也就是說會進行absolute方法,這樣一來他的分頁效率就比較讓人擔心了。如果大家有人使用Sql Server + Hibernate,請注意這一點。