|
目前比較廣泛使用的分頁方式是將查詢結果緩存在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。
下面是簡單的使用示例:
-
- //DAO查詢數據部分代碼:
- …
- 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數據庫的分頁查詢實現,每頁顯示5條
- PagedStatement pst =new PagedStatementOracleImpl(sql, pageNo, 5);
- pst.setString(1, gender);
- return pst.executeQuery();
- }
-
-
- //Servlet處理查詢請求部分代碼:
-
- …
- int pageNo;
- try{
- //可以通過參數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>
- <%
- //顯示總頁數和當前頁數(pageno)以及分頁代碼。
- //此處doQuery為頁面上提交查詢動作的javascript函數名, pageno為標識當前頁碼的參數名
- %>
- <td colspan=4><%= empPage .getHTML("doQuery", "pageno")%></td>
- </tr>
- </table>
- </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字樣
-
- ///////////////////////////////////
- //
- // 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: 用于包含數據及分頁信息的對象<br>
- * Page類實現了用于顯示分頁信息的基本方法,但未指定所含數據的類型,
- * 可根據需要實現以特定方式組織數據的子類,<br>
- * 如RowSetPage以RowSet封裝數據,ListPage以List封裝數據<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;
-
- /**
- * 默認構造方法,只構造空頁
- */
- protected Page(){
- this.init(0,0,0,DEFAULT_PAGE_SIZE,new Object());
- }
-
- /**
- * 分頁數據初始方法,由子類調用
- * @param start 本頁數據在數據庫中的起始位置
- * @param avaCount 本頁包含的數據條數
- * @param totalSize 數據庫中總記錄條數
- * @param pageSize 本頁容量
- * @param data 本頁包含的數據
- */
- 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("記錄條數大于總條數?!");
- }
-
- 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;
- }
-
- /**
- * 取本頁數據容量(本頁能包含的記錄數)
- * @return 本頁能包含的記錄數
- */
- 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);
- }
-
- /**
- * 獲取當前頁第一條數據在數據庫中的位置
- * @return
- */
- public int getStart(){
- return start;
- }
-
- /**
- * 獲取當前頁最后一條數據在數據庫中的位置
- * @return
- */
- public int getEnd(){
- int end = this.getStart() + this.getSize() -1;
- if (end<0) {
- end = 0;
- }
- return end;
- }
-
- /**
- * 獲取上一頁第一條數據在數據庫中的位置
- * @return 記錄對應的rownum
- */
- public int getStartOfPreviousPage() {
- return Math.max(start-myPageSize, 1);
- }
-
-
- /**
- * 獲取下一頁第一條數據在數據庫中的位置
- * @return 記錄對應的rownum
- */
- public int getStartOfNextPage() {
- return start + avaCount;
- }
-
- /**
- * 獲取任一頁第一條數據在數據庫中的位置,每頁條數使用默認值
- * @param pageNo 頁號
- * @return 記錄對應的rownum
- */
- public static int getStartOfAnyPage(int pageNo){
- return getStartOfAnyPage(pageNo, DEFAULT_PAGE_SIZE);
- }
-
- /**
- * 獲取任一頁第一條數據在數據庫中的位置
- * @param pageNo 頁號
- * @param pageSize 每頁包含的記錄數
- * @return 記錄對應的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;
- }
-
- /**
- * 取本頁包含的記錄數
- * @return 本頁包含的記錄數
- */
- public int getSize() {
- return avaCount;
- }
-
- /**
- * 取數據庫中包含的總記錄數
- * @return 數據庫中包含的總記錄數
- */
- public int getTotalSize() {
- return this.totalSize;
- }
-
- /**
- * 取當前頁碼
- * @return 當前頁碼
- */
- public int getCurrentPageNo(){
- return this.currentPageno;
- }
-
- /**
- * 取總頁碼
- * @return 總頁碼
- */
- public int getTotalPageCount(){
- return this.totalPageCount;
- }
-
-
- /**
- *
- * @param queryJSFunctionName 實現分頁的JS腳本名字,頁碼變動時會自動回調該方法
- * @param pageNoParamName 頁碼參數名稱
- * @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封裝數據的分頁對象</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();
-
- /**
- *默認構造方法,創建空頁
- */
- public RowSetPage(){
- this(null, 0,0);
- }
-
- /**
- *構造分頁對象
- *@param crs 包含一頁數據的OracleCachedRowSet
- *@param start 該頁數據在數據庫中的起始位置
- *@param totalSize 數據庫中包含的記錄總數
- */
- public RowSetPage(RowSet crs, int start, int totalSize) {
- this(crs,start,totalSize,Page.DEFAULT_PAGE_SIZE);
- }
-
- /**
- *構造分頁對象
- *@param crs 包含一頁數據的OracleCachedRowSet
- *@param start 該頁數據在數據庫中的起始位置
- *@param totalSize 數據庫中包含的記錄總數
- *@pageSize 本頁能容納的記錄數
- */
- 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());
- }
- }
-
- /**
- *取分頁對象中的記錄數據
- */
- 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: 根據查詢語句和頁碼查詢出當頁數據</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;
-
- /**
- * 構造一查詢出所有數據的PageStatement
- * @param sql query sql
- */
- public PagedStatement(String sql){
- this(sql,1,MAX_PAGE_SIZE);
- }
-
-
- /**
- * 構造一查詢出當頁數據的PageStatement
- * @param sql query sql
- * @param pageNo 頁碼
- */
- public PagedStatement(String sql, int pageNo){
- this(sql, pageNo, Page.DEFAULT_PAGE_SIZE);
- }
-
- /**
- * 構造一查詢出當頁數據的PageStatement,并指定每頁顯示記錄條數
- * @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);
- }
-
-
- /**
- *生成查詢一頁數據的sql語句
- *@param sql 原查詢語句
- *@startIndex 開始記錄位置
- *@size 需要獲取的記錄數
- */
- protected abstract String intiQuerySQL(String sql, int startIndex, int size);
-
-
- /**
- *使用給出的對象設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param obj 包含參數值的對象
- */
- public void setObject(int index, Object obj) throws SQLException{
- BoundParam bp = new BoundParam(index, obj);
- boundParams.remove(bp);
- boundParams.add( bp);
- }
-
- /**
- *使用給出的對象設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param obj 包含參數值的對象
- *@param targetSqlType 參數的數據庫類型
- */
- public void setObject(int index, Object obj, int targetSqlType) throws SQLException{
- BoundParam bp = new BoundParam(index, obj, targetSqlType);
- boundParams.remove(bp);
- boundParams.add(bp );
- }
-
- /**
- *使用給出的對象設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param obj 包含參數值的對象
- *@param targetSqlType 參數的數據庫類型(常量定義在java.sql.Types中)
- *@param scale 精度,小數點后的位數
- * (只對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);
- }
-
- /**
- *使用給出的字符串設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param str 包含參數值的字符串
- */
- public void setString(int index, String str)throws SQLException{
- BoundParam bp = new BoundParam(index, str) ;
- boundParams.remove(bp);
- boundParams.add(bp);
- }
-
- /**
- *使用給出的字符串設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param timestamp 包含參數值的時間戳
- */
- public void setTimestamp(int index, Timestamp timestamp)throws SQLException{
- BoundParam bp = new BoundParam(index, timestamp) ;
- boundParams.remove(bp);
- boundParams.add( bp );
- }
-
- /**
- *使用給出的整數設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param value 包含參數值的整數
- */
- public void setInt(int index, int value)throws SQLException{
- BoundParam bp = new BoundParam(index, new Integer(value)) ;
- boundParams.remove(bp);
- boundParams.add( bp );
- }
-
- /**
- *使用給出的長整數設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param value 包含參數值的長整數
- */
- public void setLong(int index, long value)throws SQLException{
- BoundParam bp = new BoundParam(index, new Long(value)) ;
- boundParams.remove(bp);
- boundParams.add( bp );
- }
-
- /**
- *使用給出的雙精度浮點數設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param value 包含參數值的雙精度浮點數
- */
- public void setDouble(int index, double value)throws SQLException{
- BoundParam bp = new BoundParam(index, new Double(value)) ;
- boundParams.remove(bp);
- boundParams.add( bp);
- }
-
- /**
- *使用給出的BigDecimal設置指定參數的值
- *@param index 第一個參數為1,第二個為2,。。。
- *@param bd 包含參數值的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);
- }
- }
- }
-
-
-
- /**
- * 執行查詢取得一頁數據,執行結束后關閉數據庫連接
- * @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數據填充進CachedRowSet
- */
- protected abstract RowSet populate(ResultSet rs) throws SQLException;
-
- /**
- *取封裝成RowSet查詢結果
- *@return RowSet
- */
- public javax.sql.RowSet getRowSet(){
- return this.rowSet;
- }
-
-
- /**
- *取封裝成RowSetPage的查詢結果
- *@return RowSetPage
- */
- public RowSetPage getRowSetPage() {
- return this.rowSetPage;
- }
-
-
-
- /**
- *關閉數據庫連接
- */
- public void close(){
- //因為數據庫連接在查詢結束或發生異常時即關閉,此處不做任何事情
- //留待擴充。
- }
-
-
-
- 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數據庫實現</p>
- * <p>Copyright: Copyright (c) 2002</p>
- * @author evan_zhao@hotmail.com
- * @version 1.0
- */
- public class PagedStatementOracleImpl extends PagedStatement {
-
- /**
- * 構造一查詢出所有數據的PageStatement
- * @param sql query sql
- */
- public PagedStatementOracleImpl(String sql){
- super(sql);
- }
-
-
- /**
- * 構造一查詢出當頁數據的PageStatement
- * @param sql query sql
- * @param pageNo 頁碼
- */
- public PagedStatementOracleImpl(String sql, int pageNo){
- super(sql, pageNo);
- }
-
- /**
- * 構造一查詢出當頁數據的PageStatement,并指定每頁顯示記錄條數
- * @param sql query sql
- * @param pageNo 頁碼
- * @param pageSize 每頁容量
- */
- public PagedStatementOracleImpl(String sql, int pageNo, int pageSize){
- super(sql, pageNo, pageSize);
- }
-
-
- /**
- *生成查詢一頁數據的sql語句
- *@param sql 原查詢語句
- *@startIndex 開始記錄位置
- *@size 需要獲取的記錄數
- */
- 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數據填充進CachedRowSet
- */
- protected RowSet populate(ResultSet rs) throws SQLException{
- OracleCachedRowSet ocrs = new OracleCachedRowSet();
- ocrs.populate(rs);
- return ocrs;
- }
-
- }
相關連接:
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設計模式的一個示例程序。
|
|
評論人: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成員變量,會存在多線程問題 |
|
評論人: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 |
感覺用存儲過程實現分頁更高效 |
|
|
|