當前位置:遊戲中心平台 - 頁遊排行榜 - 如何使用分頁顯示

如何使用分頁顯示

目前最好的JSP分頁技術

在使用數據庫的過程中,不可避免地要使用分頁功能,但是JDBC規範並沒有很好地解決這個問題。對於這種需求,很多朋友都有自己的解決方案,比如使用Vector之類的集合類在分頁之前保存取來的數據。但是這種方法的可用性很差,和JDBC自己的界面完全不壹樣,對不同類型的字段支持也很差。這裏有壹個與JDBC兼容的非常好的解決方案。

JDBC和尋呼

孫的規範的提法有時讓人哭笑不得。在JDBC1.0中,只能對壹個ResultSet執行next()操作,而不能使其向後滾動,直接導致只執行壹次SQL查詢就無法獲得結果集的大小。所以如果使用JDBC1.0驅動,幾乎不可能實現分頁。

好在Sun的JDBC2規範很好的彌補了這個不足,增加了ResultSet的前後滾動操作。雖然我們仍然不能直接支持分頁,但我們已經可以在此基礎上編寫自己的支持分頁的ResultSet。

與特定數據庫相關的實現方法

有些數據庫,比如Mysql,Oracle,都有自己的分頁方法。例如,Mysql可以使用limit子句,Oracle可以使用ROWNUM來限制結果集的大小和起始位置。這裏以Mysql為例,其典型代碼如下:

//計算記錄總數。

string SQL = " SELECT Count(*)AS total "+this。QueryPart

RS = db . execute query(SQL);

if (rs.next())

total = RS . getint(1);

//設置當前頁碼和總頁碼。

t pages =(int)math . ceil((double)this。總計/本。MaxLine);

c pages =(int)math . floor((double)Offset/this。MaxLine+1);

//根據條件,取出需要的記錄。

if(總計& gt0) {

SQL = Query + " LIMIT " + Offset +","+MaxLine;

RS = db . execute query(SQL);

}

返回RS;

}

毫無疑問,這個代碼在數據庫是Mysql的情況下會很漂亮,但是作為壹個通用類(其實我後面提供的是壹個通用類庫的壹部分),它需要適應不同的數據庫,基於這個類(庫)的應用也可能使用不同的數據庫,所以我們不會用這個方法。

另壹個繁瑣的實現方法

我見過有人這麽做的(其實包括我在內,壹開始也是用這種方法),就是不使用任何封裝,直接操作ResultSet滾動到需要分頁的對應位置,然後讀取對應的記錄數。其典型代碼如下:

& lt%

sqlStmt = sqlcon . create statement(Java . SQL . resultset . type _ SCROLL _ INSENSITIVE,

Java . SQL . resultset . concur _ READ _ ONLY);

strSQL = "從測試中選擇姓名、年齡";

//執行SQL語句,得到結果集。

sqlRst = sqlstmt . execute query(strSQL);

//獲取記錄總數

sqlrst . last();

intRowCount = SQL rst . getrow();

//統計總頁數

int pagecount =(intRowCount+int pagesize-1)/int pagesize;

//調整要顯示的頁碼

if(int page & gt;int page count)int page = int page count;

% & gt

& lttable border = " 1 " cellspacing = " 0 " cell padding = " 0 " >

& lttr & gt

& ltth & gt名字

& ltth & gt年齡

& lt/tr & gt;

& lt%

if(int page count & gt;0){

//將記錄指針定位在要顯示的頁面的第壹條記錄上。

sqlrst . absolute((int page-1)* int pagesize+1);

//顯示數據

I = 0;

而(我& ltintPageSize & amp& amp!sqlRst.isAfterLast()){

% & gt

& lttr & gt

& lttd & gt& lt% = SQL rst . getstring(1)% & gt;& lt/TD & gt;

& lttd & gt& lt% = SQL rst . getstring(2)% & gt;& lt/TD & gt;

& lt/tr & gt;

& lt%

sqlrst . next();

i++;

}

}

% & gt

& lt/table & gt;

顯然,這種方法沒有考慮到代碼重用的問題。不僅代碼量巨大,在需要修改代碼的時候也會手足無措。

使用向量分頁

我也見過其他實現分頁的類,就是先選擇所有記錄,然後獲取ResultSet中的所有數據,存儲在Vector等集合類中,再根據需要的分頁大小和頁數將數據定位到相應的位置。或者使用上面提到的兩種分頁方法,在Vector中存儲之前獲取所需的頁面。

拋開代碼的效率不說,從程序結構和使用的便利性來說都是非常糟糕的。比如這種方法支持的字段類型有限,int、double、String類型相對容易處理。如果遇到Blob、Text之類的類型,實現起來會很麻煩。這是壹個更不可取的方案。

壹種新的可分頁接口及其實現

顯然,看了以上三種實現方法,我們對於新的分頁機制有了壹個目標,那就是與具體的數據庫無關;盡可能復用代碼;盡可能與原JDBC界面保持壹致;盡可能高效。

首先我們需要提供壹個java.sql.ResultSet向後兼容的接口,命名為Pageable。該接口定義如下:

公共接口Pageable擴展java.sql.ResultSet{

/* *返回總頁數。

*/

int getpage count();

/* *返回當前頁面中的記錄數。

*/

int getPageRowsCount();

/* *返回頁面大小。

*/

int get pagesize();

/* *轉到指定頁面

*/

void gotoPage(int page);

/* *設置分頁大小

*/

void setPageSize(int pageSize);

/* *返回記錄行的總數。

*/

int getRowsCount();

/**

*轉到當前頁面的第壹條記錄。

* @ exception Java . SQL . SQL exception異常描述。

*/

void pageFirst()拋出Java . SQL . SQL exception;

/**

*轉到當前頁面的最後壹條記錄。

* @ exception Java . SQL . SQL exception異常描述。

*/

void pageLast()拋出Java . SQL . SQL exception;

/* *返回當前頁碼。

*/

int getCurPage();

}

