乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JSP分頁技術(shù)實現(xiàn)

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

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

        在oracle數(shù)據(jù)庫中查詢結(jié)果的行號使用偽列ROWNUM表示(從1開始)。例如select * from employee where rownum<10 返回前10條記錄。但因為rownum是在查詢之后排序之前賦值的,所以查詢employee按birthday排序的第100到120條記錄應(yīng)該這么寫:
      [pre]        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
      [/pre]
         mySQL可以使用LIMIT子句:
           select name, birthday from employee order by birthday LIMIT 99,20
         DB2有rownumber()函數(shù)用于獲取當(dāng)前行數(shù)。
         SQL Server沒研究過,可以參考這篇文章:http://www.csdn.net/develop/article/18/18627.shtm

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

        下面是簡單的使用示例:


          //DAO查詢數(shù)據(jù)部分代碼:
          …
          public RowSetPage getEmployee(String gender, int pageNo) throws Exception{
              String sql="select emp_id, emp_code,  user_name, real_name from employee where gender =?";
             //使用Oracle數(shù)據(jù)庫的分頁查詢實現(xiàn),每頁顯示5條
              PagedStatement pst =new PagedStatementOracleImpl(sql,  pageNo, 5);
              pst.setString(1, gender);
              return pst.executeQuery();
          }


          //Servlet處理查詢請求部分代碼:

          …
          int pageNo;
          try{
              //可以通過參數(shù)pageno獲得用戶選擇的頁碼
              pageNo = Integer.parseInt(request.getParameter("pageno") );
          }catch(Exception ex){
              //默認為第一頁
              pageNo=1;
          }
          String gender = request.getParameter("gender" );
          request.setAttribute("empPage", myBean.getEmployee(gender, pageNo) );
          …

          //JSP顯示部分代碼
      <%@ page import = "page.RowSetPage"%>
          …
          <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()">
      <%
          RowSetPage empPage = (RowSetPage)request.getAttribute("empPage");
          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("EMP_ID")%></td> 
                  <td><%= empRS.getString("EMP_CODE")%></td>  
                  <td><%= empRS.getString("USER_NAME")%></td> 
                  <td><%= empRS.getString("REAL_NAME")%></td>  
              </tr>
      <%
          }// end while
      %>
              <tr>
      <%
          //顯示總頁數(shù)和當(dāng)前頁數(shù)(pageno)以及分頁代碼。
          //此處doQuery為頁面上提交查詢動作的javascript函數(shù)名, pageno為標(biāo)識當(dāng)前頁碼的參數(shù)名
      %>
                  <td colspan=4><%= empPage .getHTML("doQuery", "pageno")%></td>
              </tr>
          </table>
          </form>

        效果如圖:


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

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

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

      您可以任意使用這些源代碼,但必須保留author evan_zhao@hotmail.com字樣


      ///////////////////////////////////
      //
      //  Page.java
      //  author: evan_zhao@hotmail.com
      //
      ///////////////////////////////////

      package page;

      import java.util.List;
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.Collections;


      /**
       * Title: 分頁對象<br>
       * Description:  用于包含數(shù)據(jù)及分頁信息的對象<br>
       *               Page類實現(xiàn)了用于顯示分頁信息的基本方法,但未指定所含數(shù)據(jù)的類型,
       *               可根據(jù)需要實現(xiàn)以特定方式組織數(shù)據(jù)的子類,<br>
       *               如RowSetPage以RowSet封裝數(shù)據(jù),ListPage以List封裝數(shù)據(jù)<br>
       * Copyright:    Copyright (c) 2002 <br>
       * @author evan_zhao@hotmail.com <br>
       * @version 1.0
       */
      public  class Page implements java.io.Serializable {
          public static final Page EMPTY_PAGE = new Page();
          public static final int  DEFAULT_PAGE_SIZE = 20;
          public static final  int MAX_PAGE_SIZE = 9999;

          private int myPageSize = DEFAULT_PAGE_SIZE;

          private int start;
          private int avaCount,totalSize;
          private Object data;

          private int currentPageno;
          private int totalPageCount;

          /**
           * 默認構(gòu)造方法,只構(gòu)造空頁
           */
          protected Page(){
              this.init(0,0,0,DEFAULT_PAGE_SIZE,new Object());
          }

          /**
           * 分頁數(shù)據(jù)初始方法,由子類調(diào)用
           * @param start 本頁數(shù)據(jù)在數(shù)據(jù)庫中的起始位置
           * @param avaCount 本頁包含的數(shù)據(jù)條數(shù)
           * @param totalSize 數(shù)據(jù)庫中總記錄條數(shù)
           * @param pageSize 本頁容量
           * @param data 本頁包含的數(shù)據(jù)
           */
          protected void init(int start, int avaCount, int totalSize, int pageSize, Object data){

              this.avaCount =avaCount;
              this.myPageSize = pageSize;

              this.start = start;
              this.totalSize = totalSize;

              this.data=data;

              //System.out.println("avaCount:"+avaCount);
              //System.out.println("totalSize:"+totalSize);
              if (avaCount>totalSize) {
                  //throw new RuntimeException("記錄條數(shù)大于總條數(shù)?!");
              }

              this.currentPageno = (start -1)/pageSize +1;
              this.totalPageCount = (totalSize + pageSize -1) / pageSize;

              if (totalSize==0 && avaCount==0){
                  this.currentPageno = 1;
                  this.totalPageCount = 1;
              }
              //System.out.println("Start Index to Page No: " + start + "-" + currentPageno);
          }

          public  Object getData(){
              return this.data;
          }

          /**
           * 取本頁數(shù)據(jù)容量(本頁能包含的記錄數(shù))
           * @return 本頁能包含的記錄數(shù)
           */
          public int getPageSize(){
              return this.myPageSize;
          }

          /**
           * 是否有下一頁
           * @return 是否有下一頁
           */
          public boolean hasNextPage() {
            /*
              if (avaCount==0 && totalSize==0){
                  return false;
              }
              return (start + avaCount -1) < totalSize;
             */
            return (this.getCurrentPageNo()<this.getTotalPageCount());
          }

          /**
           * 是否有上一頁
           * @return  是否有上一頁
           */
          public boolean hasPreviousPage() {
            /*
              return start > 1;
             */
            return (this.getCurrentPageNo()>1);
          }

          /**
           * 獲取當(dāng)前頁第一條數(shù)據(jù)在數(shù)據(jù)庫中的位置
           * @return
           */
          public int getStart(){
              return start;
          }

          /**
           * 獲取當(dāng)前頁最后一條數(shù)據(jù)在數(shù)據(jù)庫中的位置
           * @return
           */
          public int getEnd(){
              int end = this.getStart() + this.getSize() -1;
              if (end<0) {
                  end = 0;
              }
              return end;
          }

          /**
           * 獲取上一頁第一條數(shù)據(jù)在數(shù)據(jù)庫中的位置
           * @return 記錄對應(yīng)的rownum
           */
          public int getStartOfPreviousPage() {
              return Math.max(start-myPageSize, 1);
          }


          /**
           * 獲取下一頁第一條數(shù)據(jù)在數(shù)據(jù)庫中的位置
           * @return 記錄對應(yīng)的rownum
           */
          public int getStartOfNextPage() {
              return start + avaCount;
          }

          /**
           * 獲取任一頁第一條數(shù)據(jù)在數(shù)據(jù)庫中的位置,每頁條數(shù)使用默認值
           * @param pageNo 頁號
           * @return 記錄對應(yīng)的rownum
           */
          public static int getStartOfAnyPage(int pageNo){
              return getStartOfAnyPage(pageNo, DEFAULT_PAGE_SIZE);
          }

          /**
           * 獲取任一頁第一條數(shù)據(jù)在數(shù)據(jù)庫中的位置
           * @param pageNo 頁號
           * @param pageSize 每頁包含的記錄數(shù)
           * @return 記錄對應(yīng)的rownum
           */
          public static int getStartOfAnyPage(int pageNo, int pageSize){
              int startIndex = (pageNo-1) * pageSize + 1;
              if ( startIndex < 1) startIndex = 1;
              //System.out.println("Page No to Start Index: " + pageNo + "-" + startIndex);
              return startIndex;
          }

          /**
           * 取本頁包含的記錄數(shù)
           * @return 本頁包含的記錄數(shù)
           */
          public int getSize() {
              return avaCount;
          }

          /**
           * 取數(shù)據(jù)庫中包含的總記錄數(shù)
           * @return 數(shù)據(jù)庫中包含的總記錄數(shù)
           */
          public int getTotalSize() {
              return this.totalSize;
          }

          /**
           * 取當(dāng)前頁碼
           * @return 當(dāng)前頁碼
           */
          public int getCurrentPageNo(){
              return  this.currentPageno;
          }

          /**
           * 取總頁碼
           * @return 總頁碼
           */
          public int getTotalPageCount(){
              return this.totalPageCount;
          }


          /**
           *
           * @param queryJSFunctionName 實現(xiàn)分頁的JS腳本名字,頁碼變動時會自動回調(diào)該方法
           * @param pageNoParamName 頁碼參數(shù)名稱
           * @return
           */
          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.all[\"")
                   .append(pageNoParamName).append("\"].value;  \n")
                   .append(  "        document.all[\"").append(pageNoParamName)
                   .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(‘尚未定義查詢方法:function ")
                   .append(queryJSFunctionName).append("()‘); \n")
                   .append(  "          document.all[\"").append(pageNoParamName)
                   .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("‘ 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();

          }
      }


      ///////////////////////////////////
      //
      //  RowSetPage.java
      //  author: evan_zhao@hotmail.com
      //
      ///////////////////////////////////
      package page;

      import javax.sql.RowSet;


      /**
       * <p>Title: RowSetPage</p>
       * <p>Description: 使用RowSet封裝數(shù)據(jù)的分頁對象</p>
       * <p>Copyright: Copyright (c) 2003</p>
       * @author evan_zhao@hotmail.com
       * @version 1.0
       */

      public class RowSetPage extends Page {
          private javax.sql.RowSet rs;

          /**
           *空頁
           */
          public static final RowSetPage EMPTY_PAGE = new RowSetPage();

          /**
           *默認構(gòu)造方法,創(chuàng)建空頁
           */
          public RowSetPage(){
            this(null, 0,0);
          }

          /**
           *構(gòu)造分頁對象
           *@param crs 包含一頁數(shù)據(jù)的OracleCachedRowSet
           *@param start 該頁數(shù)據(jù)在數(shù)據(jù)庫中的起始位置
           *@param totalSize 數(shù)據(jù)庫中包含的記錄總數(shù)
           */
          public RowSetPage(RowSet crs, int start, int totalSize) {
              this(crs,start,totalSize,Page.DEFAULT_PAGE_SIZE);
          }

          /**
           *構(gòu)造分頁對象
           *@param crs 包含一頁數(shù)據(jù)的OracleCachedRowSet
           *@param start 該頁數(shù)據(jù)在數(shù)據(jù)庫中的起始位置
           *@param totalSize 數(shù)據(jù)庫中包含的記錄總數(shù)
           *@pageSize 本頁能容納的記錄數(shù)
           */
          public RowSetPage(RowSet crs, int start, int totalSize, int pageSize) {
              try{
                  int avaCount=0;
                  if (crs!=null) {
                      crs.beforeFirst();
                      if (crs.next()){
                          crs.last();
                          avaCount = crs.getRow();
                      }
                      crs.beforeFirst();
                  }
                  rs = crs;
                  super.init(start,avaCount,totalSize,pageSize,rs);
              }catch(java.sql.SQLException sqle){
                  throw new RuntimeException(sqle.toString());
              }
          }

          /**
           *取分頁對象中的記錄數(shù)據(jù)
           */
          public javax.sql.RowSet getRowSet(){
              return rs;
          }


      }


      ///////////////////////////////////
      //
      //  PagedStatement.java
      //  author: evan_zhao@hotmail.com
      //
      ///////////////////////////////////

      package page;

      import foo.DBUtil;

      import java.math.BigDecimal;
      import java.util.List;
      import java.util.Iterator;
      import java.util.Collections;

      import java.sql.Connection;
      import java.sql.SQLException;
      import java.sql.ResultSet;
      import java.sql.Statement;
      import java.sql.PreparedStatement;
      import java.sql.Timestamp;
      import javax.sql.RowSet;

      /**
       * <p>Title: 分頁查詢</p>
       * <p>Description: 根據(jù)查詢語句和頁碼查詢出當(dāng)頁數(shù)據(jù)</p>
       * <p>Copyright: Copyright (c) 2002</p>
       * @author evan_zhao@hotmail.com
       * @version 1.0
       */
      public abstract class PagedStatement {
          public final static int MAX_PAGE_SIZE = Page.MAX_PAGE_SIZE;

          protected String countSQL, querySQL;
          protected int pageNo,pageSize,startIndex,totalCount;
          protected javax.sql.RowSet rowSet;
          protected RowSetPage rowSetPage;

          private List boundParams;

          /**
           * 構(gòu)造一查詢出所有數(shù)據(jù)的PageStatement
           * @param sql  query sql
           */
          public PagedStatement(String sql){
              this(sql,1,MAX_PAGE_SIZE);
          }


          /**
           * 構(gòu)造一查詢出當(dāng)頁數(shù)據(jù)的PageStatement
           * @param sql  query sql
           * @param pageNo  頁碼
           */
          public PagedStatement(String sql, int pageNo){
              this(sql, pageNo, Page.DEFAULT_PAGE_SIZE);
          }

          /**
           * 構(gòu)造一查詢出當(dāng)頁數(shù)據(jù)的PageStatement,并指定每頁顯示記錄條數(shù)
           * @param sql query sql
           * @param pageNo 頁碼
           * @param pageSize 每頁容量
           */
          public PagedStatement(String sql, int pageNo, int pageSize){
              this.pageNo = pageNo;
              this.pageSize = pageSize;
              this.startIndex = Page.getStartOfAnyPage(pageNo, pageSize);
              this.boundParams = Collections.synchronizedList(new java.util.LinkedList());

              this.countSQL = "select count(*) from ( " + sql +") ";
              this.querySQL = intiQuerySQL(sql, this.startIndex, pageSize);
          }


          /**
           *生成查詢一頁數(shù)據(jù)的sql語句
           *@param sql 原查詢語句
           *@startIndex 開始記錄位置
           *@size 需要獲取的記錄數(shù)
           */
          protected abstract  String intiQuerySQL(String sql, int startIndex, int size);


          /**
           *使用給出的對象設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param obj 包含參數(shù)值的對象
           */
          public void setObject(int index, Object obj) throws SQLException{
              BoundParam bp = new BoundParam(index, obj);
              boundParams.remove(bp);
              boundParams.add( bp);
          }

          /**
           *使用給出的對象設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param obj 包含參數(shù)值的對象
           *@param targetSqlType 參數(shù)的數(shù)據(jù)庫類型
           */
          public void setObject(int index, Object obj, int targetSqlType) throws SQLException{
              BoundParam bp = new BoundParam(index, obj, targetSqlType);
              boundParams.remove(bp);
              boundParams.add(bp );
          }

          /**
           *使用給出的對象設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param obj 包含參數(shù)值的對象
           *@param targetSqlType 參數(shù)的數(shù)據(jù)庫類型(常量定義在java.sql.Types中)
           *@param scale 精度,小數(shù)點后的位數(shù)
           * (只對targetSqlType是Types.NUMBER或Types.DECIMAL有效,其它類型則忽略)
           */
          public void setObject(int index, Object obj, int targetSqlType, int scale) throws SQLException{
              BoundParam bp = new BoundParam(index, obj, targetSqlType, scale) ;
              boundParams.remove(bp);
              boundParams.add(bp);
          }

          /**
           *使用給出的字符串設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param str 包含參數(shù)值的字符串
           */
          public void setString(int index, String str)throws SQLException{
              BoundParam bp = new BoundParam(index, str)  ;
              boundParams.remove(bp);
              boundParams.add(bp);
          }

          /**
           *使用給出的字符串設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param timestamp 包含參數(shù)值的時間戳
           */
          public void setTimestamp(int index, Timestamp timestamp)throws SQLException{
              BoundParam bp = new BoundParam(index, timestamp)  ;
              boundParams.remove(bp);
              boundParams.add( bp );
          }

          /**
           *使用給出的整數(shù)設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param value 包含參數(shù)值的整數(shù)
           */
          public void setInt(int index, int value)throws SQLException{
              BoundParam bp =  new BoundParam(index, new Integer(value))  ;
              boundParams.remove(bp);
              boundParams.add( bp );
          }

          /**
           *使用給出的長整數(shù)設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param value 包含參數(shù)值的長整數(shù)
           */
          public void setLong(int index, long value)throws SQLException{
              BoundParam bp =  new BoundParam(index, new Long(value))  ;
              boundParams.remove(bp);
              boundParams.add( bp );
          }

          /**
           *使用給出的雙精度浮點數(shù)設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param value 包含參數(shù)值的雙精度浮點數(shù)
           */
          public void setDouble(int index, double value)throws SQLException{
              BoundParam bp =  new BoundParam(index, new Double(value))   ;
              boundParams.remove(bp);
              boundParams.add( bp);
          }

          /**
           *使用給出的BigDecimal設(shè)置指定參數(shù)的值
           *@param index 第一個參數(shù)為1,第二個為2,。。。
           *@param bd 包含參數(shù)值的BigDecimal
           */
          public void setBigDecimal(int index, BigDecimal bd)throws SQLException{
              BoundParam bp =   new BoundParam(index, bd )   ;
              boundParams.remove(bp);
              boundParams.add( bp);
          }

          private  void setParams(PreparedStatement pst) throws SQLException{
              if (pst==null || this.boundParams==null || this.boundParams.size()==0 ) return ;
              BoundParam param;
              for (Iterator itr = this.boundParams.iterator();itr.hasNext();){
                  param = (BoundParam) itr.next();
                  if  (param==null) continue;
                  if (param.sqlType == java.sql.Types.OTHER){
                      pst.setObject(param.index, param.value);
                  }else{
                      pst.setObject(param.index, param.value, param.sqlType, param.scale);
                  }
              }
          }

          /**
           * 執(zhí)行查詢?nèi)〉靡豁摂?shù)據(jù),執(zhí)行結(jié)束后關(guān)閉數(shù)據(jù)庫連接
           * @return RowSetPage
           * @throws SQLException
           */
          public  RowSetPage executeQuery() throws SQLException{
              System.out.println("executeQueryUsingPreparedStatement");
              Connection conn = DBUtil.getConnection();
              PreparedStatement pst = null;
              ResultSet rs = null;
              try{
                  pst = conn.prepareStatement(this.countSQL);
                  setParams(pst);
                  rs =pst.executeQuery();
                  if (rs.next()){
                      totalCount = rs.getInt(1);
                  } else {
                      totalCount = 0;
                  }

                  rs.close();
                  pst.close();

                  if (totalCount < 1 ) return RowSetPage.EMPTY_PAGE;

                  pst = conn.prepareStatement(this.querySQL);
                  System.out.println(querySQL);
                  pst.setFetchSize(this.pageSize);
                  setParams(pst);
                  rs =pst.executeQuery();
                  //rs.setFetchSize(pageSize);

                  this.rowSet = populate(rs);

                  rs.close();
                  rs = null;
                  pst.close();
                  pst = null;

                  this.rowSetPage = new RowSetPage(this.rowSet,startIndex,totalCount,pageSize);
                  return this.rowSetPage;
              }catch(SQLException sqle){
                  //System.out.println("executeQuery SQLException");
                  sqle.printStackTrace();
                  throw sqle;
              }catch(Exception e){
                  e.printStackTrace();
                  throw new RuntimeException(e.toString());
              }finally{
                  //System.out.println("executeQuery finally");
                  DBUtil.close(rs, pst, conn);
              }
          }

          /**
           *將ResultSet數(shù)據(jù)填充進CachedRowSet
           */
          protected abstract RowSet populate(ResultSet rs) throws SQLException;

          /**
           *取封裝成RowSet查詢結(jié)果
           *@return RowSet
           */
          public javax.sql.RowSet getRowSet(){
              return this.rowSet;
          }


          /**
           *取封裝成RowSetPage的查詢結(jié)果
           *@return RowSetPage
           */
          public RowSetPage getRowSetPage() {
              return this.rowSetPage;
          }

          /**
           *關(guān)閉數(shù)據(jù)庫連接
           */
          public void close(){
              //因為數(shù)據(jù)庫連接在查詢結(jié)束或發(fā)生異常時即關(guān)閉,此處不做任何事情
              //留待擴充。
          }

          private class BoundParam {
              int index;
              Object value;
              int sqlType;
              int scale;

              public BoundParam(int index, Object value) {
                  this(index, value, java.sql.Types.OTHER);
              }

              public BoundParam(int index, Object value, int sqlType) {
                  this(index, value, sqlType, 0);
              }

              public BoundParam(int index, Object value, int sqlType, int scale) {
                  this.index = index;
                  this.value = value;
                  this.sqlType = sqlType;
                  this.scale = scale;
              }

              public boolean equals(Object obj){
                  if (obj!=null && this.getClass().isInstance(obj)){
                      BoundParam bp = (BoundParam)obj;
                      if (this.index==bp.index) return true;
                  }
                  return false;
              }
          }

      }


      ///////////////////////////////////
      //
      //  PagedStatementOracleImpl.java
      //  author: evan_zhao@hotmail.com
      //
      ///////////////////////////////////
      package page;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import javax.sql.RowSet;
      import oracle.jdbc.rowset.OracleCachedRowSet;

      /**
       * <p>Title: 分頁查詢Oracle數(shù)據(jù)庫實現(xiàn)</p>
       * <p>Copyright: Copyright (c) 2002</p>
       * @author evan_zhao@hotmail.com
       * @version 1.0
       */
      public class PagedStatementOracleImpl extends PagedStatement {

          /**
           * 構(gòu)造一查詢出所有數(shù)據(jù)的PageStatement
           * @param sql  query sql
           */
          public PagedStatementOracleImpl(String sql){
              super(sql);
          }


          /**
           * 構(gòu)造一查詢出當(dāng)頁數(shù)據(jù)的PageStatement
           * @param sql  query sql
           * @param pageNo  頁碼
           */
          public PagedStatementOracleImpl(String sql, int pageNo){
              super(sql, pageNo);
          }

          /**
           * 構(gòu)造一查詢出當(dāng)頁數(shù)據(jù)的PageStatement,并指定每頁顯示記錄條數(shù)
           * @param sql query sql
           * @param pageNo 頁碼
           * @param pageSize 每頁容量
           */
          public PagedStatementOracleImpl(String sql, int pageNo, int pageSize){
              super(sql, pageNo, pageSize);
          }


          /**
           *生成查詢一頁數(shù)據(jù)的sql語句
           *@param sql 原查詢語句
           *@startIndex 開始記錄位置
           *@size 需要獲取的記錄數(shù)
           */
          protected String intiQuerySQL(String sql, int startIndex, int size){
              StringBuffer querySQL = new StringBuffer();
              if (size != super.MAX_PAGE_SIZE) {
                  querySQL.append("select * from (select my_table.*,rownum as my_rownum from(")
                          .append(  sql)
                          .append(") my_table where rownum<").append(startIndex + size)
                          .append(") where my_rownum>=").append(startIndex);
              } else {
                  querySQL.append("select * from (select my_table.*,rownum as my_rownum from(")
                          .append(sql)
                          .append(") my_table ")
                          .append(") where my_rownum>=").append(startIndex);
              }
              return querySQL.toString();
          }

          /**
           *將ResultSet數(shù)據(jù)填充進CachedRowSet
           */
          protected  RowSet populate(ResultSet rs) throws SQLException{
              OracleCachedRowSet ocrs = new OracleCachedRowSet();
              ocrs.populate(rs);
              return ocrs;
          }

      }


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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多