/**
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了崇陽(yáng)免費(fèi)建站歡迎大家使用!
*?分頁(yè)代碼
*?
*?@author?Star
*?@version?1.0?2008/07/08
*/
public?class?CutPage?implements?Serializable{
private?static?Log?log?=?LogFactory.getLog(CutPage.class);
private?int?curPageNo?=?0;?//?當(dāng)前頁(yè)數(shù),從0開始
private?int?size?=?0;?//?所有數(shù)據(jù)條數(shù)
private?String?url;?//?頁(yè)面跳轉(zhuǎn)的路徑
private?List?showList;?//?當(dāng)前頁(yè)面需要顯示的數(shù)據(jù)列表
private?int?pageSize?=?20;//?每頁(yè)顯示的數(shù)據(jù)條數(shù)
private?int?groupSize?=?1;//?多少頁(yè)為一組
private?String?pageNavigation;//?導(dǎo)航條
/**
?*?每次通過sql語(yǔ)句從數(shù)據(jù)庫(kù)里面分組取出需要顯示的數(shù)據(jù)
?*?
?*?@param?request
?*????????????javax.servlet.http.HttpServletRequest對(duì)象
?*?@param?sql
?*????????????String?查詢數(shù)據(jù)庫(kù)的sql語(yǔ)句
?*?@param?pageSize
?*????????????int?每頁(yè)顯示的條數(shù)
?*?@param?groupSize
?*????????????int?分成多少組
?*?@param?url
?*????????????String?頁(yè)面跳轉(zhuǎn)的路徑,若沒有特殊的參數(shù)傳遞,可以傳入null或"",
?*????????????如是在aciton里面調(diào)用,并且action是繼承自DispatherAction的話最好傳入完整的路徑
?*/
public?void?init(HttpServletRequest?request,?String?sql,?int?pageSize,
int?groupSize,?int?pageNo,?String?url)?{
//?上一頁(yè)、下一頁(yè)跳轉(zhuǎn)路徑
if?(url?!=?null)?{
this.url?=?url;
}?else?{
this.url?=?request.getRequestURL()?+?"";
}
if?(pageSize??0)
this.pageSize?=?pageSize;//?每頁(yè)多少條記錄
if?(groupSize??0)
this.groupSize?=?groupSize;
//?當(dāng)前第幾頁(yè)
if?(pageNo??0)?{
this.curPageNo?=?0;
}?else?{
this.curPageNo?=?pageNo;
}
int?curGroup?=?this.curPageNo?/?this.groupSize?+?1;
//?是否是新的一組數(shù)據(jù),如果是則到數(shù)據(jù)庫(kù)取數(shù)據(jù)
this.size?=?parseInt(request.getSession().getAttribute("page_all_size")
+?"",?0);
if?(this.curPageNo?%?this.groupSize?==?0
||?(request.getSession().getAttribute("cur_group")?!=?null??parseInt(
""?+?request.getSession().getAttribute("cur_group"),?1)?!=?curGroup)
||?this.size?==?0?||?request.getParameter("reload")?!=?null)?{
request.getSession().setAttribute("cur_group",?curGroup);
if?(pageNo??0
?request.getSession().getAttribute("page_sql")?!=?null)?{
sql?=?request.getSession().getAttribute("page_sql")?+?"";
}?else?{
request.getSession().setAttribute("page_sql",?sql);
}
this.size?=?getTotalCount(sql);
List?list?=?getPageData(sql,?(this.curPageNo?/?this.groupSize)
*?this.pageSize?*?this.groupSize,?this.pageSize
*?this.groupSize);
request.getSession().setAttribute("page_all_size",?this.size);
request.getSession().setAttribute("page_cur_list",?list);
this.setShowList(list);//?設(shè)置頁(yè)面上的顯示數(shù)據(jù)
}?else?{
this.setShowList((List)?request.getSession().getAttribute(
"page_cur_list"));//?設(shè)置頁(yè)面上的顯示數(shù)據(jù)
}
}
/**
?*?每次通過sql語(yǔ)句從數(shù)據(jù)庫(kù)里面分組取出需要顯示的數(shù)據(jù)
?*?
?*?@param?request
?*????????????javax.servlet.http.HttpServletRequest對(duì)象
?*?@param?sql
?*????????????String?查詢數(shù)據(jù)庫(kù)的sql語(yǔ)句
?*?@param?pageSize
?*????????????int?每頁(yè)顯示的條數(shù)
?*?@param?groupSize
?*????????????int?分成多少組
?*?@param?url
?*????????????String?頁(yè)面跳轉(zhuǎn)的路徑,若沒有特殊的參數(shù)傳遞,可以傳入null或"",
?*????????????如是在aciton里面調(diào)用,并且action是繼承自DispatherAction的話最好傳入完整的路徑
?*/
public?void?init(HttpServletRequest?request,?String?sql,?int?pageSize,
int?groupSize,?String?url)?{
//?當(dāng)前第幾頁(yè)
String?curPage?=?request.getParameter("pageNo");
init(request,?sql,?pageSize,?groupSize,?parseInt(curPage,?-1),?url);
}
/**
?*?每次通過sql語(yǔ)句從數(shù)據(jù)庫(kù)里面分組取出需要顯示的數(shù)據(jù)
?*?
?*?@param?request
?*????????????javax.servlet.http.HttpServletRequest對(duì)象
?*?@param?sql
?*????????????String?查詢數(shù)據(jù)庫(kù)的sql語(yǔ)句
?*?@param?pageSize
?*????????????int?每頁(yè)顯示的條數(shù)
?*?@param?groupSize
?*????????????int?分成多少組
?*?@param?url
?*????????????String?頁(yè)面跳轉(zhuǎn)的路徑,若沒有特殊的參數(shù)傳遞,可以傳入null或"",
?*????????????如是在aciton里面調(diào)用,并且action是繼承自DispatherAction的話最好傳入完整的路徑
?*/
public?void?init(HttpServletRequest?request,?String?sql,?int?pageSize,
int?groupSize,?int?pageNo)?{
init(request,?sql,?pageSize,?groupSize,?pageNo,?"");
}
太多了,貼不下,見附件
使用分頁(yè)類,直接調(diào)用就可以,代碼如下:
package com.godwin.news.util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
/**
* 分頁(yè)類,用于封閉分頁(yè)顯示信息
*
* @author javabs
*
*/
public class Pager {
// 當(dāng)前頁(yè)
private int currentPage;
// 總頁(yè)數(shù)
private int totalPage;
// 總記錄數(shù)
private int totalRecord;
// 每頁(yè)條數(shù)
private int pageSize;
// 是否有下一頁(yè)
private int hasNext;
private ArrayList keys;
private ArrayList values;
// 查詢串
private String queryString;
// 首頁(yè)
private String firstLink;
// 上一頁(yè)
private String previousLink;
// 下一頁(yè)
private String nextLink;
// 尾頁(yè)
private String lastLink;
// 鏈接
private String forScriptLink;
public Pager(int pageSize, String queryString) {
keys = new ArrayList();
values = new ArrayList();
setQueryString(queryString);
setPageSize(pageSize);
}
public String getForScriptLink() {
if (keys.contains("toPage"))
removeKey("toPage");
String tmp = getQueryString();
if (tmp.length() == 0)
return "?";
else
return "?" + tmp + "";
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(String toPage) {
int tmpage = 1;
try {
tmpage = Integer.parseInt(toPage);
} catch (NumberFormatException e) {
tmpage = 1;
}
if (tmpage 1)
tmpage = 1;
else if (tmpage getTotalPage())
tmpage = getTotalPage();
currentPage = tmpage;
}
public String getFirstLink() {
return getQueryStr(1);
}
public int getHasNext() {
int i = 1;
if (getCurrentPage() = getTotalPage())
i = 0;
return i;
}
public String getLastLink() {
return getQueryStr(getTotalPage());
}
public String getNextLink() {
return getQueryStr(currentPage == totalPage ? currentPage : (currentPage + 1));
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String getPreviousLink() {
return getQueryStr(currentPage == 1 ? currentPage : currentPage - 1);
}
public void setPreviousLink(String previousLink) {
this.previousLink = previousLink;
}
public String getQueryString() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i keys.size(); i++) {
String key = (String) keys.get(i);
String value = (String) values.get(i);
sb.append("");
sb.append(key);
sb.append("=");
sb.append(value);
}
return sb.delete(0, 1).toString();
}
public void setQueryString(String queryString) {
if (queryString != null) {
String s[] = queryString.split("");
for (int i = 0; i s.length; i++) {
String s1[] = s[i].split("=");
if (s1.length == 2) {
keys.add(s1[0]);
values.add(s1[1]);
} else {
keys.add(s1[0]);
values.add("");
}
}
}
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage() {
if (totalRecord % pageSize == 0) {
totalPage = totalRecord / pageSize;
totalPage = totalPage == 0 ? 1 : totalPage;
}
else
totalPage = totalRecord / pageSize + 1;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
setTotalPage();
}
public String[] getQueryParameterValues(String key) {
return getQueryParameterValues(key, "UTF-8");
}
public String[] getQueryParameterValues(String key, String decode) {
ArrayList ret = new ArrayList();
for (int i = 0; i keys.size(); i++)
if (((String) keys.get(i)).equals(key))
try {
ret.add(URLDecoder.decode((String) values.get(i), decode));
} catch (UnsupportedEncodingException e) {
ret.add((String) values.get(i));
}
if (ret.size() == 0)
return null;
String strArr[] = new String[ret.size()];
for (int i = 0; i ret.size(); i++)
strArr[i] = (String) ret.get(i);
return strArr;
}
public String getQueryParameter(String key) {
return getQueryParameter(key, "UTF-8");
}
public String getQueryParameter(String key, String decode) {
String value = "";
if (key != "toPage") {
try {
value = URLDecoder.decode(getValue(key), decode);
} catch (UnsupportedEncodingException e) {
value = getValue(key);
}
} else {
int tmpage = 1;
try {
value = getValue(key);
tmpage = Integer.parseInt(value);
} catch (NumberFormatException e) {
tmpage = 1;
} catch (NullPointerException e1) {
tmpage = 1;
}
if (tmpage 1)
tmpage = 1;
else if (tmpage getTotalPage())
tmpage = getTotalPage();
value = (new StringBuffer(String.valueOf(tmpage))).toString();
}
return value;
}
public void setQueryParameter(String key, String value) {
if (key.equals("toPage"))
removeKey(key);
keys.add(key);
values.add(value);
}
public String getQueryStr(int toPage) {
setQueryParameter("toPage", (new StringBuffer(String.valueOf(toPage))).toString());
return "?" + getQueryString();
}
private String getValue(String key) {
String ret = "";
for (int i = 0; i keys.size(); i++) {
if (!((String) keys.get(i)).equals(key))
continue;
ret = (String) values.get(i);
break;
}
return ret;
}
private void removeKey(String key) {
for (int i = 0; i keys.size(); i++) {
if (!((String) keys.get(i)).equals(key))
continue;
keys.remove(i);
values.remove(i);
break;
}
}
public static void main(String args[]) {
String str = "a=中文aab=2c=3c=4c=5";
Pager page = new Pager(2, str);
page.setTotalRecord(10);
page.setCurrentPage("1");
System.out.println(page.getFirstLink());
System.out.println(page.getPreviousLink());
System.out.println(page.getNextLink());
System.out.println(page.getLastLink());
String s = page.getQueryParameter("a");
System.out.println("s: " + s);
}
}
數(shù)據(jù)庫(kù) 分頁(yè)的查詢語(yǔ)句為 select top pageSize * from objectTable obj where obj.id not in(select top (pageNumber-1)*pageSize id from objectTable) 然后將查詢結(jié)果放到一個(gè)List集合中 返回回去。在頁(yè)面進(jìn)行顯示就可以了。但注意的是頁(yè)面要控制好當(dāng)前頁(yè)碼。 pageSize: 每頁(yè)顯示的信息條數(shù)、pageNumber:當(dāng)前頁(yè)碼
實(shí)現(xiàn)原理很簡(jiǎn)單,就是建立一個(gè)Page類,里面放當(dāng)前訪問的頁(yè)數(shù)和每一頁(yè)顯示的記錄行數(shù)。然后通過分頁(yè)計(jì)算就可以得出下列數(shù)據(jù)。
總頁(yè)數(shù) = 總記錄數(shù)/每頁(yè)大小,如果0!=總記錄數(shù)%每頁(yè)大小,那么總頁(yè)數(shù)再+1。
當(dāng)前頁(yè)數(shù)。
表記錄的起始位置=(當(dāng)前頁(yè)數(shù)-1)*每頁(yè)大小。
總記錄數(shù)(select count(*) from [表名] [where [條件]]。從數(shù)據(jù)庫(kù)中查詢得到)
每頁(yè)大小,可以固定,也可以從頁(yè)面?zhèn)鬟^來有了這幾個(gè)參數(shù)之后,就用sql語(yǔ)句查出對(duì)應(yīng)的記錄就可以了。
Java是一種可以撰寫跨平臺(tái)應(yīng)用程序的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言。
Java?技術(shù)具有卓越的通用性、高效性、平臺(tái)移植性和安全性,廣泛應(yīng)用于PC、數(shù)據(jù)中心、游戲控制臺(tái)、科學(xué)超級(jí)計(jì)算機(jī)、移動(dòng)電話和互聯(lián)網(wǎng),同時(shí)擁有全球最大的開發(fā)者專業(yè)社群。
它最初被命名為Oak,目標(biāo)設(shè)定在家用電器等小型系統(tǒng)的編程語(yǔ)言,來解決諸如電視機(jī)、電話、鬧鐘、烤面包機(jī)等家用電器的控制和通訊問題。
由于這些智能化家電的市場(chǎng)需求沒有預(yù)期的高,Sun放棄了該項(xiàng)計(jì)劃。就在Oak幾近失敗之時(shí),隨著互聯(lián)網(wǎng)的發(fā)展,Sun看到了Oak在計(jì)算機(jī)網(wǎng)絡(luò)上的廣闊應(yīng)用前景,于是改造了Oak,以“Java”的名稱正式發(fā)布。
Java的主要工作是通過編程語(yǔ)言來制作互聯(lián)網(wǎng)頁(yè)面、制作動(dòng)態(tài)效果以及網(wǎng)站等技術(shù)。
package dl.wsxx.base;
public class Pager {
private int totalRows; // 總行數(shù)
private int pageSize; // 每頁(yè)顯示的行數(shù)
private int currentPage; // 當(dāng)前頁(yè)號(hào)
private int totalPages; // 總頁(yè)數(shù)
private int startRow; // 當(dāng)前頁(yè)在數(shù)據(jù)庫(kù)中的起始行
private int pageStartRow; // 當(dāng)前頁(yè)開始行
private int pageEndRow; // 當(dāng)前頁(yè)結(jié)束行
private int hasNextPage; // 下一頁(yè)存在標(biāo)識(shí)[0:不存在,1:存在]
private int hasPreviousPage; // 前一頁(yè)存在標(biāo)識(shí)[0:不存在,1:存在]
public Pager() {
}
public Pager(int _totalRows,int _pageSize) {
pageSize = _pageSize;
totalRows = _totalRows;
totalPages = totalRows / pageSize;
int mod = totalRows % pageSize;
if (mod 0) {
totalPages++;
}
currentPage = 1;
startRow = 0;
}
public int getStartRow() {
return startRow;
}
public int getpageStartRow() {
return pageStartRow;
}
public int getpageEndRow() {
return pageEndRow;
}
public int getTotalPages() {
return totalPages;
}
public int getCurrentPage() {
return currentPage;
}
public int getPageSize() {
return pageSize;
}
public int getHasNextPage() {
return hasNextPage;
}
public int getHasPreviousPage() {
return hasPreviousPage;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public void setPageStartRow(int pageStartRow) {
this.pageStartRow = pageStartRow;
}
public void setPageEndRow(int pageEndRow) {
this.pageEndRow = pageEndRow;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setHasNextPage(int hasNextPage) {
this.hasNextPage = hasNextPage;
}
public void setHasPreviousPage(int hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public int getTotalRows() {
return totalRows;
}
public void first() {
currentPage = 1;
startRow = 0;
pageStartRow = startRow + 1;
this.hasFlagSet(currentPage, totalPages);
if (this.hasNextPage == 0) {
pageEndRow = totalRows;
} else {
pageEndRow = startRow + pageSize;
}
}
public void previous() {
if (currentPage == 1) {
return;
}
currentPage--;
startRow = (currentPage - 1) * pageSize;
pageStartRow = startRow + 1;
this.hasFlagSet(currentPage, totalPages);
if (this.hasNextPage == 0) {
pageEndRow = totalRows;
} else {
pageEndRow = startRow + pageSize;
}
}
public void next() {
if (currentPage totalPages) {
currentPage++;
}
startRow = (currentPage - 1) * pageSize;
pageStartRow = startRow + 1;
this.hasFlagSet(currentPage, totalPages);
if (this.hasNextPage == 0) {
pageEndRow = totalRows;
} else {
pageEndRow = startRow + pageSize;
}
}
public void last() {
currentPage = totalPages;
startRow = (currentPage - 1) * pageSize;
pageStartRow = startRow + 1;
this.hasFlagSet(currentPage, totalPages);
if (this.hasNextPage == 0) {
pageEndRow = totalRows;
} else {
pageEndRow = startRow + pageSize;
}
}
public void refresh(int _currentPage) {
currentPage = _currentPage;
if (currentPage totalPages) {
last();
}
this.hasFlagSet(currentPage, totalPages);
}
private void hasFlagSet(int currentPage, int totalPages) {
if (currentPage == totalPages) {
if (currentPage == 1) {
this.hasPreviousPage = 0;
this.hasNextPage = 0;
} else {
this.hasPreviousPage = 1;
this.hasNextPage = 0;
}
} else {
if (currentPage == 1) {
this.hasPreviousPage = 0;
this.hasNextPage = 1;
} else {
this.hasPreviousPage = 1;
this.hasNextPage = 1;
}
}
}
}
這是我的工程里的分頁(yè)核心代碼,希望對(duì)你有用,還有ssh分頁(yè)文檔,可以參照研究一下。
一個(gè)簡(jiǎn)單的JAVA分頁(yè)方法
定義兩個(gè)Vector,一個(gè)為儲(chǔ)存查詢所有記錄的totalV,另一個(gè)儲(chǔ)存當(dāng)前頁(yè)的記錄currentPageV;
總的記錄數(shù):int totalSize = totalV.getSize();
每頁(yè)顯示的記錄數(shù):int countPerPage;
總頁(yè)數(shù):int totalPageNum = totalSize/countPerPage;
//如果總的記錄數(shù)和每頁(yè)記錄數(shù)的余數(shù)大于零,
//那么總的頁(yè)數(shù)為他們的整除結(jié)果加一
if (totalSize%countPerPage 0 ){
totalPageNum = totalSize/countPerPage + 1;
}
當(dāng)前的頁(yè)數(shù):pageNum;
for (int j = 0;jtotalV.size();j++){
//分頁(yè),根據(jù)當(dāng)前的頁(yè)數(shù)和每頁(yè)顯示的記錄數(shù)從totalV中取出記錄
//往currentPageV中添加記錄;
//如果當(dāng)前記錄在(當(dāng)前頁(yè)碼-1)*每頁(yè)顯示記錄數(shù)(包括等于)
//和 當(dāng)前頁(yè)碼*每頁(yè)顯示記錄數(shù)(不包括等于)之間的時(shí)候;
//就屬于該頁(yè)的數(shù)據(jù)
if ( (j = (pageNum - 1) * countPerPage) (j pageNum * countPerPage)) {
currentPageV.addElement(totalV.get(j));
}
//當(dāng)currentPageV記錄數(shù)等于每頁(yè)顯示記錄數(shù),
//停止往currentPageV中添加記錄
if (currentPageV.size() == countPerPage) {
break;
}
}
那么,當(dāng)前頁(yè)中顯示的記錄,就是currentPageV中的記錄。
第二個(gè)分頁(yè)
在使用數(shù)據(jù)庫(kù)的過程中,不可避免的需要使用到分頁(yè)的功能,可是JDBC的規(guī)范對(duì)此卻沒有很好的解決。對(duì)于這個(gè)需求很多朋友都有自己的解決方案,比如使用Vector等集合類先保存取出的數(shù)據(jù)再分頁(yè)。但這種方法的可用性很差,與JDBC本身的接口完全不同,對(duì)不同類型的字段的支持也不好。這里提供了一種與JDBC兼容性非常好的方案。
JDBC和分頁(yè)
Sun的JDBC規(guī)范的制定,有時(shí)很讓人哭笑不得,在JDBC1.0中,對(duì)于一個(gè)結(jié)果集(ResultSet)你甚至只能執(zhí)行next()操作,而無法讓其向后滾動(dòng),這就直接導(dǎo)致在只執(zhí)行一次SQL查詢的情況下無法獲得結(jié)果集的大小。所以,如果你使用的是JDBC1.0的驅(qū)動(dòng),那么是幾乎無法實(shí)現(xiàn)分頁(yè)的。
好在Sun的JDBC2規(guī)范中很好的彌補(bǔ)了這一個(gè)不足,增加了結(jié)果集的前后滾動(dòng)操作,雖然仍然不能直接支持分頁(yè),但我們已經(jīng)可以在這個(gè)基礎(chǔ)上寫出自己的可支持分頁(yè)的ResultSet了。
和具體數(shù)據(jù)庫(kù)相關(guān)的實(shí)現(xiàn)方法
有一些數(shù)據(jù)庫(kù),如Mysql, Oracle等有自己的分頁(yè)方法,比如Mysql可以使用limit子句,Oracle可以使用ROWNUM來限制結(jié)果集的大小和起始位置。這里以Mysql為例,其典型代碼如下:
// 計(jì)算總的記錄條數(shù)
String SQL = "SELECT Count(*) AS total " + this.QueryPart;
rs = db.executeQuery(SQL);
if (rs.next())
Total = rs.getInt(1);
// 設(shè)置當(dāng)前頁(yè)數(shù)和總頁(yè)數(shù)
TPages = (int)Math.ceil((double)this.Total/this.MaxLine);
CPages = (int)Math.floor((double)Offset/this.MaxLine+1);
// 根據(jù)條件判斷,取出所需記錄
if (Total 0) {
SQL = Query + " LIMIT " + Offset + " , " + MaxLine;
rs = db.executeQuery(SQL);
}
return rs;
}
毫無疑問,這段代碼在數(shù)據(jù)庫(kù)是Mysql時(shí)將會(huì)是漂亮的,但是作為一個(gè)通用的類(事實(shí)上我后面要提供的就是一個(gè)通用類庫(kù)中的一部分),需要適應(yīng)不同的數(shù)據(jù)庫(kù),而基于這個(gè)類(庫(kù))的應(yīng)用,也可能使用不同的數(shù)據(jù)庫(kù),所以,我們將不使用這種方法。
另一種繁瑣的實(shí)現(xiàn)方法
我看過一些人的做法(事實(shí)上包括我在內(nèi),一開始也是使用這種方法的),即不使用任何封裝,在需要分頁(yè)的地方,直接操作ResultSet滾到相應(yīng)的位置,再讀取相應(yīng)數(shù)量的記錄。其典型代碼如下:
%
sqlStmt = sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
java.sql.ResultSet.CONCUR_READ_ONLY);
strSQL = "select name,age from test";
//執(zhí)行SQL語(yǔ)句并獲取結(jié)果集
sqlRst = sqlStmt.executeQuery(strSQL);
//獲取記錄總數(shù)
sqlRst.last();
intRowCount = sqlRst.getRow();
//記算總頁(yè)數(shù)
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//調(diào)整待顯示的頁(yè)碼
if(intPageintPageCount) intPage = intPageCount;
%
table border="1" cellspacing="0" cellpadding="0"
tr
th姓名/th
th年齡/th
/tr
%
if(intPageCount0){
//將記錄指針定位到待顯示頁(yè)的第一條記錄上
sqlRst.absolute((intPage-1) * intPageSize + 1);
//顯示數(shù)據(jù)
i = 0;
while(iintPageSize !sqlRst.isAfterLast()){
%
tr
td%=sqlRst.getString(1)%/td
td%=sqlRst.getString(2)%/td
/tr
%
sqlRst.next();
i++;
}
}
%
/table
很顯然,這種方法沒有考慮到代碼重用的問題,不僅代碼數(shù)量巨大,而且在代碼需要修改的情況下,將會(huì)無所適從。
使用Vector進(jìn)行分頁(yè)
還見過另一些實(shí)現(xiàn)分頁(yè)的類,是先將所有記錄都select出來,然后將ResultSet中的數(shù)據(jù)都get出來,存入Vector等集合類中,再根據(jù)所需分頁(yè)的大小,頁(yè)數(shù),定位到相應(yīng)的位置,讀取數(shù)據(jù)?;蛘呦仁褂们懊嫣岬降膬煞N分頁(yè)方法,取得所需的頁(yè)面之后,再存入Vector中。
扔開代碼的效率不說,單是從程序結(jié)構(gòu)和使用的方便性上講,就是很糟糕的。比如,這種做法支持的字段類型有限,int, double, String類型還比較好處理,如果碰到Blob, Text等類型,實(shí)現(xiàn)起來就很麻煩了。這是一種更不可取的方案。
一個(gè)新的Pageable接口及其實(shí)現(xiàn)
很顯然,看過上面三種實(shí)現(xiàn)方法后,我們對(duì)新的分頁(yè)機(jī)制有了一個(gè)目標(biāo),即:不與具體數(shù)據(jù)庫(kù)相關(guān);盡可能做到代碼重用;盡可能與原JDBC接口的使用方法保持一致;盡可能高的效率。
首先,我們需要提供一個(gè)與java.sql.ResultSet向下兼容的接口,把它命名為Pageable,接口定義如下:
public interface Pageable extends java.sql.ResultSet{
/**返回總頁(yè)數(shù)
*/
int getPageCount();
/**返回當(dāng)前頁(yè)的記錄條數(shù)
*/
int getPageRowsCount();
/**返回分頁(yè)大小
*/
int getPageSize();
/**轉(zhuǎn)到指定頁(yè)
*/
void gotoPage(int page) ;
/**設(shè)置分頁(yè)大小
*/
void setPageSize(int pageSize);
/**返回總記錄行數(shù)
*/
int getRowsCount();
/**
* 轉(zhuǎn)到當(dāng)前頁(yè)的第一條記錄
* @exception java.sql.SQLException 異常說明。
*/
void pageFirst() throws java.sql.SQLException;
/**
* 轉(zhuǎn)到當(dāng)前頁(yè)的最后一條記錄
* @exception java.sql.SQLException 異常說明。
*/
void pageLast() throws java.sql.SQLException;
/**返回當(dāng)前頁(yè)號(hào)
*/
int getCurPage();
}
這是一個(gè)對(duì)java.sql.ResultSet進(jìn)行了擴(kuò)展的接口,主要是增加了對(duì)分頁(yè)的支持,如設(shè)置分頁(yè)大小,跳轉(zhuǎn)到某一頁(yè),返回總頁(yè)數(shù)等等。
接著,我們需要實(shí)現(xiàn)這個(gè)接口,由于這個(gè)接口繼承自ResultSet,并且它的大部分功能也都和ResultSet原有功能相同,所以這里使用了一個(gè)簡(jiǎn)單的Decorator模式。
PageableResultSet2的類聲明和成員聲明如下:
public class PageableResultSet2 implements Pageable {
protected java.sql.ResultSet rs=null;
protected int rowsCount;
protected int pageSize;
protected int curPage;
protected String command = "";
}
可以看到,在PageableResultSet2中,包含了一個(gè)ResultSet的實(shí)例(這個(gè)實(shí)例只是實(shí)現(xiàn)了ResultSet接口,事實(shí)上它是由各個(gè)數(shù)據(jù)庫(kù)廠商分別實(shí)現(xiàn)的),并且把所有由ResultSet繼承來的方法都直接轉(zhuǎn)發(fā)給該實(shí)例來處理。
PageableResultSet2中繼承自ResultSet的主要方法:
//……
public boolean next() throws SQLException {
return rs.next();
}
//……
public String getString(String columnName) throws SQLException {
try {
return rs.getString(columnName);
}
catch (SQLException e) {//這里是為了增加一些出錯(cuò)信息的內(nèi)容便于調(diào)試
throw new SQLException (e.toString()+" columnName="
+columnName+" SQL="+this.getCommand());
}
}
//……
只有在Pageable接口中新增的方法才需要自己的寫方法處理。
/**方法注釋可參考Pageable.java
*/
public int getCurPage() {
return curPage;
}
public int getPageCount() {
if(rowsCount==0) return 0;
if(pageSize==0) return 1;
//calculate PageCount
double tmpD=(double)rowsCount/pageSize;
int tmpI=(int)tmpD;
if(tmpDtmpI) tmpI++;
return tmpI;
}
public int getPageRowsCount() {
if(pageSize==0) return rowsCount;
if(getRowsCount()==0) return 0;
if(curPage!=getPageCount()) return pageSize;
return rowsCount-(getPageCount()-1)*pageSize;
}
public int getPageSize() {
return pageSize;
}
public int getRowsCount() {
return rowsCount;
}
public void gotoPage(int page) {
if (rs == null)
return;
if (page 1)
page = 1;
if (page getPageCount())
page = getPageCount();
int row = (page - 1) * pageSize + 1;
try {
rs.absolute(row);
curPage = page;
}
catch (java.sql.SQLException e) {
}
}
public void pageFirst() throws java.sql.SQLException {
int row=(curPage-1)*pageSize+1;
rs.absolute(row);
}
public void pageLast() throws java.sql.SQLException {
int row=(curPage-1)*pageSize+getPageRowsCount();
rs.absolute(row);
}
public void setPageSize(int pageSize) {
if(pageSize=0){
this.pageSize=pageSize;
curPage=1;
}
}
//PageableResultSet2的構(gòu)造方法:
public PageableResultSet2(java.sql.ResultSet rs) throws java.sql.SQLException {
if(rs==null) throw new SQLException("given ResultSet is NULL","user");
rs.last();
rowsCount=rs.getRow();
rs.beforeFirst();
this.rs=rs;
}
/*如果要提高效率,可以利用select count(*) 語(yǔ)句取得所有記錄數(shù),注釋掉
構(gòu)造函數(shù)的rs.last();rowsCount=rs.getRow();rs.beforeFirst();三句。
在調(diào)用構(gòu)造函數(shù)后調(diào)用此方法獲得所有的記錄,參數(shù)是select count(*)后的結(jié)果集
*/
public void setRowsCount(java.sql.ResultSet rs)throws java.sql.SQLException {
if(rs==null) throw new SQLException("given ResultSet is NULL","user");
rowCount=rs.getInt(1);
}
這里只是簡(jiǎn)單的取得一個(gè)總記錄數(shù),并將記錄游標(biāo)移回初始位置(before first),同時(shí)將參數(shù)中的ResultSet賦給成員變量。
Pageable的使用方法
因?yàn)镻ageable接口繼承自ResultSet,所以在使用方法上與ResultSet一致,尤其是在不需要分頁(yè)功能的時(shí)候,可以直接當(dāng)成ResultSet使用。而在需要分頁(yè)時(shí),只需要簡(jiǎn)單的setPageSize, gotoPage,即可。
PreparedStatement pstmt=null;
Pageable rs=null;
……//構(gòu)造SQL,并準(zhǔn)備一個(gè)pstmt.
rs=new PageableResultSet2(pstmt.executeQuery());//構(gòu)造一個(gè)Pageable
rs.setPageSize(20);//每頁(yè)20個(gè)記錄
rs.gotoPage(2);//跳轉(zhuǎn)到第2頁(yè)
for(int i=0; irs.getPageRowsCount(); i++){//循環(huán)處理
int id=rs.getInt(“ID”);
……//繼續(xù)處理
rs.next();
}
總結(jié)
一個(gè)好的基礎(chǔ)類應(yīng)該是便于使用,并且具備足夠的可移植性,同時(shí)要保證其功能的完善。在上面的實(shí)現(xiàn)中,我們從java.sql.ResultSet接口繼承出Pageable,并實(shí)現(xiàn)了它。這就保證了在使用中與JDBC原有操作的一致性,同時(shí)對(duì)原有功能沒有縮減。
同時(shí)它也是易于使用的,因?yàn)榉庋b了一切必要的操作,所以在你的代碼中唯一顯得"難看"和"不舒服"的地方就是需要自己去構(gòu)造一個(gè)PageableResultSet2。不過只要你愿意,這也是可以解決的。
當(dāng)然它也有具有充分的可移植性,當(dāng)你將數(shù)據(jù)庫(kù)由Oracle變?yōu)镸ysql或者SQLServer的時(shí)候,你仍然可以使用這些分頁(yè)的代碼。它在使用中(或者說在移植的過程中)唯一的限制就是你必須要使用一個(gè)支持JDBC2的驅(qū)動(dòng)(現(xiàn)在明白為什么我把類命名為PageableResultSet2了吧。:P),不過,好在JDBC2已經(jīng)成為標(biāo)準(zhǔn)了,絕大多數(shù)的數(shù)據(jù)庫(kù)(如Oracle, Mysql, SQLServer)都有自己的或者第三方提供的JDBC2的驅(qū)動(dòng)。
OK,這個(gè)分頁(yè)的實(shí)現(xiàn)是否對(duì)你的編程有幫助呢?仔細(xì)看看,其實(shí)真正自己寫的代碼并不多的,大部分都只是簡(jiǎn)單的轉(zhuǎn)發(fā)操作。一個(gè)合適的模式應(yīng)用可以幫你很大忙。
這里只是簡(jiǎn)單的取得一個(gè)總記錄數(shù),并將記錄游標(biāo)移回初始位置(before first),同時(shí)將參數(shù)中的ResultSet賦給成員變量。
文章題目:java分頁(yè)代碼封裝 分頁(yè)Java
本文地址:http://muchs.cn/article18/hhidgp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、標(biāo)簽優(yōu)化、微信公眾號(hào)、網(wǎng)站內(nèi)鏈、App開發(fā)、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容