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

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

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

    風人園

    弱水三千,只取一瓢,便能解渴;佛法無邊,奉行一法,便能得益。
    隨筆 - 99, 文章 - 181, 評論 - 56, 引用 - 0
    數據加載中……

    JSP分頁技術實現

    目前比較廣泛使用的分頁方式是將查詢結果緩存在HttpSession或有狀態bean中,翻頁的時候從緩存中取出一頁數據顯示。這種方法有兩個主要的缺點:一是用戶可能看到的是過期數據;二是如果數據量非常大時第一次查詢遍歷結果集會耗費很長時間,并且緩存的數據也會占用大量內存,效率明顯下降。
      其它常見的方法還有每次翻頁都查詢一次數據庫,從ResultSet中只取出一頁數據(使用rs.last();rs.getRow()獲得總計錄條數,使用rs.absolute()定位到本頁起始記錄)。這種方式在某些數據庫(如oracle)的JDBC實現中差不多也是需要遍歷所有記錄,實驗證明在記錄數很大時速度非常慢。
      至于緩存結果集ResultSet的方法則完全是一種錯誤的做法。因為ResultSet在Statement或Connection關閉時也會被關閉,如果要使ResultSet有效勢必長時間占用數據庫連接。

      因此比較好的分頁做法應該是每次翻頁的時候只從數據庫里檢索頁面大小的塊區的數據。這樣雖然每次翻頁都需要查詢數據庫,但查詢出的記錄數很少,網絡傳輸數據量不大,如果使用連接池更可以略過最耗時的建立數據庫連接過程。而在數據庫端有各種成熟的優化技術用于提高查詢速度,比在應用服務器層做緩存有效多了。

      在oracle數據庫中查詢結果的行號使用偽列ROWNUM表示(從1開始)。例如select * from employee where rownum<10 返回前10條記錄。但因為rownum是在查詢之后排序之前賦值的,所以查詢employee按birthday排序的第100到120條記錄應該這么寫:
            select * from (
                select my_table.*, rownum as my_rownum from (
                    select name, birthday from employee order by birthday
                ) my_table where rownum <120
            ) where my_rownum>=100

      mySQL可以使用LIMIT子句:
        select name, birthday from employee order by birthday LIMIT 99,20
      DB2有rownumber()函數用于獲取當前行數。
      SQL Server沒研究過,可以參考這篇文章:http://www.csdn.net/develop/article/18/18627.shtm

      在Web程序中分頁會被頻繁使用,但分頁的實現細節卻是編程過程中比較麻煩的事情。大多分頁顯示的查詢操作都同時需要處理復雜的多重查詢條件,sql語句需要動態拼接組成,再加上分頁需要的記錄定位、總記錄條數查詢以及查詢結果的遍歷、封裝和顯示,程序會變得很復雜并且難以理解。因此需要一些工具類簡化分頁代碼,使程序員專注于業務邏輯部分。下面是我設計的兩個工具類:
      PagedStatement  封裝了數據庫連接、總記錄數查詢、分頁查詢、結果數據封裝和關閉數據庫連接等操作,并使用了PreparedStatement支持動態設置參數。
      RowSetPage  參考PetStore的page by page iterator模式, 設計RowSetPage用于封裝查詢結果(使用OracleCachedRowSet緩存查詢出的一頁數據,關于使用CachedRowSet封裝數據庫查詢結果請參考JSP頁面查詢顯示常用模式)以及當前頁碼、總記錄條數、當前記錄數等信息, 并且可以生成簡單的HTML分頁代碼。
      PagedStatement 查詢的結果封裝成RowsetPage。

      下面是簡單的使用示例
    1.     //DAO查詢數據部分代碼:
    2.     …
    3.     public RowSetPage getEmployee(String gender, int pageNo) throws Exception{
    4.         String sql="select emp_id, emp_code,  user_name, real_name from employee where gender =?";
    5.        //使用Oracle數據庫的分頁查詢實現,每頁顯示5條
    6.         PagedStatement pst =new PagedStatementOracleImpl(sql,  pageNo, 5);
    7.         pst.setString(1, gender);
    8.         return pst.executeQuery();
    9.     }
    10.     //Servlet處理查詢請求部分代碼:
    11.     …
    12.     int pageNo;
    13.     try{
    14.         //可以通過參數pageno獲得用戶選擇的頁碼
    15.         pageNo = Integer.parseInt(request.getParameter("pageno") );
    16.     }catch(Exception ex){
    17.         //默認為第一頁
    18.         pageNo=1;
    19.     }
    20.     String gender = request.getParameter("gender" );
    21.     request.setAttribute("empPage", myBean.getEmployee(gender, pageNo) );
    22.     …
    23.     //JSP顯示部分代碼
    24. <%@ page import = "page.RowSetPage"%>
    25.     …
    26.     <script language="javascript">
    27.         function doQuery(){
    28.             form1.actionType.value="doQuery";
    29.             form1.submit();
    30.     }
    31.     </script>
    32.     …
    33.     <form name=form1 method=get>
    34.       <input type=hidden name=actionType>
    35.       性別:
    36.       <input type=text name=gender size=1 value="<%=request.getParameter("gender")%>">
    37.       <input type=button value=" 查詢 " onclick="doQuery()">
    38. <%
    39.     RowSetPage empPage = (RowSetPage)request.getAttribute("empPage");
    40.     if (empPage == null ) empPage = RowSetPage.EMPTY_PAGE;
    41. %>
    42.     …
    43.     <table  cellspacing="0" width="90%">
    44.         <tr> <td>ID</td> <td>代碼</td> <td>用戶名</td> <td>姓名</td>  </tr>
    45. <%
    46.     javax.sql.RowSet empRS = (javax.sql.RowSet) empPage.getRowSet();
    47.     if (empRS!=nullwhile (empRS.next() ) {
    48. %>
    49.         <tr>  
    50.             <td><%= empRS.getString("EMP_ID")%></td> 
    51.             <td><%= empRS.getString("EMP_CODE")%></td>  
    52.             <td><%= empRS.getString("USER_NAME")%></td> 
    53.             <td><%= empRS.getString("REAL_NAME")%></td>  
    54.         </tr>
    55. <%
    56.     }// end while
    57. %>
    58.         <tr>
    59. <%
    60.     //顯示總頁數和當前頁數(pageno)以及分頁代碼。
    61.     //此處doQuery為頁面上提交查詢動作的javascript函數名, pageno為標識當前頁碼的參數名
    62. %>
    63.             <td colspan=4><%= empPage .getHTML("doQuery""pageno")%></td>
    64.         </tr>
    65.     </table>
    66.     </form>

      效果如圖:


      因為分頁顯示一般都會伴有查詢條件和查詢動作,頁面應已經有校驗查詢條件和提交查詢的javascript方法(如上面的doQuery),所以RowSetPage.getHTML()生成的分頁代碼在用戶選擇新頁碼時直接回調前面的處理提交查詢的javascript方法。注意在顯示查詢結果的時候上次的查詢條件也需要保持,如<input type=text name=gender size=1 value="<%=request.getParameter("gender")%>">。同時由于頁碼的參數名可以指定,因此也支持在同一頁面中有多個分頁區。
      另一種分頁代碼實現是生成每一頁的URL,將查詢參數和頁碼作為QueryString附在URL后面。這種方法的缺陷是在查詢條件比較復雜時難以處理,并且需要指定處理查詢動作的servlet,可能不適合某些定制的查詢操作。
      如果對RowSetPage.getHTML()生成的默認分頁代碼不滿意可以編寫自己的分頁處理代碼,RowSetPage提供了很多getter方法用于獲取相關信息(如當前頁碼、總頁數、 總記錄數和當前記錄數等)。
      在實際應用中可以將分頁查詢和顯示做成jsp taglib, 進一步簡化JSP代碼,屏蔽Java Code。

    附:分頁工具類的源代碼, 有注釋,應該很容易理解。

    1.Page.java
    2.RowSetPage.java(RowSetPage繼承Page)
    3.PagedStatement.java
    4.PagedStatementOracleImpl.java(PagedStatementOracleImpl繼承PagedStatement)



    您可以任意使用這些源代碼,但必須保留author evan_zhao@hotmail.com字樣
    1. ///////////////////////////////////
    2. //
    3. //  Page.java
    4. //  author: evan_zhao@hotmail.com
    5. //
    6. ///////////////////////////////////
    7. package page;
    8. import java.util.List;
    9. import java.util.ArrayList;
    10. import java.util.Collection;
    11. import java.util.Collections;
    12. /**
    13.  * Title: 分頁對象<br>
    14.  * Description:  用于包含數據及分頁信息的對象<br>
    15.  *               Page類實現了用于顯示分頁信息的基本方法,但未指定所含數據的類型,
    16.  *               可根據需要實現以特定方式組織數據的子類,<br>
    17.  *               如RowSetPage以RowSet封裝數據,ListPage以List封裝數據<br>
    18.  * Copyright:    Copyright (c) 2002 <br>
    19.  * @author evan_zhao@hotmail.com <br>
    20.  * @version 1.0
    21.  */
    22. public  class Page implements java.io.Serializable {
    23.     public static final Page EMPTY_PAGE = new Page();
    24.     public static final int  DEFAULT_PAGE_SIZE = 20;
    25.     public static final  int MAX_PAGE_SIZE = 9999;
    26.     private int myPageSize = DEFAULT_PAGE_SIZE;
    27.     private int start;
    28.     private int avaCount,totalSize;
    29.     private Object data;
    30.     private int currentPageno;
    31.     private int totalPageCount;
    32.     /**
    33.      * 默認構造方法,只構造空頁
    34.      */
    35.     protected Page(){
    36.         this.init(0,0,0,DEFAULT_PAGE_SIZE,new Object());
    37.     }
    38.     /**
    39.      * 分頁數據初始方法,由子類調用
    40.      * @param start 本頁數據在數據庫中的起始位置
    41.      * @param avaCount 本頁包含的數據條數
    42.      * @param totalSize 數據庫中總記錄條數
    43.      * @param pageSize 本頁容量
    44.      * @param data 本頁包含的數據
    45.      */
    46.     protected void init(int start, int avaCount, int totalSize, int pageSize, Object data){
    47.         this.avaCount =avaCount;
    48.         this.myPageSize = pageSize;
    49.         this.start = start;
    50.         this.totalSize = totalSize;
    51.         this.data=data;
    52.         //System.out.println("avaCount:"+avaCount);
    53.         //System.out.println("totalSize:"+totalSize);
    54.         if (avaCount>totalSize) {
    55.             //throw new RuntimeException("記錄條數大于總條數?!");
    56.         }
    57.         this.currentPageno = (start -1)/pageSize +1;
    58.         this.totalPageCount = (totalSize + pageSize -1) / pageSize;
    59.         if (totalSize==0 && avaCount==0){
    60.             this.currentPageno = 1;
    61.             this.totalPageCount = 1;
    62.         }
    63.         //System.out.println("Start Index to Page No: " + start + "-" + currentPageno);
    64.     }
    65.     public  Object getData(){
    66.         return this.data;
    67.     }
    68.     /**
    69.      * 取本頁數據容量(本頁能包含的記錄數)
    70.      * @return 本頁能包含的記錄數
    71.      */
    72.     public int getPageSize(){
    73.         return this.myPageSize;
    74.     }
    75.     /**
    76.      * 是否有下一頁
    77.      * @return 是否有下一頁
    78.      */
    79.     public boolean hasNextPage() {
    80.       /*
    81.         if (avaCount==0 && totalSize==0){
    82.             return false;
    83.         }
    84.         return (start + avaCount -1) < totalSize;
    85.        */
    86.       return (this.getCurrentPageNo()<this.getTotalPageCount());
    87.     }
    88.     /**
    89.      * 是否有上一頁
    90.      * @return  是否有上一頁
    91.      */
    92.     public boolean hasPreviousPage() {
    93.       /*
    94.         return start > 1;
    95.        */
    96.       return (this.getCurrentPageNo()>1);
    97.     }
    98.     /**
    99.      * 獲取當前頁第一條數據在數據庫中的位置
    100.      * @return
    101.      */
    102.     public int getStart(){
    103.         return start;
    104.     }
    105.     /**
    106.      * 獲取當前頁最后一條數據在數據庫中的位置
    107.      * @return
    108.      */
    109.     public int getEnd(){
    110.         int end = this.getStart() + this.getSize() -1;
    111.         if (end<0) {
    112.             end = 0;
    113.         }
    114.         return end;
    115.     }
    116.     /**
    117.      * 獲取上一頁第一條數據在數據庫中的位置
    118.      * @return 記錄對應的rownum
    119.      */
    120.     public int getStartOfPreviousPage() {
    121.         return Math.max(start-myPageSize, 1);
    122.     }
    123.     /**
    124.      * 獲取下一頁第一條數據在數據庫中的位置
    125.      * @return 記錄對應的rownum
    126.      */
    127.     public int getStartOfNextPage() {
    128.         return start + avaCount;
    129.     }
    130.     /**
    131.      * 獲取任一頁第一條數據在數據庫中的位置,每頁條數使用默認值
    132.      * @param pageNo 頁號
    133.      * @return 記錄對應的rownum
    134.      */
    135.     public static int getStartOfAnyPage(int pageNo){
    136.         return getStartOfAnyPage(pageNo, DEFAULT_PAGE_SIZE);
    137.     }
    138.     /**
    139.      * 獲取任一頁第一條數據在數據庫中的位置
    140.      * @param pageNo 頁號
    141.      * @param pageSize 每頁包含的記錄數
    142.      * @return 記錄對應的rownum
    143.      */
    144.     public static int getStartOfAnyPage(int pageNo, int pageSize){
    145.         int startIndex = (pageNo-1) * pageSize + 1;
    146.         if ( startIndex < 1) startIndex = 1;
    147.         //System.out.println("Page No to Start Index: " + pageNo + "-" + startIndex);
    148.         return startIndex;
    149.     }
    150.     /**
    151.      * 取本頁包含的記錄數
    152.      * @return 本頁包含的記錄數
    153.      */
    154.     public int getSize() {
    155.         return avaCount;
    156.     }
    157.     /**
    158.      * 取數據庫中包含的總記錄數
    159.      * @return 數據庫中包含的總記錄數
    160.      */
    161.     public int getTotalSize() {
    162.         return this.totalSize;
    163.     }
    164.     /**
    165.      * 取當前頁碼
    166.      * @return 當前頁碼
    167.      */
    168.     public int getCurrentPageNo(){
    169.         return  this.currentPageno;
    170.     }
    171.     /**
    172.      * 取總頁碼
    173.      * @return 總頁碼
    174.      */
    175.     public int getTotalPageCount(){
    176.         return this.totalPageCount;
    177.     }
    178.     /**
    179.      *
    180.      * @param queryJSFunctionName 實現分頁的JS腳本名字,頁碼變動時會自動回調該方法
    181.      * @param pageNoParamName 頁碼參數名稱
    182.      * @return
    183.      */
    184.     public String getHTML(String queryJSFunctionName, String pageNoParamName){
    185.         if (getTotalPageCount()<1){
    186.             return "<input type='hidden' name='"+pageNoParamName+"' value='1' >";
    187.         }
    188.         if (queryJSFunctionName == null || queryJSFunctionName.trim().length()<1) {
    189.             queryJSFunctionName = "gotoPage";
    190.         }
    191.         if (pageNoParamName == null || pageNoParamName.trim().length()<1){
    192.             pageNoParamName = "pageno";
    193.         }
    194.         String gotoPage = "_"+queryJSFunctionName;
    195.         StringBuffer html = new StringBuffer("\n");
    196.         html.append("<script language=\"Javascript1.2\">\n")
    197.              .append("function ").append(gotoPage).append("(pageNo){  \n")
    198.              .append(  "   var curPage=1;  \n")
    199.              .append(  "   try{ curPage = document.all[\"")
    200.              .append(pageNoParamName).append("\"].value;  \n")
    201.              .append(  "        document.all[\"").append(pageNoParamName)
    202.              .append("\"].value = pageNo;  \n")
    203.              .append(  "        ").append(queryJSFunctionName).append("(pageNo); \n")
    204.              .append(  "        return true;  \n")
    205.              .append(  "   }catch(e){ \n")
    206. //             .append(  "      try{ \n")
    207. //             .append(  "           document.forms[0].submit();  \n")
    208. //             .append(  "      }catch(e){   \n")
    209.              .append(  "          alert('尚未定義查詢方法:function ")
    210.              .append(queryJSFunctionName).append("()'); \n")
    211.              .append(  "          document.all[\"").append(pageNoParamName)
    212.              .append("\"].value = curPage;  \n")
    213.              .append(  "          return false;  \n")
    214. //             .append(  "      }  \n")
    215.              .append(  "   }  \n")
    216.              .append(  "}")
    217.              .append(  "</script>  \n")
    218.              .append(  "");
    219.         html.append( "<table  border=0 cellspacing=0 cellpadding=0 align=center width=80%>  \n")
    220.              .append( "  <tr>  \n")
    221.              .append( "    <td align=left><br>  \n");
    222.         html.append(  "       共" ).append( getTotalPageCount() ).append( "頁")
    223.              .append(  "       [") .append(getStart()).append("..").append(getEnd())
    224.              .append("/").append(this.getTotalSize()).append("]  \n")
    225.              .append( "    </td>  \n")
    226.              .append( "    <td align=right>  \n");
    227.         if (hasPreviousPage()){
    228.              html.append( "[<a href='javascript:").append(gotoPage)
    229.              .append("(") .append(getCurrentPageNo()-1) 
    230.              .append( ")'>上一頁</a>]   \n");
    231.         }
    232.         html.append(  "       第")
    233.              .append(   "        <select name='")
    234.              .append(pageNoParamName).append("' onChange='javascript:")
    235.              .append(gotoPage).append("(this.value)'>\n");
    236.         String selected = "selected";
    237.         for(int i=1;i<=getTotalPageCount();i++){
    238.             if( i == getCurrentPageNo() )
    239.                  selected = "selected";
    240.             else selected = "";
    241.             html.append( "      <option value='").append(i).append("' ")
    242.               .append(selected).append(">").append(i).append("</option>  \n");
    243.         }
    244.         if (getCurrentPageNo()>getTotalPageCount()){
    245.             html.append( "      <option value='").append(getCurrentPageNo())
    246.             .append("' selected>").append(getCurrentPageNo())
    247.             .append("</option>  \n");
    248.         }
    249.         html.append( "    </select>頁  \n");
    250.         if (hasNextPage()){
    251.              html.append( "    [<a href='javascript:").append(gotoPage)
    252.                .append("(").append((getCurrentPageNo()+1)) 
    253.                .append( ")'>下一頁</a>]   \n");
    254.         }
    255.         html.append( "</td></tr></table>  \n");
    256.         return html.toString();
    257.     }
    258. }
    259. ///////////////////////////////////
    260. //
    261. //  RowSetPage.java
    262. //  author: evan_zhao@hotmail.com
    263. //
    264. ///////////////////////////////////
    265. package page;
    266. import javax.sql.RowSet;
    267. /**
    268.  * <p>Title: RowSetPage</p>
    269.  * <p>Description: 使用RowSet封裝數據的分頁對象</p>
    270.  * <p>Copyright: Copyright (c) 2003</p>
    271.  * @author evan_zhao@hotmail.com
    272.  * @version 1.0
    273.  */
    274. public class RowSetPage extends Page {
    275.     private javax.sql.RowSet rs;
    276.     /**
    277.      *空頁
    278.      */
    279.     public static final RowSetPage EMPTY_PAGE = new RowSetPage();
    280.     /**
    281.      *默認構造方法,創建空頁
    282.      */
    283.     public RowSetPage(){
    284.       this(null, 0,0);
    285.     }
    286.     /**
    287.      *構造分頁對象
    288.      *@param crs 包含一頁數據的OracleCachedRowSet
    289.      *@param start 該頁數據在數據庫中的起始位置
    290.      *@param totalSize 數據庫中包含的記錄總數
    291.      */
    292.     public RowSetPage(RowSet crs, int start, int totalSize) {
    293.         this(crs,start,totalSize,Page.DEFAULT_PAGE_SIZE);
    294.     }
    295.     /**
    296.      *構造分頁對象
    297.      *@param crs 包含一頁數據的OracleCachedRowSet
    298.      *@param start 該頁數據在數據庫中的起始位置
    299.      *@param totalSize 數據庫中包含的記錄總數
    300.      *@pageSize 本頁能容納的記錄數
    301.      */
    302.     public RowSetPage(RowSet crs, int start, int totalSize, int pageSize) {
    303.         try{
    304.             int avaCount=0;
    305.             if (crs!=null) {
    306.                 crs.beforeFirst();
    307.                 if (crs.next()){
    308.                     crs.last();
    309.                     avaCount = crs.getRow();
    310.                 }
    311.                 crs.beforeFirst();
    312.             }
    313.             rs = crs;
    314.             super.init(start,avaCount,totalSize,pageSize,rs);
    315.         }catch(java.sql.SQLException sqle){
    316.             throw new RuntimeException(sqle.toString());
    317.         }
    318.     }
    319.     /**
    320.      *取分頁對象中的記錄數據
    321.      */
    322.     public javax.sql.RowSet getRowSet(){
    323.         return rs;
    324.     }
    325. }
    326. ///////////////////////////////////
    327. //
    328. //  PagedStatement.java
    329. //  author: evan_zhao@hotmail.com
    330. //
    331. ///////////////////////////////////
    332. package page;
    333. import foo.DBUtil;
    334. import java.math.BigDecimal;
    335. import java.util.List;
    336. import java.util.Iterator;
    337. import java.util.Collections;
    338. import java.sql.Connection;
    339. import java.sql.SQLException;
    340. import java.sql.ResultSet;
    341. import java.sql.Statement;
    342. import java.sql.PreparedStatement;
    343. import java.sql.Timestamp;
    344. import javax.sql.RowSet;
    345. /**
    346.  * <p>Title: 分頁查詢</p>
    347.  * <p>Description: 根據查詢語句和頁碼查詢出當頁數據</p>
    348.  * <p>Copyright: Copyright (c) 2002</p>
    349.  * @author evan_zhao@hotmail.com
    350.  * @version 1.0
    351.  */
    352. public abstract class PagedStatement {
    353.     public final static int MAX_PAGE_SIZE = Page.MAX_PAGE_SIZE;
    354.     protected String countSQL, querySQL;
    355.     protected int pageNo,pageSize,startIndex,totalCount;
    356.     protected javax.sql.RowSet rowSet;
    357.     protected RowSetPage rowSetPage;
    358.     private List boundParams;
    359.     /**
    360.      * 構造一查詢出所有數據的PageStatement
    361.      * @param sql  query sql
    362.      */
    363.     public PagedStatement(String sql){
    364.         this(sql,1,MAX_PAGE_SIZE);
    365.     }
    366.     /**
    367.      * 構造一查詢出當頁數據的PageStatement
    368.      * @param sql  query sql
    369.      * @param pageNo  頁碼
    370.      */
    371.     public PagedStatement(String sql, int pageNo){
    372.         this(sql, pageNo, Page.DEFAULT_PAGE_SIZE);
    373.     }
    374.     /**
    375.      * 構造一查詢出當頁數據的PageStatement,并指定每頁顯示記錄條數
    376.      * @param sql query sql
    377.      * @param pageNo 頁碼
    378.      * @param pageSize 每頁容量
    379.      */
    380.     public PagedStatement(String sql, int pageNo, int pageSize){
    381.         this.pageNo = pageNo;
    382.         this.pageSize = pageSize;
    383.         this.startIndex = Page.getStartOfAnyPage(pageNo, pageSize);
    384.         this.boundParams = Collections.synchronizedList(new java.util.LinkedList());
    385.         this.countSQL = "select count(*) from ( " + sql +") ";
    386.         this.querySQL = intiQuerySQL(sql, this.startIndex, pageSize);
    387.     }
    388.     /**
    389.      *生成查詢一頁數據的sql語句
    390.      *@param sql 原查詢語句
    391.      *@startIndex 開始記錄位置
    392.      *@size 需要獲取的記錄數
    393.      */
    394.     protected abstract  String intiQuerySQL(String sql, int startIndex, int size);
    395.     /**
    396.      *使用給出的對象設置指定參數的值
    397.      *@param index 第一個參數為1,第二個為2,。。。
    398.      *@param obj 包含參數值的對象
    399.      */
    400.     public void setObject(int index, Object obj) throws SQLException{
    401.         BoundParam bp = new BoundParam(index, obj);
    402.         boundParams.remove(bp);
    403.         boundParams.add( bp);
    404.     }
    405.     /**
    406.      *使用給出的對象設置指定參數的值
    407.      *@param index 第一個參數為1,第二個為2,。。。
    408.      *@param obj 包含參數值的對象
    409.      *@param targetSqlType 參數的數據庫類型
    410.      */
    411.     public void setObject(int index, Object obj, int targetSqlType) throws SQLException{
    412.         BoundParam bp = new BoundParam(index, obj, targetSqlType);
    413.         boundParams.remove(bp);
    414.         boundParams.add(bp );
    415.     }
    416.     /**
    417.      *使用給出的對象設置指定參數的值
    418.      *@param index 第一個參數為1,第二個為2,。。。
    419.      *@param obj 包含參數值的對象
    420.      *@param targetSqlType 參數的數據庫類型(常量定義在java.sql.Types中)
    421.      *@param scale 精度,小數點后的位數
    422.      * (只對targetSqlType是Types.NUMBER或Types.DECIMAL有效,其它類型則忽略)
    423.      */
    424.     public void setObject(int index, Object obj, int targetSqlType, int scale) throws SQLException{
    425.         BoundParam bp = new BoundParam(index, obj, targetSqlType, scale) ;
    426.         boundParams.remove(bp);
    427.         boundParams.add(bp);
    428.     }
    429.     /**
    430.      *使用給出的字符串設置指定參數的值
    431.      *@param index 第一個參數為1,第二個為2,。。。
    432.      *@param str 包含參數值的字符串
    433.      */
    434.     public void setString(int index, String str)throws SQLException{
    435.         BoundParam bp = new BoundParam(index, str)  ;
    436.         boundParams.remove(bp);
    437.         boundParams.add(bp);
    438.     }
    439.     /**
    440.      *使用給出的字符串設置指定參數的值
    441.      *@param index 第一個參數為1,第二個為2,。。。
    442.      *@param timestamp 包含參數值的時間戳
    443.      */
    444.     public void setTimestamp(int index, Timestamp timestamp)throws SQLException{
    445.         BoundParam bp = new BoundParam(index, timestamp)  ;
    446.         boundParams.remove(bp);
    447.         boundParams.add( bp );
    448.     }
    449.     /**
    450.      *使用給出的整數設置指定參數的值
    451.      *@param index 第一個參數為1,第二個為2,。。。
    452.      *@param value 包含參數值的整數
    453.      */
    454.     public void setInt(int index, int value)throws SQLException{
    455.         BoundParam bp =  new BoundParam(index, new Integer(value))  ;
    456.         boundParams.remove(bp);
    457.         boundParams.add( bp );
    458.     }
    459.     /**
    460.      *使用給出的長整數設置指定參數的值
    461.      *@param index 第一個參數為1,第二個為2,。。。
    462.      *@param value 包含參數值的長整數
    463.      */
    464.     public void setLong(int index, long value)throws SQLException{
    465.         BoundParam bp =  new BoundParam(index, new Long(value))  ;
    466.         boundParams.remove(bp);
    467.         boundParams.add( bp );
    468.     }
    469.     /**
    470.      *使用給出的雙精度浮點數設置指定參數的值
    471.      *@param index 第一個參數為1,第二個為2,。。。
    472.      *@param value 包含參數值的雙精度浮點數
    473.      */
    474.     public void setDouble(int index, double value)throws SQLException{
    475.         BoundParam bp =  new BoundParam(index, new Double(value))   ;
    476.         boundParams.remove(bp);
    477.         boundParams.add( bp);
    478.     }
    479.     /**
    480.      *使用給出的BigDecimal設置指定參數的值
    481.      *@param index 第一個參數為1,第二個為2,。。。
    482.      *@param bd 包含參數值的BigDecimal
    483.      */
    484.     public void setBigDecimal(int index, BigDecimal bd)throws SQLException{
    485.         BoundParam bp =   new BoundParam(index, bd )   ;
    486.         boundParams.remove(bp);
    487.         boundParams.add( bp);
    488.     }
    489.     private  void setParams(PreparedStatement pst) throws SQLException{
    490.         if (pst==null || this.boundParams==null || this.boundParams.size()==0 ) return ;
    491.         BoundParam param;
    492.         for (Iterator itr = this.boundParams.iterator();itr.hasNext();){
    493.             param = (BoundParam) itr.next();
    494.             if  (param==nullcontinue;
    495.             if (param.sqlType == java.sql.Types.OTHER){
    496.                 pst.setObject(param.index, param.value);
    497.             }else{
    498.                 pst.setObject(param.index, param.value, param.sqlType, param.scale);
    499.             }
    500.         }
    501.     }
    502.     /**
    503.      * 執行查詢取得一頁數據,執行結束后關閉數據庫連接
    504.      * @return RowSetPage
    505.      * @throws SQLException
    506.      */
    507.     public  RowSetPage executeQuery() throws SQLException{
    508.         System.out.println("executeQueryUsingPreparedStatement");
    509.         Connection conn = DBUtil.getConnection();
    510.         PreparedStatement pst = null;
    511.         ResultSet rs = null;
    512.         try{
    513.             pst = conn.prepareStatement(this.countSQL);
    514.             setParams(pst);
    515.             rs =pst.executeQuery();
    516.             if (rs.next()){
    517.                 totalCount = rs.getInt(1);
    518.             } else {
    519.                 totalCount = 0;
    520.             }
    521.             rs.close();
    522.             pst.close();
    523.             if (totalCount < 1 ) return RowSetPage.EMPTY_PAGE;
    524.             pst = conn.prepareStatement(this.querySQL);
    525.             System.out.println(querySQL);
    526.             pst.setFetchSize(this.pageSize);
    527.             setParams(pst);
    528.             rs =pst.executeQuery();
    529.             //rs.setFetchSize(pageSize);
    530.             this.rowSet = populate(rs);
    531.             rs.close();
    532.             rs = null;
    533.             pst.close();
    534.             pst = null;
    535.             this.rowSetPage = new RowSetPage(this.rowSet,startIndex,totalCount,pageSize);
    536.             return this.rowSetPage;
    537.         }catch(SQLException sqle){
    538.             //System.out.println("executeQuery SQLException");
    539.             sqle.printStackTrace();
    540.             throw sqle;
    541.         }catch(Exception e){
    542.             e.printStackTrace();
    543.             throw new RuntimeException(e.toString());
    544.         }finally{
    545.             //System.out.println("executeQuery finally");
    546.             DBUtil.close(rs, pst, conn);
    547.         }
    548.     }
    549.     /**
    550.      *將ResultSet數據填充進CachedRowSet
    551.      */
    552.     protected abstract RowSet populate(ResultSet rs) throws SQLException;
    553.     /**
    554.      *取封裝成RowSet查詢結果
    555.      *@return RowSet
    556.      */
    557.     public javax.sql.RowSet getRowSet(){
    558.         return this.rowSet;
    559.     }
    560.     /**
    561.      *取封裝成RowSetPage的查詢結果
    562.      *@return RowSetPage
    563.      */
    564.     public RowSetPage getRowSetPage() {
    565.         return this.rowSetPage;
    566.     }
    567.     /**
    568.      *關閉數據庫連接
    569.      */
    570.     public void close(){
    571.         //因為數據庫連接在查詢結束或發生異常時即關閉,此處不做任何事情
    572.         //留待擴充。
    573.     }
    574.     private class BoundParam {
    575.         int index;
    576.         Object value;
    577.         int sqlType;
    578.         int scale;
    579.         public BoundParam(int index, Object value) {
    580.             this(index, value, java.sql.Types.OTHER);
    581.         }
    582.         public BoundParam(int index, Object value, int sqlType) {
    583.             this(index, value, sqlType, 0);
    584.         }
    585.         public BoundParam(int index, Object value, int sqlType, int scale) {
    586.             this.index = index;
    587.             this.value = value;
    588.             this.sqlType = sqlType;
    589.             this.scale = scale;
    590.         }
    591.         public boolean equals(Object obj){
    592.             if (obj!=null && this.getClass().isInstance(obj)){
    593.                 BoundParam bp = (BoundParam)obj;
    594.                 if (this.index==bp.index) return true;
    595.             }
    596.             return false;
    597.         }
    598.     }
    599. }
    600. ///////////////////////////////////
    601. //
    602. //  PagedStatementOracleImpl.java
    603. //  author: evan_zhao@hotmail.com
    604. //
    605. ///////////////////////////////////
    606. package page;
    607. import java.sql.ResultSet;
    608. import java.sql.SQLException;
    609. import javax.sql.RowSet;
    610. import oracle.jdbc.rowset.OracleCachedRowSet;
    611. /**
    612.  * <p>Title: 分頁查詢Oracle數據庫實現</p>
    613.  * <p>Copyright: Copyright (c) 2002</p>
    614.  * @author evan_zhao@hotmail.com
    615.  * @version 1.0
    616.  */
    617. public class PagedStatementOracleImpl extends PagedStatement {
    618.     /**
    619.      * 構造一查詢出所有數據的PageStatement
    620.      * @param sql  query sql
    621.      */
    622.     public PagedStatementOracleImpl(String sql){
    623.         super(sql);
    624.     }
    625.     /**
    626.      * 構造一查詢出當頁數據的PageStatement
    627.      * @param sql  query sql
    628.      * @param pageNo  頁碼
    629.      */
    630.     public PagedStatementOracleImpl(String sql, int pageNo){
    631.         super(sql, pageNo);
    632.     }
    633.     /**
    634.      * 構造一查詢出當頁數據的PageStatement,并指定每頁顯示記錄條數
    635.      * @param sql query sql
    636.      * @param pageNo 頁碼
    637.      * @param pageSize 每頁容量
    638.      */
    639.     public PagedStatementOracleImpl(String sql, int pageNo, int pageSize){
    640.         super(sql, pageNo, pageSize);
    641.     }
    642.     /**
    643.      *生成查詢一頁數據的sql語句
    644.      *@param sql 原查詢語句
    645.      *@startIndex 開始記錄位置
    646.      *@size 需要獲取的記錄數
    647.      */
    648.     protected String intiQuerySQL(String sql, int startIndex, int size){
    649.         StringBuffer querySQL = new StringBuffer();
    650.         if (size != super.MAX_PAGE_SIZE) {
    651.             querySQL.append("select * from (select my_table.*,rownum as my_rownum from(")
    652.                     .append(  sql)
    653.                     .append(") my_table where rownum<").append(startIndex + size)
    654.                     .append(") where my_rownum>=").append(startIndex);
    655.         } else {
    656.             querySQL.append("select * from (select my_table.*,rownum as my_rownum from(")
    657.                     .append(sql)
    658.                     .append(") my_table ")
    659.                     .append(") where my_rownum>=").append(startIndex);
    660.         }
    661.         return querySQL.toString();
    662.     }
    663.     /**
    664.      *將ResultSet數據填充進CachedRowSet
    665.      */
    666.     protected  RowSet populate(ResultSet rs) throws SQLException{
    667.         OracleCachedRowSet ocrs = new OracleCachedRowSet();
    668.         ocrs.populate(rs);
    669.         return ocrs;
    670.     }
    671. }


    相關連接
      JSP頁面查詢顯示常用模式,介紹查詢結果集封裝的幾種常用模式。本程序使用了其中部分代碼
      RowSet規范原來是JDBC(TM) 2.0 Optional Package的一部分,現在已經并入JDBC3.0規范,并且將成為J2SE1.5的組成部分。
      關于RowSet的實現各個數據庫的jdbc driver應該都有提供,oracle實現可以到http://otn.oracle.com/software/tech/java/sqlj_jdbc/content.html下載(Additional RowSet support)
      Sun也提供了RowSet的參考實現,應該可以支持大多數數據庫:http://java.sun.com/products/jdbc/download.html
      PetStore 是Sun關于J2EE設計模式的一個示例程序。

    版權聲明   給作者寫信
    本篇文章對您是否有幫助?  投票:         投票結果:     10       2
    作者其它文章: 作者全部文章
    評論人:sun2bin 發表時間: Sat Sep 06 09:31:57 CST 2003
    在我的印象里面,Oracle中如果使用where rownum > xxx的話將會一條記錄也不返回。一般只使用rownum<xxx或rownum<=xxx。
    評論人:sun2bin 發表時間: Sat Sep 06 09:32:39 CST 2003
    對不起,看錯了。:P
    評論人:calmness 發表時間: Mon Sep 08 22:12:15 CST 2003
    若使用EJB的CMP來獲得大的查詢結果,該如何控制呢
    評論人:evan 發表時間: Tue Sep 09 09:17:42 CST 2003
    千萬不要這么做,效率極其低下
    評論人:mmgg 發表時間: Thu Sep 11 10:19:14 CST 2003
    這是我寫的測試代碼,為什么只能看第一頁,不能翻到第二頁!
    <%@ page import = "page.*"%>
    <script language="javascript">
        function doQuery(){
            form1.actionType.value="doQuery";
            form1.submit();    
            }    
    </script>
    <form name=form1 method=get>
    <input type=hidden name=actionType>
    性別:<input type=text name=gender size=1 value="<%=request.getParameter("gender")%>">
    <input type=button value=" 查詢 " onclick="doQuery()">
    </form>
    <%! int pageNo;%>
    <%

    try{        //可以通過參數pageno獲得用戶選擇的頁碼        
    pageNo = Integer.parseInt(request.getParameter("pageno") );    }catch(Exception ex){        
    //默認為第一頁        
    pageNo=1;    
    }
    String sql="select xh,xm,nsrsbh,nsrmc from fl_cjzgjcd";    //使用Oracle數據庫的分頁查詢實現,每頁顯示5條

    PagedStatement pst =new PagedStatementOracleImpl(sql,  pageNo, 3);        
    //pst.setString(1, gender);
    RowSetPage empPage = pst.executeQuery(); 

    if (empPage == null )
    empPage = RowSetPage.EMPTY_PAGE;
    %>
    <table  cellspacing="0" width="90%"> 
    <tr> <td>ID</td> <td>代碼</td> <td>用戶名</td> <td>姓名</td>  </tr>
    <%    javax.sql.RowSet empRS = (javax.sql.RowSet) empPage.getRowSet();
    if (empRS!=null) while (empRS.next() ) {
    %>        
    <tr>
    <td><%= empRS.getString("XH")%></td>
    <td><%= empRS.getString("XM")%></td>
    <td><%= empRS.getString("NSRSBH")%></td>
    <td><%= empRS.getString("NSRMC")%></td>
    </tr><%    }
    // end while
    %>        
    <tr>
    <%    //顯示總頁數和當前頁數(pageno)以及分頁代碼。    //此處doQuery為頁面上提交查詢動作的javascript函數名,pageno為標識當前頁碼的參數名
    %>            
    <td colspan=4><%= empPage.getHTML("doQuery", "pageno")
    %>
    </td>        
    </tr>    
    </table>
    評論人:mmgg 發表時間: Thu Sep 11 11:08:20 CST 2003
    OK了,你的代碼中有個小問題!</form>應該是在</table>的后邊,否則無法傳遞pageno參數給頁面!
    評論人:evan 發表時間: Thu Sep 11 12:21:22 CST 2003
    謝謝!

    jsp代碼中不要這么申明:<%! int pageNo;%>,因為這樣pageNo是servlet成員變量,會存在多線程問題
    評論人:eppen 發表時間: Thu Sep 11 12:59:14 CST 2003
    網上還有一個比較好的分頁方法

    http://tech.163.com/tm/030407/030407_89186.html
    評論人:mmgg 發表時間: Fri Sep 12 13:28:49 CST 2003
    明白了,evan,期待您的下一篇文章!
    評論人:mmgg 發表時間: Fri Sep 12 16:44:58 CST 2003
    evan,每次查詢都要連接一次數據庫是否影響效率,我看到的其他的代碼大都是連接數據庫后將連接放到session中,下次用的時候取出,不知道你是怎么考慮的?
    評論人:evan 發表時間: Tue Sep 16 21:29:06 CST 2003
    如果連接保存在session中什么時候關閉?如果用戶很多也會有問題吧?
    一般解決方法是使用連接池,大多應用服務器或web framework都支持,自己寫一個也不難
    評論人:freedomlinux 發表時間: Fri Oct 10 10:16:53 CST 2003
    there are a little problem in  JavaScript of "Page.java" .the writer use "document.all" ,but not "document.getElementById".so another browser (i.e mozilla) can not browse it.i correct the javaScript in it.
    so the linux user can browse it smoothly,here is the code.
    ///////////////////////////////////////////////////////////////
        public String getHTML(String queryJSFunctionName, String pageNoParamName){
            if (getTotalPageCount()<1){
                return "<input type='hidden' name='"+pageNoParamName+"' value='1' >";
            }
            if (queryJSFunctionName == null || queryJSFunctionName.trim().length()<1) {
                queryJSFunctionName = "gotoPage";
            }
            if (pageNoParamName == null || pageNoParamName.trim().length()<1){
                pageNoParamName = "pageno";
            }

            String gotoPage = "_"+queryJSFunctionName;
           
            StringBuffer html = new StringBuffer("\n");
            html.append("<script language=\"Javascript1.2\">\n")
                 .append("function ").append(gotoPage).append("(pageNo){  \n")
                 .append(  "   var curPage=1;  \n")
                 .append(  "   try{ curPage = document.getElementById(\"")
                 .append("select_id").append("\").value;  \n")
                 .append(  "        document.getElementById(\"").append("select_id")
                 .append("\").value = pageNo;  \n")
                 .append(  "        ").append(queryJSFunctionName).append("(pageNo); \n")
                 .append(  "        return true;  \n")
                 .append(  "   }catch(e){ \n")
    //             .append(  "      try{ \n")
    //             .append(  "           document.forms[0].submit();  \n")
    //             .append(  "      }catch(e){   \n")
                 .append(  "          alert('Not define inquiry method :function ")
                 .append(queryJSFunctionName).append("()'); \n")
                 .append(  "          document.getElementById(\"").append("select_id")
                 .append("\").value = curPage;  \n")
                 .append(  "          return false;  \n")
    //             .append(  "      }  \n")
                 .append(  "   }  \n")
                 .append(  "}")
                 .append(  "</script>  \n")
                 .append(  "");
            html.append( "<table  border=0 cellspacing=0 cellpadding=0 align=center width=80%>  \n")
                 .append( "  <tr>  \n")
                 .append( "    <td align=left><br>  \n");
            html.append(  "       共" ).append( getTotalPageCount() ).append("頁")
                 .append(  "       [") .append(getStart()).append("..").append(getEnd())
                 .append("/").append(this.getTotalSize()).append("]  \n")
                 .append( "    </td>  \n")
                 .append( "    <td align=right>  \n");
            if (hasPreviousPage()){
                 html.append( "[<a href='javascript:").append(gotoPage)
                 .append("(") .append(getCurrentPageNo()-1) 
                 .append( ")'>上一頁</a>]   \n");
            }
            html.append(  "       第")
                 .append(   "        <select name='")
                 .append(pageNoParamName).append("' id='select_id'").append(" onChange='javascript:")
                 .append(gotoPage).append("(this.value)'>\n");
            String selected = "selected";
            for(int i=1;i<=getTotalPageCount();i++){
                if( i == getCurrentPageNo() )
                     selected = "selected";
                else selected = "";
                html.append( "      <option value='").append(i).append("' ")
                  .append(selected).append(">").append(i).append("</option>  \n");
            }
            if (getCurrentPageNo()>getTotalPageCount()){
                html.append( "      <option value='").append(getCurrentPageNo())
                .append("' selected>").append(getCurrentPageNo())
                .append("</option>  \n");
            }
            html.append( "    </select>頁  \n");
            if (hasNextPage()){
                 html.append( "    [<a href='javascript:").append(gotoPage)
                   .append("(").append((getCurrentPageNo()+1)) 
                   .append( ")'>下一頁</a>]   \n");
            }
            html.append( "</td></tr></table>  \n");

            return html.toString();

        }
    ////////////////////////////////////////////////////////////////////////
    Don't use document.all

    I've lost count of the number of Javascript scripts I've seen floating around that include the equivalent of the following code snippet:

    if (document.all) {
       element = document.all[id];
    else {
       element = document.getElementById(id);
    }

    document.all was introduced in Internet Explorer 4, because the W3C DOM hadn't yet standardised a way of grabbing references to elements using their ID. By the time IE 5 came out, document.getElementById() had been standardised and as a result, IE 5 included support for it.

    IE 5 was released in September 1998. A popular browser statistics site (insert usual disclaimer as to the reliability of any stats but your own here) show IE 4's market share to be in the region of 1%. Even Netscape 4 has more users than that!

    Don't use document.all. document.getElementById() is supported by every Javascript supporting browser released since 1998.
    游客: michaellhj 發表時間: Thu Nov 20 13:07:30 CST 2003
    你好,記得你在JavaResearchOrganization上發過的帖子:”JSP分頁技術實現“嗎?


    我看過后覺得很不錯,決定采用你的方法了。首先注明的是我是新手,希望一些很低級的問題和錯誤請你原諒。

    我是用websphere 5.0開發的,數據庫是oracle;


    我在做一個日志管理,所以在EJB中建立了OperatorLog,OperatorLogHome,OperatorLogBean,并且把你提供的那四個類,放在了searchPage中。而oracle的rowset的ocrs12.zip文件已經包含在oracle的jdbc中了。
    另外,你的import foo.DBUtil我無法找到,于是建立一個DBUtil.java,實現import DBUtil,不知道這和foo.DBUtil有沒有區別。好了,我想一起準備工作已經完成了。

    當然,我現在做的是后臺的調用,也就是在EJB進行檢測我的開發。但是遇到了在PagedStatement.java中,執行rs =pst.executeQuery()時,出現了:
    [03-11-20 12:37:09:922 CST] 495b0a00 SystemOut     O executeQueryUsingPreparedStatement
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R java.sql.SQLException: ORA-00907: 缺少右括號

    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:830)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2391)
    [03-11-20 12:37:10:188 CST] 495b0a00 SystemErr     R     at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)
    [03-11-20 12:37:10:203 CST] 495b0a00 SystemErr     R     at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
    [03-11-20 12:37:10:203 CST] 495b0a00 SystemErr     R     at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:527)
    [03-11-20 12:37:10:203 CST] 495b0a00 SystemErr     R     at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeQuery(WSJdbcPreparedStatement.java:498)
    [03-11-20 12:37:10:203 CST] 495b0a00 SystemErr     R     at searchPage.PagedStatement.executeQuery(PagedStatement.java:215)
    [03-11-20 12:37:10:203 CST] 495b0a00 SystemErr     R     at logmanager.ejb.OperatorLogBean.getOPERATOR_ID(OperatorLogBean.java:58)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at logmanager.ejb.EJSRemoteStatelessOperatorLog_67a0df88.getOPERATOR_ID(EJSRemoteStatelessOperatorLog_67a0df88.java:36)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at java.lang.reflect.Method.invoke(Native Method)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at com.ibm.rmi.corba.ServantObjectImpl$3.run(ServantObjectImpl.java:223)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at java.security.AccessController.doPrivileged(Native Method)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at com.ibm.rmi.corba.ServantObjectImpl.invoke(ServantObjectImpl.java:221)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at $Proxy1.getOPERATOR_ID(Unknown Source)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at logmanager.ejb._OperatorLog_Stub.getOPERATOR_ID(_OperatorLog_Stub.java:260)
    [03-11-20 12:37:10:219 CST] 495b0a00 SystemErr     R     at java.lang.reflect.Method.invoke(Native Method)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.etools.utc.model.ReflectionMethodModel.invoke(ReflectionMethodModel.java:68)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.etools.utc.servlet.InvokeServlet.invoke(InvokeServlet.java:110)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.etools.utc.servlet.InvokeServlet.doPost(InvokeServlet.java:323)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
    [03-11-20 12:37:10:234 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:258)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:872)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:491)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:173)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:79)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:199)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java:114)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:187)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:331)
    [03-11-20 12:37:10:250 CST] 495b0a00 SystemErr     R     at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
    [03-11-20 12:37:10:266 CST] 495b0a00 SystemErr     R     at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:432)
    [03-11-20 12:37:10:266 CST] 495b0a00 SystemErr     R     at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:343)
    [03-11-20 12:37:10:266 CST] 495b0a00 SystemErr     R     at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:592)

    我不知道怎么解決,希望你能夠告訴我,萬分感謝!


    另附:一些改動已標明(粗體):
    EJB中的SESSIONBEAN-----------------OperatorLogBean.java
    package logmanager.ejb;
    import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.PreparedStatement;


    import oracle.jdbc.rowset.OracleCachedRowSet;

    import searchPage.*;
    /**
     * Bean implementation class for Enterprise Bean: OperatorLog
     */
    public class OperatorLogBean implements javax.ejb.SessionBean {
     private javax.ejb.SessionContext mySessionCtx;
     /**
      * getSessionContext
      */
     public javax.ejb.SessionContext getSessionContext() {
      return mySessionCtx;
     }
     /**
      * setSessionContext
      */
     public void setSessionContext(javax.ejb.SessionContext ctx) {
      mySessionCtx = ctx;
     }
     /**
      * ejbCreate
      */
     public void ejbCreate() throws javax.ejb.CreateException {
     }
     /**
      * ejbActivate
      */
     public void ejbActivate() {
     }
     /**
      * ejbPassivate
      */
     public void ejbPassivate() {
     }
     /**
      * ejbRemove
      */
     public void ejbRemove() {
     }
     public RowSetPage getOPERATOR_ID(String OPERATOR_ID, int pageNo) throws Exception{
      String sql="SELECT OPERATION_LOG.LOG_ID,OPERATION_LOG.LOG_TIME,OPERATION_LOG.LOG_CONTENT,OPERATOR.OPERATOR_ID,OPERATOR.OPERATOR_NAME,OPERATOR.PASSWORD,OPERATOR.OPERATOR_STATE,ORGANIZE.ORG_ID,ORGANIZE.ORG_NAME,ORGANIZE.ORG_TYPE,TERMINAL_INFO.IP,SYSTEM_MODULE.MODULE_ID,ROLE_INFO.ROLE_ID,ROLE_INFO.ROLE_NAME,ROLE_INFO.ROLE_TYPE,ROLE_INFO.ROLE_INHERIT,MODULE_FUNCTION.FUNCTION_ID,MODULE_FUNCTION.FUNCTION_NAME,MODULE_FUNCTION.FUNCTION_URL,SYSTEM_MODULE.MODULE_NAME,SYSTEM_MODULE.MODULE_DEPTH,SYSTEM_MODULE.ROOT_ID,SYSTEM_MODULE.PARENT_ID";
             sql=sql+"FROM OPERATION_LOG,OPERATOR,ORGANIZE,TERMINAL_INFO,MODULE_FUNCTION,OPERATOR_ROLE,ROLE_INFO,ROLE_PERMISSION,SYSTEM_MODULE";  
             sql=sql+"WHERE ( OPERATOR.OPERATOR_ID = OPERATION_LOG.OPERATOR_ID ) and ( ORGANIZE.ORG_ID = OPERATOR.ORG_ID ) and ( TERMINAL_INFO.ORG_ID = ORGANIZE.ORG_ID ) and ( OPERATOR_ROLE.OPERATOR_ID = OPERATOR.OPERATOR_ID ) and ( ROLE_INFO.ROLE_ID = OPERATOR_ROLE.ROLE_ID ) and  ( ROLE_INFO.ORG_ID = ORGANIZE.ORG_ID ) and  ( ROLE_PERMISSION.ROLE_ID = ROLE_INFO.ROLE_ID ) and  ( ROLE_PERMISSION.FUNCTION_ID = MODULE_FUNCTION.FUNCTION_ID ) and  ( SYSTEM_MODULE.MODULE_ID = ROLE_PERMISSION.FUNCTION_MODULE ) and  ( SYSTEM_MODULE.MODULE_ID = MODULE_FUNCTION.FUNCTION_MODULE ) and  (  OPERATION_LOG.OPERATOR_ID = ?  ) ";
       
        //使用Oracle數據庫的分頁查詢實現,每頁顯示5條        
      PagedStatement pst =new PagedStatementOracleImpl(sql,pageNo, 5);   
      pst.setString(1, OPERATOR_ID);   
      return pst.executeQuery();
     }

    }

    你編寫的四個文件沒有修改,只是對DBUtil.java中的jndi做了改變。

        private static void initDataSource() throws Exception{
            // Put connection properties in to a hashtable.


            if (ctx == null) {
                ctx = new InitialContext();
            }
            if (ds == null) {
                ds = (javax.sql.DataSource) ctx.lookup("java:comp/env/jdbc/ejbPool");
            }
        }    




    評論人:wa5326232 發表時間: Wed May 11 14:19:53 CST 2005
    收獲啊```別的什么都不說了```
    評論人:sics1314 發表時間: Wed Mar 15 14:56:50 CST 2006
    暫時還搞不懂,俺是初學者~!學習ing~!
    評論人:downbar 發表時間: Fri May 26 10:58:58 CST 2006
    PagedStatementOracleImpl.java中 如下語句調試不通過,
    OracleCachedRowSet ors = newOracleCachedRowSet(); 
    請教是什么原因呢?
    評論人:wangguan 發表時間: Sun Jun 18 08:06:46 CST 2006
    [cop]
    評論人:ahliujin 發表時間: Thu Nov 09 14:18:05 CST 2006
    收藏
    評論人:winc218 發表時間: Wed May 02 18:29:22 CST 2007
    感覺用存儲過程實現分頁更高效

    posted on 2007-12-16 13:49 風人園 閱讀(592) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 免费大学生国产在线观看p| 亚洲人成人网毛片在线播放| 国产精品国产自线拍免费软件| 久久青草精品38国产免费| 美女被羞羞网站免费下载| 亚洲人成人网毛片在线播放| 久久精品国产亚洲AV大全| 亚洲欧洲国产精品香蕉网| 免费大黄网站在线观看| 在线a毛片免费视频观看| 99爱在线精品免费观看| 日韩精品无码免费一区二区三区| 久久免费国产精品| 午夜亚洲乱码伦小说区69堂| 亚洲熟妇久久精品| 亚洲1234区乱码| 亚洲天堂电影在线观看| 亚洲AV日韩精品久久久久| 亚洲高清国产拍精品熟女| 亚洲日本国产精华液| 一区二区三区亚洲| 亚洲精品高清视频| 亚洲AV乱码一区二区三区林ゆな| 一本久久a久久精品亚洲| 毛茸茸bbw亚洲人| 亚洲区不卡顿区在线观看| 亚洲国产香蕉人人爽成AV片久久 | 亚洲精品~无码抽插| 亚洲狠狠爱综合影院婷婷| 亚洲Av无码乱码在线播放| 免费大黄网站在线观看| 亚洲成人一区二区| 亚洲欧洲国产成人综合在线观看| 免费人成视频在线观看视频| 免费一级毛片在线播放| 又色又污又黄无遮挡的免费视| 全亚洲最新黄色特级网站| 亚洲不卡AV影片在线播放| 久久久久久久亚洲精品| 中文字幕精品亚洲无线码一区| 亚洲国产一二三精品无码|