<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基礎上完成的
    在看JPetStore的代碼時,發現它的分頁處理主要是通過返回PaginatedList對象來完成的。如:在CatalogService類中
    public?PaginatedList?getProductListByCategory(String?categoryId)?{?
    ????
    return?productDao.getProductListByCategory(categoryId);?
    ??}
    ?

    分頁是操作數據庫型系統常遇到的問題。分頁實現方法很多,但效率的差異就很大了。iBatis是通過什么方式來實現這個分頁的了。查看它的實現部分:
    ?
    返回的PaginatedList實際上是個接口,實現這個接口的是PaginatedDataList類的對象,查看PaginatedDataList類發現,每次翻頁的時候最后都會調用下面這段函數
    private?List?getList(int?idx,?int?localPageSize)?throws?SQLException?{?
    ????
    return?sqlMapExecutor.queryForList(statementName,?parameterObject,?(idx)?*?pageSize,?localPageSize);?
    ??}
    ?
    由于
    public?interface?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?{?
    ????
    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的如何實現以及是否支持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?

    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,當然也可以將這些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;
    posted on 2007-01-18 16:27 滌生 閱讀(8459) 評論(6)  編輯  收藏


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

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(5)

    隨筆檔案

    UML

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 男女交性永久免费视频播放| 无码av免费网站| 亚洲av成人一区二区三区在线观看| 亚洲一卡2卡三卡4卡无卡下载| 成人毛片手机版免费看| 亚洲日韩看片无码电影| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 中文字幕精品三区无码亚洲| 一个人免费观看www视频在线| 亚洲日本va在线观看| 成人免费视频软件网站| 亚洲6080yy久久无码产自国产| 亚洲成av人片天堂网老年人| 久久性生大片免费观看性| 亚洲日韩乱码中文无码蜜桃臀网站| 免费观看成人久久网免费观看| 亚洲午夜久久久精品影院| 久久国内免费视频| 美国毛片亚洲社区在线观看| 亚洲欧洲中文日韩av乱码| 免费视频一区二区| 亚洲伊人久久大香线蕉| 国产精品二区三区免费播放心 | 国产精品亚洲专区无码WEB| 午夜亚洲av永久无码精品| 三年片免费高清版| 亚洲狠狠狠一区二区三区| 日本大片在线看黄a∨免费| h视频免费高清在线观看| 亚洲影院在线观看| 日韩精品免费一区二区三区| 好湿好大好紧好爽免费视频| 亚洲视频一区在线播放| 国产免费观看视频| 色欲国产麻豆一精品一AV一免费 | 久久高潮一级毛片免费| 亚洲理论片在线中文字幕| 又爽又黄无遮挡高清免费视频| 久久这里只精品热免费99| 亚洲熟妇丰满xxxxx| 国产亚洲成av片在线观看|