之所以要把sql server 2000 jdbc 分頁單獨來說說,又兩個地方還是值得一提,一者是SQL Server 2000要實現數據庫分頁是比較麻煩的事情。二者是jdbc查詢出多個ResultSet 的取法。
先在項目的classpath中添加msbase.jar,mssqlserver.jar,msutil.jar 怎麼來的就不多廢話了。需要說的是我最先用的sql server 2005 jdbc驅動sqljdbc.jar放到項目中,後來的程序是報錯的。回頭想想,報錯有理,SQL Server 2005 已經支持rownum 分頁了。
先說說SQL Server 2000的分頁的實現,目前實現方法大概是那三種。我個人還是喜歡使用存儲過程,原因是使用非常方便,至於使用的存儲過程,這裡還是放出來看看,估計大家用的都大同小異。
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Pr_QueryByPage]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
BEGIN
EXEC dbo.sp_executesql @statement = N'create procedure [dbo].[Pr_QueryByPage]
@sqlstr nvarchar(4000), --查詢sql
@currentpage int, --第頁記錄條數
@pagesize int --每頁顯示記錄
as
set nocount on
declare @P1 int, --P1是游標的ID
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
select ceiling(1.0*@rowcount/@pagesize) as TotalPage,@rowcount as [RowCount]
set @currentpage=(@currentpage-1)*@pagesize+1
exec sp_cursorfetch @P1,16,@currentpage,@pagesize
exec sp_cursorclose @P1
set nocount off '
END
GO
這個存儲過程的實現,使用了三個系統存儲過程sp_cursoropen ,sp_cursorfetch ,sp_cursorclose 從字面上的意思大概是他叫結果集使用游標打開,然後讀取其中的@pageSize條記錄,所以單從查詢上來講,性能是不及使用select top 之類的實現。
使用起來非常容易,exec Pr_QueryByPage 'select * from yourtable',1,10 就可以了麻煩的是他返回的是三張表。第一張表是查詢的表,但是沒有記錄。第二個表一行兩列,第一個列是總頁數,第二個列是總記錄條數。第三張表才是需要的數據。這就造成了取的時候有點小麻煩,因為之前只知道,在.Net中可以直接fill(DataSet),然後DataSet裡面可取DataTable。但是在jdbc裡面我映像中ResultSet 只能容一張表。後來找了一些資料,原來PreparedStatement,CallableStatement,Statement都支持查詢返回多個ResultSet ,好了,非常好。 下面是我使用CallableStatemnt取到的結果集。
CallableStatement cs = conn.prepareCall("exec Pr_QueryByPage 'select * from ckdmzd',1,10");
ResultSet rs = null;
/**
* execute returns :
* true : returns ResultSet(s)
* false: returns rows affected
*/
boolean hasResultSet = cs.execute();
if(hasResultSet){
/**
* skip the first ResultSet
*/
rs=cs.getResultSet();
/**
* second ResultSet : pageCount & recordCount
*/
if(cs.getMoreResults()){
rs=cs.getResultSet();
while(rs.next()){
String pageCount=rs.getString(1);
String recordCount=rs.getString(2);
}
}
/**
* the thrid one is the paged result
*/
if(cs.getMoreResults()){
rs=cs.getResultSet();
while(rs.next()){
// do somthing with ResultSet
}
}
}
這樣就實現了分頁,網上很多人測試了,這個方法的性能不及別的方法,這裡我要指出的是,別的方法是不能返回總的記錄條數的。而要知道總的記錄條數,通常需要select count(*) from ( your sql) 這兩次查詢叫起來的時間未必會少。
總結
使用上述方法實現sql server 2000 jdbc 分頁,使用方便,性能還說的過去。我不知道SQL Server 2005 的查詢性能是否又提升。