JSP分页技术实现.docx

上传人:b****3 文档编号:10283420 上传时间:2023-05-24 格式:DOCX 页数:33 大小:24.73KB
下载 相关 举报
JSP分页技术实现.docx_第1页
第1页 / 共33页
JSP分页技术实现.docx_第2页
第2页 / 共33页
JSP分页技术实现.docx_第3页
第3页 / 共33页
JSP分页技术实现.docx_第4页
第4页 / 共33页
JSP分页技术实现.docx_第5页
第5页 / 共33页
JSP分页技术实现.docx_第6页
第6页 / 共33页
JSP分页技术实现.docx_第7页
第7页 / 共33页
JSP分页技术实现.docx_第8页
第8页 / 共33页
JSP分页技术实现.docx_第9页
第9页 / 共33页
JSP分页技术实现.docx_第10页
第10页 / 共33页
JSP分页技术实现.docx_第11页
第11页 / 共33页
JSP分页技术实现.docx_第12页
第12页 / 共33页
JSP分页技术实现.docx_第13页
第13页 / 共33页
JSP分页技术实现.docx_第14页
第14页 / 共33页
JSP分页技术实现.docx_第15页
第15页 / 共33页
JSP分页技术实现.docx_第16页
第16页 / 共33页
JSP分页技术实现.docx_第17页
第17页 / 共33页
JSP分页技术实现.docx_第18页
第18页 / 共33页
JSP分页技术实现.docx_第19页
第19页 / 共33页
JSP分页技术实现.docx_第20页
第20页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

JSP分页技术实现.docx

《JSP分页技术实现.docx》由会员分享,可在线阅读,更多相关《JSP分页技术实现.docx(33页珍藏版)》请在冰点文库上搜索。

JSP分页技术实现.docx

JSP分页技术实现

JSP分页技术实现使用工具类实现通用分页处理

目前比较广泛使用的分页方式是将查询结果缓存在HttpSession或有状态bean中,翻页的时候从缓存中取出一页数据显示。

这种方法有两个主要的缺点:

一是用户可能看到的是过期数据;二是如果数据量非常大时第一次查询遍历结果集会耗费很长时间,并且缓存的数据也会占用大量内存,效率明显下降。

  其它常见的方法还有每次翻页都查询一次数据库,从ResultSet中只取出一页数据(使用rs.last();rs.getRow()获得总计录条数,使用rs.absolute()定位到本页起始记录)。

这种方式在某些数据库(如oracle)的JDBC实现中差不多也是需要遍历所有记录,实验证明在记录数很大时速度非常慢。

  至于缓存结果集ResultSet的方法则完全是一种错误的做法。

因为ResultSet在Statement或Connection关闭时也会被关闭,如果要使ResultSet有效势必长时间占用数据库连接。

  因此比较好的分页做法应该是每次翻页的时候只从数据库里检索页面大小的块区的数据。

这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。

而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。

  在oracle数据库中查询结果的行号使用伪列ROWNUM表示(从1开始)。

例如select*fromemployeewhererownum<10返回前10条记录。

但因为rownum是在查询之后排序之前赋值的,所以查询employee按birthday排序的第100到120条记录应该这么写:

[pre]select*from(

selectmy_table.*,rownumasmy_rownumfrom(

selectname,birthdayfromemployeeorderbybirthday

)my_tablewhererownum<120

)wheremy_rownum>=100

[/pre]

  mySQL可以使用LIMIT子句:

    selectname,birthdayfromemployeeorderbybirthdayLIMIT99,20

  DB2有rownumber()函数用于获取当前行数。

  

  在Web程序中分页会被频繁使用,但分页的实现细节却是编程过程中比较麻烦的事情。

大多分页显示的查询操作都同时需要处理复杂的多重查询条件,sql语句需要动态拼接组成,再加上分页需要的记录定位、总记录条数查询以及查询结果的遍历、封装和显示,程序会变得很复杂并且难以理解。

因此需要一些工具类简化分页代码,使程序员专注于业务逻辑部分。

下面是我设计的两个工具类:

  PagedStatement封装了数据库连接、总记录数查询、分页查询、结果数据封装和关闭数据库连接等操作,并使用了PreparedStatement支持动态设置参数。

  RowSetPage参考PetStore的pagebypageiterator模式,设计RowSetPage用于封装查询结果(使用OracleCachedRowSet缓存查询出的一页数据,关于使用CachedRowSet封装数据库查询结果请参考JSP页面查询显示常用模式)以及当前页码、总记录条数、当前记录数等信息,并且可以生成简单的HTML分页代码。

  PagedStatement查询的结果封装成RowsetPage。

  下面是简单的使用示例:

