久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

oracle 數(shù)據(jù)庫,,分頁問題。簡單經(jīng)典的,。

 usejava 2005-10-09

 前言
     在使用數(shù)據(jù)庫的過程中,,不可避免的需要使用到分頁的功能,可是JDBC的規(guī)范對此卻沒有很好的解決,。對于這個需求很多朋友都有自己的解決方案,,比如使用Vector等集合類先保存取出的數(shù)據(jù)再分頁,。但這種方法的可用性很差,與JDBC本身的接口完全不同,,對不同類型的字段的支持也不好,。這里提供了一種與JDBC兼容性非常好的方案。

 JDBC和分頁
  Sun的JDBC規(guī)范的制定,,有時很讓人哭笑不得,,在JDBC1.0中,對于一個結(jié)果集(ResultSet)你甚至只能執(zhí)行next()操作,,而無法讓其向后滾動,,這就直接導(dǎo)致在只執(zhí)行一次SQL查詢的情況下無法獲得結(jié)果集的大小。所以,,如果你使用的是JDBC1.0的驅(qū)動,,那么是幾乎無法實現(xiàn)分頁的。
  好在Sun的JDBC2規(guī)范中很好的彌補了這一個不足,,增加了結(jié)果集的前后滾動操作,,雖然仍然不能直接支持分頁,但我們已經(jīng)可以在這個基礎(chǔ)上寫出自己的可支持分頁的ResultSet了,。

 和具體數(shù)據(jù)庫相關(guān)的實現(xiàn)方法
  有一些數(shù)據(jù)庫,,如Mysql, Oracle等有自己的分頁方法,比如Mysql可以使用limit子句,,Oracle可以使用ROWNUM來限制結(jié)果集的大小和起始位置,。這里以Mysql為例,其典型代碼如下:
    // 計算總的記錄條數(shù)
    String SQL = "SELECT Count(*) AS total " + this.QueryPart;
    rs = db.executeQuery(SQL);
    if (rs.next())
    Total = rs.getInt(1);
    // 設(shè)置當(dāng)前頁數(shù)和總頁數(shù)
    TPages = (int)Math.ceil((double)this.Total/this.MaxLine);
    CPages = (int)Math.floor((double)Offset/this.MaxLine+1);
    // 根據(jù)條件判斷,,取出所需記錄
    if (Total > 0) {
      SQL = Query + " LIMIT " + Offset + " , " + MaxLine;
      rs = db.executeQuery(SQL);
    }
    return rs;
  }
  毫無疑問,,這段代碼在數(shù)據(jù)庫是Mysql時將會是漂亮的,但是作為一個通用的類(事實上我后面要提供的就是一個通用類庫中的一部分),,需要適應(yīng)不同的數(shù)據(jù)庫,,而基于這個類(庫)的應(yīng)用,也可能使用不同的數(shù)據(jù)庫,,所以,,我們將不使用這種方法。

 另一種繁瑣的實現(xiàn)方法
  我看過一些人的做法(事實上包括我在內(nèi),,一開始也是使用這種方法的),,即不使用任何封裝,在需要分頁的地方,,直接操作ResultSet滾到相應(yīng)的位置,,再讀取相應(yīng)數(shù)量的記錄
。其典型代碼如下:
<%
sqlStmt = sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
java.sql.ResultSet.CONCUR_READ_ONLY);
strSQL = "select name,age from test";
//執(zhí)行SQL語句并獲取結(jié)果集
sqlRst = sqlStmt.executeQuery(strSQL);
//獲取記錄總數(shù)
sqlRst.last();
intRowCount = sqlRst.getRow();
//記算總頁數(shù)
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//調(diào)整待顯示的頁碼
if(intPage>intPageCount) intPage = intPageCount;
%>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
   <th>姓名</th>
   <th>年齡</th>
