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

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

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

    隨筆-10  評論-10  文章-0  trackbacks-0
        請問,如何使用Hibernte進行分頁????
    posted on 2007-04-23 21:34 細(xì)雨游風(fēng) 閱讀(253) 評論(2)  編輯  收藏

    評論:
    # re: 有沒哪位大哥大姐幫幫我? 2007-04-26 18:06 | 123
    Hibernate提供了一個支持跨系統(tǒng)的分頁機制,這樣無論底層是什么樣的數(shù)據(jù)庫都能用統(tǒng)一的接口進行分頁操作。比如下面的代碼就是從第500條開始取出100條記錄:
    Query q = session.createQuery("from FooBar as f");
    q.setFirstResult(500);
    q.setMaxResults(100);
    List l = q.list();
    那么Hibernate底層如何實現(xiàn)分頁的呢?Hibernate根據(jù)Query拼裝SQL語句的地方是在org.hibernate.loader.Loader類的divpareQueryStatement方法中,對分頁支持的代碼在這一段中可以發(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方法來得到不同平臺的分頁語句。
    在MySQLDialect中是如下實現(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來實現(xiàn)分頁,這在Oracle上是最好的方式,因為如果只是一層或者兩層的查詢語句的rownum不能支持order by。
    此外Interbase,PostgreSQL,HSQL等也在語法級別上支持分頁,具體實現(xiàn)可以查看相應(yīng)的Dialect實現(xiàn)。如果數(shù)據(jù)庫不支持分頁的SQL語句,那么如果數(shù)據(jù)庫支持可滾動游標(biāo),那么Hibernate就會采使用ResultSet的absolute方法直接移到查詢起點;否則使用循環(huán)語句,通過rs.next一步步移動到要查詢的數(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,在進行查詢分頁的操作上,是具有非常大的靈活性,Hibernate會首先嘗試用特定數(shù)據(jù)庫的分頁sql,如果沒用,再嘗試Scrollable,如果不支持Scrollable再采用rset.next()移動的辦法。這樣既兼顧了查詢分頁的性能,同時又保證了代碼在不同的數(shù)據(jù)庫之間的可移植性。
      回復(fù)  更多評論
      
    # re: 有沒哪位大哥大姐幫幫我? 2007-04-26 20:16 | 細(xì)雨游風(fēng)
    嗯 很詳細(xì) 謝謝你~~!  回復(fù)  更多評論
      

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av区一区二区三| 中文字幕第13亚洲另类| av无码免费一区二区三区| 国产精品亚洲综合久久| 亚洲欧洲日产v特级毛片| 久久精品国产亚洲av日韩| 18禁无遮挡无码网站免费| 人体大胆做受免费视频| 亚洲精品伊人久久久久| 亚洲免费视频观看| 国产亚洲一区二区三区在线不卡| 亚洲色偷偷综合亚洲AV伊人| 三上悠亚亚洲一区高清| 国产亚洲精久久久久久无码| 国产男女猛烈无遮挡免费网站| 57pao国产成永久免费视频| 99re免费在线视频| 波多野结衣在线免费观看| 日韩精品无码区免费专区| 日韩成人免费aa在线看| 性短视频在线观看免费不卡流畅| 你是我的城池营垒免费观看完整版| 亚洲另类无码专区丝袜| 最新亚洲人成无码网站| 免费人妻精品一区二区三区| 亚洲综合一区二区三区四区五区| 亚洲国产欧美日韩精品一区二区三区| 国产午夜亚洲精品不卡电影| 国产黄色片免费看| 最近2018中文字幕免费视频| 国产乱码免费卡1卡二卡3卡| 国产成人免费一区二区三区| 亚洲永久精品ww47| 亚洲精品自拍视频| 亚洲AV日韩AV一区二区三曲| 国产精品极品美女自在线观看免费 | 亚洲福利在线播放| 永久免费av无码网站大全| 亚洲精品WWW久久久久久| 久久久久亚洲精品无码系列| 亚洲AV无码专区亚洲AV伊甸园 |