//DAO查询数据部分代码:

publicRowSetPagegetEmployee(Stringgender,intpageNo)throwsException{

Stringsql="selectemp_id,emp_code,user_name,real_namefromemployeewheregender=?

";

//使用Oracle数据库的分页查询实现,每页显示5条

PagedStatementpst=newPagedStatementOracleImpl(sql,pageNo,5);

pst.setString(1,gender);

returnpst.executeQuery();

}

//Servlet处理查询请求部分代码:

intpageNo;

try{

//可以通过参数pageno获得用户选择的页码

pageNo=Integer.parseInt(request.getParameter("pageno"));

}catch(Exceptionex){

//默认为第一页

pageNo=1;

}

Stringgender=request.getParameter("gender");

request.setAttribute("empPage",myBean.getEmployee(gender,pageNo));

//JSP显示部分代码

<%@pageimport="page.RowSetPage"%>

functiondoQuery(){

form1.actionType.value="doQuery";

form1.submit();

}

性别:

">

<%

RowSetPageempPage=(RowSetPage)request.getAttribute("empPage");

if(empPage==null)empPage=RowSetPage.EMPTY_PAGE;

%>

ID代码用户名姓名

<%

javax.sql.RowSetempRS=(javax.sql.RowSet)empPage.getRowSet();

if(empRS!

=null)while(empRS.next()){

%>

<%=empRS.getString("EMP_ID")%>

<%=empRS.getString("EMP_CODE")%>

<%=empRS.getString("USER_NAME")%>

<%=empRS.getString("REAL_NAME")%>

<%

}//endwhile

%>

<%

//显示总页数和当前页数(pageno)以及分页代码。

//此处doQuery为页面上提交查询动作的javascript函数名,pageno为标识当前页码的参数名

%>

<%=empPage.getHTML("doQuery","pageno")%>

  效果如图:

=800)window.open('/XrssFile/2006-5/11/2006511194114817.jpg');"height=201alt=""hspace=0src="/UploadPic/2007-5/20075623104206.JPG"width=492onload="if(this.width>'800')this.width='800';if(this.height>'800')this.height='800';"border=0>

因为分页显示一般都会伴有查询条件和查询动作,页面应已经有校验查询条件和提交查询的javascript方法(如上面的doQuery),所以RowSetPage.getHTML()生成的分页代码在用户选择新页码时直接回调前面的处理提交查询的javascript方法。

注意在显示查询结果的时候上次的查询条件也需要保持,如">。

同时由于页码的参数名可以指定,因此也支持在同一页面中有多个分页区。

  另一种分页代码实现是生成每一页的URL,将查询参数和页码作为QueryString附在URL后面。

这种方法的缺陷是在查询条件比较复杂时难以处理,并且需要指定处理查询动作的servlet,可能不适合某些定制的查询操作。

  如果对RowSetPage.getHTML()生成的默认分页代码不满意可以编写自己的分页处理代码,RowSetPage提供了很多getter方法用于获取相关信息(如当前页码、总页数、总记录数和当前记录数等)。

  在实际应用中可以将分页查询和显示做成jsptaglib,进一步简化JSP代码,屏蔽JavaCode。

附:

分页工具类的源代码,有注释,应该很容易理解。

1.Page.java

2.RowSetPage.java(RowSetPage继承Page)

3.PagedStatement.java

4.PagedStatementOracleImpl.java(PagedStatementOracleImpl继承PagedStatement)

您可以任意使用这些源代码,但必须保留authorevan_zhao@字样

///////////////////////////////////

//

//Page.java

//author:

evan_zhao@

//

///////////////////////////////////

packagepage;

importjava.util.List;

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.Collections;

/**

*Title:

分页对象

*Description:

用于包含数据及分页信息的对象

*Page类实现了用于显示分页信息的基本方法,但未指定所含数据的类型,

*可根据需要实现以特定方式组织数据的子类,

*如RowSetPage以RowSet封装数据,ListPage以List封装数据

*Copyright:

Copyright(c)2002

*@authorevan_zhao@

*@version1.0

*/