</tr>
<%
if(intPageCount>0){
   //將記錄指針定位到待顯示頁的第一條記錄上
   sqlRst.absolute((intPage-1) * intPageSize + 1);
   //顯示數(shù)據(jù)
   i = 0;
   while(i<intPageSize && !sqlRst.isAfterLast()){
      %>
<tr>
   <td><%=sqlRst.getString(1)%></td>
   <td><%=sqlRst.getString(2)%></td>
</tr>
      <%
      sqlRst.next();
      i++;
   }
}
%>
</table>
  很顯然,,這種方法沒有考慮到代碼重用的問題,,不僅代碼數(shù)量巨大,,而且在代碼需要修改的情況下,將會無所適從,。

 使用Vector進(jìn)行分頁
  還見過另一些實現(xiàn)分頁的類,,是先將所有記錄都select出來,然后將ResultSet中的數(shù)據(jù)都get出來,,存入Vector等集合類中,,再根據(jù)所需分頁的大小,頁數(shù),,定位到相應(yīng)的位置,,讀取數(shù)據(jù),?;蛘呦仁褂们懊嫣岬降膬煞N分頁方法,,取得所需的頁面之后,再存入Vector中,。扔開代碼的效率不說,,單是從程序結(jié)構(gòu)和使用的方便性上講,,就是很糟糕的,。比如,這種做法支持的字段類型有限,,int, double, String類型還比較好處理,,如果碰到Blob, Text等類型,實現(xiàn)起來就很麻煩了,。這是一種更不可取的方案,。 前言
     在使用數(shù)據(jù)庫的過程中,不可避免的需要使用到分頁的功能,,可是JDBC的規(guī)范對此卻沒有很好的解決,。對于這個需求很多朋友都有自己的解決方案,比如使用Vector等集合類先保存取出的數(shù)據(jù)再分頁,。但這種方法的可用性很差,,與JDBC本身的接口完全不同,對不同類型的字段的支持也不好,。這里提供了一種與JDBC兼容性非常好的方案,。

 JDBC和分頁
  Sun的JDBC規(guī)范的制定,有時很讓人哭笑不得,,在JDBC1.0中,,對于一個結(jié)果集(ResultSet)你甚至只能執(zhí)行next()操作,而無法讓其向后滾動,,這就直接導(dǎo)致在只執(zhí)行一次SQL查詢的情況下無法獲得結(jié)果集的大小,。所以,,如果你使用的是JDBC1.0的驅(qū)動,那么是幾乎無法實現(xiàn)分頁的,。
  好在Sun的JDBC2規(guī)范中很好的彌補了這一個不足,,增加了結(jié)果集的前后滾動操作,雖然仍然不能直接支持分頁,,但我們已經(jīng)可以在這個基礎(chǔ)上寫出自己的可支持分頁的ResultSet了,。

 和具體數(shù)據(jù)庫相關(guān)的實現(xiàn)方法
  有一些數(shù)據(jù)庫,如Mysql, Oracle等有自己的分頁方法,,比如Mysql可以使用limit子句,,Oracle可以使用ROWNUM來限制結(jié)果集的大小和起始位置。這里以Mysql為例,,其典型代碼如下:
    // 計算總的記錄條數(shù)
    String SQL = "SELECT Count(*) AS total " + this.QueryPart;
    rs = db.executeQuery(SQL);
    if (rs.next())
    Total = rs.getInt(1);
    // 設(shè)置當(dāng)前頁數(shù)和總頁數(shù)
    TPages = (int)Math.ceil((double)this.Total/this.MaxLine);
    CPages = (int)Math.floor((double)Offset/this.MaxLine+1);
    // 根據(jù)條件判斷,,取出所需記錄
    if (Total > 0) {
      SQL = Query + " LIMIT " + Offset + " , " + MaxLine;
      rs = db.executeQuery(SQL);
    }
    return rs;
  }
  毫無疑問,這段代碼在數(shù)據(jù)庫是Mysql時將會是漂亮的,,但是作為一個通用的類(事實上我后面要提供的就是一個通用類庫中的一部分),,需要適應(yīng)不同的數(shù)據(jù)庫,而基于這個類(庫)的應(yīng)用,,也可能使用不同的數(shù)據(jù)庫,,所以,我們將不使用這種方法,。

 另一種繁瑣的實現(xiàn)方法
  我看過一些人的做法(事實上包括我在內(nèi),,一開始也是使用這種方法的),即不使用任何封裝,,在需要分頁的地方,,直接操作ResultSet滾到相應(yīng)的位置,再讀取相應(yīng)數(shù)量的記錄
,。其典型代碼如下:
<%
sqlStmt = sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
java.sql.ResultSet.CONCUR_READ_ONLY);
strSQL = "select name,age from test";
//執(zhí)行SQL語句并獲取結(jié)果集
sqlRst = sqlStmt.executeQuery(strSQL);
//獲取記錄總數(shù)
sqlRst.last();
intRowCount = sqlRst.getRow();
//記算總頁數(shù)
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//調(diào)整待顯示的頁碼
if(intPage>intPageCount) intPage = intPageCount;
%>



  
  

<%
if(intPageCount>0){
   //將記錄指針定位到待顯示頁的第一條記錄上
   sqlRst.absolute((intPage-1) * intPageSize + 1);
   //顯示數(shù)據(jù)
   i = 0;
   while(i      %>

  
  

      <%
      sqlRst.next();
      i++;
   }
}
%>
姓名年齡
<%=sqlRst.getString(1)%><%=sqlRst.getString(2)%>

  很顯然,,這種方法沒有考慮到代碼重用的問題,不僅代碼數(shù)量巨大,,而且在代碼需要修改的情況下,,將會無所適從。

 使用Vector進(jìn)行分頁
  還見過另一些實現(xiàn)分頁的類,,是先將所有記錄都select出來,,然后將ResultSet中的數(shù)據(jù)都get出來,存入Vector等集合類中,,再根據(jù)所需分頁的大小,,頁數(shù),定位到相應(yīng)的位置,讀取數(shù)據(jù),?;蛘呦仁褂们懊嫣岬降膬煞N分頁方法,取得所需的頁面之后,,再存入Vector中,。扔開代碼的效率不說,單是從程序結(jié)構(gòu)和使用的方便性上講,,就是很糟糕的,。比如,這種做法支持的字段類型有限,,int, double, String類型還比較好處理,,如果碰到Blob, Text等類型,實現(xiàn)起來就很麻煩了,。這是一種更不可取的方案,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多