IBatis的分頁研究 sql分頁

2021-06-14 06:06:22 字數 3229 閱讀 7575

在看jpetstore的**時,發現它的分頁處理主要是通過返回paginatedlist物件來完成的。如:在catalogservice類中

public paginatedlist getproductlistbycategory(string categoryid)

分頁是運算元據庫型系統常遇到的問題。分頁實現方法很多,但效率的差異就很大了。ibatis是通過什麼方式來實現這個分頁的了。檢視它的實現部分:

返回的paginatedlist實際上是個介面,實現這個介面的是paginateddatalist類的物件,檢視paginateddatalist類發現,每次翻頁的時候最後都會呼叫下面這段函式

private list getlist(int idx, int localpagesize) throws sqlexception

由於

public inte***ce sqlmapclient extends sqlmapexecutor, sqlmaptransactionmanager

所以實際的呼叫次序如下:

sqlmapclientimpl.queryforpaginatedlist->sqlmapsessionimpl.queryforpaginatedlist 

->sqlmapexecutordelegate.queryforpaginatedlist->generalstatement.executequeryforlist

->generalstatment.executequerywithcallback->generalstatment.executequerywithcallback

->sqlexecutor.executequery->sqlexecutor.handlemultipleresults()->sqlexecutor.executequery-> handleresults

分頁處理的函式如下

private void handleresults(requestscope request, resultset rs, int skipresults, int maxresults, rowhandlercallback callback) throws sqlexception  

} else

} }

// get results

int resultsfetched = 0;

while ((maxresults == sqlexecutor.no_maximum_results || resultsfetched < maxresults) && rs.next())

} } finally

}

由此可見,ibatis的分頁主要依賴於jdbcdriver的如何實現以及是否支援rs.absolute(skipresults)。它並不是乙個好的分頁方式。它先要取出所有的符合條件的記錄存入resultset物件,然後用absolute方法進行定位,來實現分頁。當記錄數較大(比如十萬條)時,整體的查詢速度將會變得很慢。

所以分頁還是要考慮採用直接操作sql語句來完成。當然小批量的可以採用ibatis的分頁模式。一般分頁的sql語句與資料庫的具體實現有關

mysql: 

select * from a limit startrow,endrow

oracle:

select b.* from (select a.*,rownum as linenum from (select * from a) a where rownum <= endrow) b where linenum >= startrow

public string createoraclepagingsql(string sql, int pageindex, int pagesize)

綜上,小批量(<2w)可以採用ibatis自帶的分頁類,大批量的還是直接操縱sql,當然也可以將這些sql自己進行封裝,或在包中封裝都可以。包封裝的示例**如下:

乙個封裝了分頁功能的oracle package

create or replace package body fmw_fy_helper is

procedure get_data(pi_sql in varchar,pi_whichpage in integer,pi_rownum in integer,

po_cur_data out cur_data,po_allrownum out integer,pio_succeed in out integer)

as v_cur_data cur_data;

v_cur_temp cur_temp;

v_temp integer;

v_sql varchar(5000);

v_temp1 integer;

v_temp2 integer;

begin

pio_succeed := 1;

v_sql := 'select count(''a'') from ( ' || pi_sql || ')';

execute immediate v_sql into v_temp;

po_allrownum:=ceil(v_temp/pi_rownum);

v_sql := '';

v_temp :=pi_whichpage*pi_rownum + 1;

v_temp1:=(pi_whichpage-1)*pi_rownum + 1;

v_temp2:=pi_whichpage*pi_rownum;

v_sql:= 'select * from (select rownum as rn,t.* from (' || pi_sql ||') t where rownum<' || to_char(v_temp) || ') where rn between ' || to_char(v_temp1) || ' and ' || to_char(v_temp2);

open v_cur_data for v_sql;

if v_cur_data %notfound

then

pio_succeed:=-1;

return;

end if;

po_cur_data := v_cur_data;

end;

IBatis的分頁研究 sql分頁

在看jpetstore的 時,發現它的分頁處理主要是通過返回paginatedlist物件來完成的。如 在catalogservice類中public paginatedlist getproductlistbycategory string categoryid 分頁是運算元據庫型系統常遇到的問題...

SQL儲存過程分頁演算法研究

1.俄羅斯儲存過程 的改良版 create procedure pagination1 pagesize int,頁面大小,如每頁儲存20條記錄 pageindex int 當前頁碼 as set nocount on begin declare indextable table id int id...

ibatis 分頁的簡單實現

cheungmine 2013 8 26 使用ssi struts2,spring3,ibatis2.3 框架開發web服務的時候有乙個需求就是對查詢得到的結果分頁顯示.ibatis2的查詢函式主要有 queryforlist 和 queryforpaginatedlist queryforpagi...