publicclassPageimplementsjava.io.Serializable{

publicstaticfinalPageEMPTY_PAGE=newPage();

publicstaticfinalintDEFAULT_PAGE_SIZE=20;

publicstaticfinalintMAX_PAGE_SIZE=9999;

privateintmyPageSize=DEFAULT_PAGE_SIZE;

privateintstart;

privateintavaCount,totalSize;

privateObjectdata;

privateintcurrentPageno;

privateinttotalPageCount;

/**

*默认构造方法,只构造空页

*/

protectedPage(){

this.init(0,0,0,DEFAULT_PAGE_SIZE,newObject());

}

/**

*分页数据初始方法,由子类调用

*@paramstart本页数据在数据库中的起始位置

*@paramavaCount本页包含的数据条数

*@paramtotalSize数据库中总记录条数

*@parampageSize本页容量

*@paramdata本页包含的数据

*/

protectedvoidinit(intstart,intavaCount,inttotalSize,intpageSize,Objectdata){

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){

//thrownewRuntimeException("记录条数大于总条数?

");

}

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("StartIndextoPageNo:

"+start+"-"+currentPageno);

}

publicObjectgetData(){

returnthis.data;

}

/**

*取本页数据容量(本页能包含的记录数)

*@return本页能包含的记录数

*/

publicintgetPageSize(){

returnthis.myPageSize;

}

/**

*是否有下一页

*@return是否有下一页

*/

publicbooleanhas下一页:

控制字符串的超长部分用省略号表示(){

/*

if(avaCount==0&&totalSize==0){

returnfalse;

}

return(start+avaCount-1)

*/

return(this.getCurrentPageNo()

}

/**

*是否有上一页

*@return是否有上一页

*/

publicbooleanhasPreviousPage(){

/*

returnstart>1;

*/

return(this.getCurrentPageNo()>1);

}

/**

*获取当前页第一条数据在数据库中的位置

*@return

*/

publicintgetStart(){

returnstart;

}

/**

*获取当前页最后一条数据在数据库中的位置

*@return

*/

publicintgetEnd(){

intend=this.getStart()+this.getSize()-1;

if(end<0){

end=0;

}

returnend;

}

/**

*获取上一页第一条数据在数据库中的位置

*@return记录对应的rownum

*/

publicintgetStartOfPreviousPage(){

returnMath.max(start-myPageSize,1);

}

/**

*获取下一页第一条数据在数据库中的位置

*@return记录对应的rownum

*/

publicintgetStartOf下一页:

控制字符串的超长部分用省略号表示(){

returnstart+avaCount;

}

/**

*获取任一页第一条数据在数据库中的位置,每页条数使用默认值

*@parampageNo页号

*@return记录对应的rownum

*/

publicstaticintgetStartOfAnyPage(intpageNo){

returngetStartOfAnyPage(pageNo,DEFAULT_PAGE_SIZE);

}

/**

*获取任一页第一条数据在数据库中的位置

*@parampageNo页号

*@parampageSize每页包含的记录数

*@return记录对应的rownum

*/

publicstaticintgetStartOfAnyPage(intpageNo,intpageSize){

intstartIndex=(pageNo-1)*pageSize+1;

if(startIndex<1)startIndex=1;

//System.out.println("PageNotoStartIndex:

"+pageNo+"-"+startIndex);

returnstartIndex;

}

/**

*取本页包含的记录数

*@return本页包含的记录数

*/

publicintgetSize(){

returnavaCount;

}

/**

*取数据库中包含的总记录数

*@return数据库中包含的总记录数

*/

publicintgetTotalSize(){

returnthis.totalSize;

}

/**

*取当前页码

*@return当前页码

*/

publicintgetCurrentPageNo(){

returnthis.currentPageno;

}

/**

*取总页码

*@return总页码

*/

publicintgetTotalPageCount(){

returnthis.totalPageCount;

}

/**

*

*@paramqueryJSFunctionName实现分页的JS脚本名字,页码变动时会自动回调该方法

*@parampageNoParamName页码参数名称

*@return

*/

publicStringgetHTML(StringqueryJSFunctionName,StringpageNoParamName){

if(getTotalPageCount()<1){

return"";

}

if(queryJSFunctionName==null||queryJSFunctionName.trim().length()<1){

queryJSFunctionName="gotoPage";

}

if(pageNoParamName==null||pageNoParamName.trim().length()<1){

pageNoParamName="pageno";

}

StringgotoPage="_"+queryJSFunctionName;

StringBufferhtml=newStringBuffer("\n");

html.append("\n")

.append("function").append(gotoPage).append("(pageNo){\n")

.append("varcurPage=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("returntrue;\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("

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2