<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 11,  comments - 28,  trackbacks - 0

    本文是在參閱了http://ivanl.javaeye.com/blog/24739基礎(chǔ)上完成的
    在看JPetStore的代碼時(shí),發(fā)現(xiàn)它的分頁處理主要是通過返回PaginatedList對(duì)象來完成的。如:在CatalogService類中
    public?PaginatedList?getProductListByCategory(String?categoryId)?{?
    ????
    return?productDao.getProductListByCategory(categoryId);?
    ??}
    ?

    分頁是操作數(shù)據(jù)庫型系統(tǒng)常遇到的問題。分頁實(shí)現(xiàn)方法很多,但效率的差異就很大了。iBatis是通過什么方式來實(shí)現(xiàn)這個(gè)分頁的了。查看它的實(shí)現(xiàn)部分:
    ?
    返回的PaginatedList實(shí)際上是個(gè)接口,實(shí)現(xiàn)這個(gè)接口的是PaginatedDataList類的對(duì)象,查看PaginatedDataList類發(fā)現(xiàn),每次翻頁的時(shí)候最后都會(huì)調(diào)用下面這段函數(shù)
    private?List?getList(int?idx,?int?localPageSize)?throws?SQLException?{?
    ????
    return?sqlMapExecutor.queryForList(statementName,?parameterObject,?(idx)?*?pageSize,?localPageSize);?
    ??}
    ?
    由于
    public?interface?SqlMapClient?extends?SqlMapExecutor,?SqlMapTransactionManager?{……}?

    所以實(shí)際的調(diào)用次序如下:
    SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList?
    ->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList?
    ->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback?
    ->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()->SqlExecutor.executeQuery->?handleResults?
    分頁處理的函數(shù)如下
    private?void?handleResults(RequestScope?request,?ResultSet?rs,?int?skipResults,?int?maxResults,?RowHandlerCallback?callback)?throws?SQLException?{?
    ????
    try?{?
    ??????request.setResultSet(rs);?
    ??????ResultMap?resultMap?
    =?request.getResultMap();?
    ??????
    if?(resultMap?!=?null)?{?
    ????????
    //?Skip?Results?
    ????????if?(rs.getType()?!=?ResultSet.TYPE_FORWARD_ONLY)?{?
    ??????????
    if?(skipResults?>?0)?{?
    ????????????rs.absolute(skipResults);?
    ??????????}
    ?
    ????????}
    ?else?{?
    ??????????
    for?(int?i?=?0;?i?<?skipResults;?i++)?{?
    ????????????
    if?(!rs.next())?{?
    ??????????????
    return;?
    ????????????}
    ?
    ??????????}
    ?
    ????????}
    ?
    ??
    ????????
    //?Get?Results?
    ????????int?resultsFetched?=?0;?
    ????????
    while?((maxResults?==?SqlExecutor.NO_MAXIMUM_RESULTS?||?resultsFetched?<?maxResults)?&&?rs.next())?{?
    ??????????Object[]?columnValues?
    =?resultMap.resolveSubMap(request,?rs).getResults(request,?rs);?
    ??????????callback.handleResultObject(request,?columnValues,?rs);?
    ??????????resultsFetched
    ++;?
    ????????}
    ?
    ??????}
    ?
    ????}
    ?finally?{?
    ??????request.setResultSet(
    null);?
    ????}
    ?
    ??}
    ?

    由此可見,iBatis的分頁主要依賴于jdbcdriver的如何實(shí)現(xiàn)以及是否支持rs.absolute(skipResults)。它并不是一個(gè)好的分頁方式。它先要取出所有的符合條件的記錄存入ResultSet對(duì)象,然后用absolute方法進(jìn)行定位,來實(shí)現(xiàn)分頁。當(dāng)記錄數(shù)較大(比如十萬條)時(shí),整體的查詢速度將會(huì)變得很慢。
    所以分頁還是要考慮采用直接操作sql語句來完成。當(dāng)然小批量的可以采用iBatis的分頁模式。一般分頁的sql語句與數(shù)據(jù)庫的具體實(shí)現(xiàn)有關(guān)
    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?

    Hibernate的Oracle分頁采用的就是是拼湊RowNum的Sql語句來完成的。參考代碼如下:?
    ?
    ????????public?String?createOraclePagingSql(String?sql,?int?pageIndex,?int?pageSize){?
    ????????????
    int?m?=?pageIndex?*?pageSize;?
    ????????????
    int?n?=?m?+?pageSize;?
    ????????????
    return?"select?*?from?(?select?row_.*,?rownum?rownum_?from?(?"?+?sql?
    ????????????????????
    +?"?)?row_?where?rownum?<=?"?+?n??
    ????????????????????
    +?")?where?rownum_?>?"?+?m;?
    ????????}
    ?
    綜上,小批量(<2w)可以采用ibatis自帶的分頁類,大批量的還是直接操縱sql,當(dāng)然也可以將這些sql自己進(jìn)行封裝,或在包中封裝都可以。包封裝的示例代碼如下:
    一個(gè)封裝了分頁功能的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;
    posted on 2007-01-18 16:27 滌生 閱讀(8460) 評(píng)論(6)  編輯  收藏


    FeedBack:
    # re: IBatis的分頁研究
    2007-01-18 17:29 | BeanSoft
    是呀, 學(xué)習(xí) ORM 工具的時(shí)候, 還是得熟悉 JDBC 和 SQL 的, 要不然系統(tǒng)瓶頸了就沒招了.  回復(fù)  更多評(píng)論
      
    # re: IBatis的分頁研究
    2007-01-18 18:31 | 滌生
    @BeanSoft
    說的甚是,尤其是遇到一些典型的會(huì)出現(xiàn)性能問題的地方,一定要研究一下所使用ORM工具的實(shí)現(xiàn)方法。既要知其然,又要知其所以然
      回復(fù)  更多評(píng)論
      
    # re: IBatis的分頁研究
    2007-01-18 18:33 | 布衣郎
    不錯(cuò),支持一下,使用數(shù)據(jù)庫本身的分頁方法,對(duì)效率有所幫助,如果數(shù)據(jù)量不大,可以采用ibatis默認(rèn)的方法。  回復(fù)  更多評(píng)論
      
    # re: IBatis的分頁研究
    2007-01-18 20:36 | 劍事
    用了快一年了
    也算選對(duì)了  回復(fù)  更多評(píng)論
      
    # re: IBatis的分頁研究
    2007-02-11 11:19 | str
    很多的ORM框架實(shí)際都是用數(shù)據(jù)庫自己帶的分頁方式。。  回復(fù)  更多評(píng)論
      
    # re: IBatis的分頁研究
    2008-07-08 16:56 | 汽車
    性能是個(gè)大問題  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(5)

    隨筆檔案

    UML

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 无码国产精品一区二区免费模式 | 亚洲国产精品第一区二区三区| 亚洲一区在线观看视频| 最近免费字幕中文大全视频| 亚洲成Av人片乱码色午夜| 在线看片免费人成视频福利| 亚洲精品乱码久久久久久| 国色精品va在线观看免费视频 | 国产成人精品日本亚洲18图| 国拍在线精品视频免费观看| 亚洲91精品麻豆国产系列在线| 国产片AV片永久免费观看| 国产精品高清视亚洲一区二区| 四虎影院免费在线播放| 国产精品亚洲五月天高清| 不卡精品国产_亚洲人成在线| 精品国产污污免费网站入口| 亚洲av永久无码制服河南实里 | 日韩av无码免费播放| 亚洲一区二区三区首页| 曰曰鲁夜夜免费播放视频 | 日韩国产精品亚洲а∨天堂免| 国产公开免费人成视频| 国产大片免费天天看| 久久噜噜噜久久亚洲va久| 91成年人免费视频| 国产在亚洲线视频观看| 亚洲人成色7777在线观看| 亚洲电影在线免费观看| 特级毛片免费播放| 亚洲卡一卡2卡三卡4卡无卡三| AV免费网址在线观看| 特级毛片爽www免费版| 亚洲精品高清久久| 日韩免费一级毛片| 国产成人精品免费久久久久| 在线a亚洲老鸭窝天堂av高清| 毛茸茸bbw亚洲人| 日韩av无码成人无码免费| 在线播放国产不卡免费视频| 亚洲精品白色在线发布|