這是壹個擴展java.sql.ResultSet的接口,主要是增加了對分頁的支持,比如設置分頁大小,跳轉到壹個頁面,返回總頁數等等。

然後,我們需要實現這個接口,因為這個接口繼承自ResultSet,它的大部分函數與ResultSet的原始函數相同,所以這裏使用了壹個簡單的Decorator模式。

PageableResultSet2的類聲明和成員聲明如下:

公共類PageableResultSet2實現Pageable {

受保護的Java . SQL . resultset RS = null;

受保護的int rowsCount

受保護的int pageSize

受保護的int curPage

受保護的字符串命令= " ";

}

可以看到PageableResultSet2包含了ResultSet的壹個實例(這個實例只實現了ResultSet接口,實際上是各種數據庫廠商實現的),所有從ResultSet繼承的方法都直接轉發到這個實例進行處理。

PageableResultSet2中從ResultSet繼承的主要方法:

//……

public boolean next()拋出SQLException {

返回RS . next();

}

//……

公共字符串getString(String columnName)引發SQLException {

嘗試{

返回RS . getstring(column name);

}

Catch (SQLException e) {//這是為了調試增加壹些錯誤信息。

拋出新的SQLException(e . tostring()+" column name = "

+column name+" SQL = "+this . get command());

}

}

//……

只有可分頁接口中新添加的方法才需要用自己的編寫方法來處理。

/* *有關方法說明,請參考Pageable.java。

*/

public int getCurPage() {

返回curPage

}

public int getPageCount() {

if(rowsCount==0)返回0;

if(pageSize==0)返回1;

//計算頁面計數

double tmpD =(double)rows count/pageSize;

int tmpI =(int)tmpD;

if(tmpD & gt;tmpI)tmpi++;

返回tmpI

}

public int getPageRowsCount() {

if(pageSize==0)返回rowsCount

if(getRowsCount()==0)返回0;

如果(curPage!=getPageCount())返回pageSize

return rows count-(getPageCount()-1)* pageSize;

}

public int getPageSize() {

返回pageSize

}

public int getRowsCount() {

返回rowsCount

}

public void gotoPage(int page) {

if (rs == null)

返回;

如果(page & lt1)

page = 1;

如果(第頁& gtgetPageCount())

page = getpage count();

int row =(page-1)* pageSize+1;

嘗試{

RS . absolute(row);

curPage = page

}

catch (java.sql.SQLException e) {

}

}

public void pageFirst()拋出java.sql.SQLException {

int row =(cur page-1)* pageSize+1;

RS . absolute(row);

}

public void pageLast()拋出java.sql.SQLException {

int row =(cur page-1)* pageSize+getPageRowsCount();

RS . absolute(row);

}

public void setPageSize(int pageSize){

if(pageSize & gt;=0){

this.pageSize = pageSize

cur page = 1;

}

}

PageableResultSet2的構造方法:

public pageable resultset 2(Java . SQL . resultset RS)拋出java.sql.SQLException {

if(rs==null)拋出新的SQLException("給定結果集為null ","用戶");

RS . last();

rows count = RS . getrow();

RS . before first();

this.rs = rs

}

在這裏,我們簡單地獲取記錄總數,將記錄光標移回原始位置(在first之前),並將參數中的結果集賦給成員變量。

如何使用可分頁

由於Pageable接口繼承自ResultSet,所以在用法上與ResultSet壹致,尤其是不需要分頁函數時,可以直接作為ResultSet使用。需要分頁的時候,只需要壹個簡單的setPageSize,gotoPage。

PreparedStatement pstmt = null

可分頁rs = null

.....//構造SQL,準備壹個pstmt。

RS = new pageableresultset 2(pstmt . execute query());//構造可分頁的

RS . setpagesize(20);//每頁20條記錄

RS . goto page②;//跳轉到第2頁

for(int I = 0;我& ltRS . getpagerowscount();I++){//循環處理

int ID = RS . getint(" ID ");

.....//繼續處理

}

摘要

壹個好的基礎類應該是易用的,有足夠的可移植性,同時保證功能的完善。在上面的實現中,我們從java.sql.ResultSet接口繼承了Pageable並實現了它。這樣既保證了使用中與JDBC原有操作的壹致性,同時又不降低原有功能。

同時,它很容易使用,因為它封裝了所有必要的操作,所以在妳的代碼中唯壹顯得“醜陋”和“不舒服”的是妳需要自己構造壹個PageableResultSet2。但是如果妳想的話是可以解決的。

當然,它也是完全便攜的。當您將數據庫從Oracle更改為Mysql或SQLServer時,仍然可以使用這些分頁代碼。它在使用中(或者在移植過程中)唯壹的限制就是妳必須使用壹個支持JDBC2的驅動程序(現在看看我為什麽把這個類命名為PageableResultSet2)。:p),不過好在JDBC2已經成為標準,大部分數據庫(如Oracle、Mysql、SQLServer)都有自己的JDBC2驅動或者第三方提供的驅動。

好了,這個分頁的實現對妳的編程有幫助嗎?仔細壹看,其實自己寫的代碼並不多,大部分只是簡單的轉發操作。壹個合適的模式應用可以幫到妳很多。

  • 上一篇:摩爾莊園的漿果叢林怎麽上樹?
  • 下一篇:cf手遊閃回解決方案
  • copyright 2024遊戲中心平台