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

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

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

    如鵬網(wǎng) 大學(xué)生計(jì)算機(jī)學(xué)習(xí)社區(qū)

    CowNew開源團(tuán)隊(duì)

    http://www.cownew.com 郵件請(qǐng)聯(lián)系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評(píng)論 :: 0 Trackbacks

    ?分頁在任何系統(tǒng)中都是非常頭疼的事情,有的數(shù)據(jù)庫在語法上支持分頁,而有的數(shù)據(jù)庫則需要使用可滾動(dòng)游標(biāo)來實(shí)現(xiàn),并且在不支持可滾動(dòng)游標(biāo)的系統(tǒng)上只能使用單向游標(biāo)逐步接近要取得的數(shù)據(jù)。
    ?Hibernate提供了一個(gè)支持跨系統(tǒng)的分頁機(jī)制,這樣無論底層是什么樣的數(shù)據(jù)庫都能用統(tǒng)一的接口進(jìn)行分頁操作。比如下面的代碼就是從第500條開始取出100條記錄:
    Query q = session.createQuery("from FooBar as f");
    q.setFirstResult(500);
    q.setMaxResults(100);
    List l = q.list();
    那么Hibernate底層如何實(shí)現(xiàn)分頁的呢?Hibernate根據(jù)Query拼裝SQL語句的地方是在org.hibernate.loader.Loader類的prepareQueryStatement方法中,對(duì)分頁支持的代碼在這一段中可以發(fā)現(xiàn):
    if (useLimit)
    {
    sql = dialect.getLimitString(
    ?????sql.trim(), //use of trim() here is ugly?
    ?????useOffset ? getFirstRow(selection) : 0,
    ?????getMaxOrLimit(selection, dialect)
    ????);
    ?}
    ?此處調(diào)用Dialect的getLimitString方法來得到不同平臺(tái)的分頁語句。
    在MySQLDialect中是如下實(shí)現(xiàn)getLimitString方法的:
    public String getLimitString(String sql, boolean hasOffset)
    {
    return new StringBuffer( sql.length()+20 )
    .append(sql)
    .append( hasOffset ? " limit ?, ?" : " limit ?")
    .toString();
    }
    ?這是MySQL的專用分頁語句,再來看Oracle9Dialect:
    ?public String getLimitString(String sql, boolean hasOffset) {
    ??
    ??sql = sql.trim();
    ??boolean isForUpdate = false;
    ??if ( sql.toLowerCase().endsWith(" for update") ) {
    ???sql = sql.substring( 0, sql.length()-11 );
    ???isForUpdate = true;
    ??}
    ??
    ??StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
    ??if (hasOffset) {
    ???pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
    ??}
    ??else {
    ???pagingSelect.append("select * from ( ");
    ??}
    ??pagingSelect.append(sql);
    ??if (hasOffset) {
    ???pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
    ??}
    ??else {
    ???pagingSelect.append(" ) where rownum <= ?");
    ??}

    ??if ( isForUpdate ) {
    ???pagingSelect.append( " for update" );
    ??}
    ??
    ??return pagingSelect.toString();
    ?}?
    Oracle采用嵌套3層的查詢語句結(jié)合rownum來實(shí)現(xiàn)分頁,這在Oracle上是最好的方式,因?yàn)槿绻皇且粚踊蛘邇蓪拥牟樵冋Z句的rownum不能支持order by。
    此外Interbase,PostgreSQL,HSQL等也在語法級(jí)別上支持分頁,具體實(shí)現(xiàn)可以查看相應(yīng)的Dialect實(shí)現(xiàn)。如果數(shù)據(jù)庫不支持分頁的SQL語句,那么如果數(shù)據(jù)庫支持可滾動(dòng)游標(biāo),那么Hibernate就會(huì)采使用ResultSet的absolute方法直接移到查詢起點(diǎn);否則使用循環(huán)語句,通過rs.next一步步移動(dòng)到要查詢的數(shù)據(jù)處:
    final int firstRow = getFirstRow( selection );
    if ( firstRow != 0 )
    {
    if ( getFactory().getSettings().isScrollableResultSetsEnabled() )
    {
    // 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();
    }
    }

    可見使用Hibernate,在進(jìn)行查詢分頁的操作上,是具有非常大的靈活性,Hibernate會(huì)首先嘗試用特定數(shù)據(jù)庫的分頁sql,如果沒用,再嘗試Scrollable,如果不支持Scrollable再采用rset.next()移動(dòng)的辦法。這樣既兼顧了查詢分頁的性能,同時(shí)又保證了代碼在不同的數(shù)據(jù)庫之間的可移植性。

    posted on 2007-03-06 09:22 CowNew開源團(tuán)隊(duì) 閱讀(674) 評(píng)論(0)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲国产成人精品电影| 亚洲日韩国产精品第一页一区| 久久这里只精品99re免费| 日韩精品亚洲aⅴ在线影院| 一级午夜a毛片免费视频| 久久伊人亚洲AV无码网站| 亚洲一卡2卡4卡5卡6卡在线99| 久草免费在线观看视频| 亚洲一级黄色大片| 日本不卡在线观看免费v| 国产成人亚洲毛片| 亚洲一区二区三区免费在线观看| 91大神亚洲影视在线| 成人AV免费网址在线观看| 亚洲AV无码久久精品色欲| 最好看最新的中文字幕免费| 亚洲精品国产福利片| 岛国大片免费在线观看| 美女黄频免费网站| 久久精品国产精品亚洲色婷婷| 最近免费中文在线视频| 情人伊人久久综合亚洲| 精品无码人妻一区二区免费蜜桃| 精品亚洲成在人线AV无码| 四虎影视精品永久免费网站| a级毛片毛片免费观看永久| 免费国产综合视频在线看| 中国性猛交xxxxx免费看| 亚洲国语在线视频手机在线| 国产成人免费一区二区三区| 日韩精品无码免费专区午夜| 中文字幕亚洲一区二区三区| 免费A级毛片无码视频| 亚洲女女女同性video| 亚洲色精品vr一区二区三区| 我的小后妈韩剧在线看免费高清版 | 国产精品视_精品国产免费| 久青草国产免费观看| 亚洲综合在线成人一区| 免费一级毛片正在播放| 1000部羞羞禁止免费观看视频 |