说到分页算法一般WEB开发都会用到我只是在我的实现技术上用了struts框架其实原理都一样的
看了网上相当多的分页算法有对的也有好多是错的更有好多是不太优化的还有以前自己在augmentum做的一个分页算法总结了一些不足决定重新再写一个分页算法
首先应该写个bean来记录存储一些页面的属性
分页大致需要如下属性
privateintcurrentPage=;//当前页
privateinttotalPages=;//总页数
privateintpageRecorders=;//每页条数据
privateinttotalRows=;//总数据数
privateintpageStartRow=;//每页的起始数
privateintpageEndRow=;//每页显示数据的终止数
privatebooleanhasNextPage=false;//是否有下一页
privatebooleanhasPreviousPage=false;//是否有前一页
privateintnextPage=;//下一页的页码
privateintpreviousPage=;//上一页的页码
然后这些属性之间是有联系的我们可以在构造函数的时候就初始化一些属性
有两种方法
一根据总的页数(假设当前页为)
publicPageBean(inttotalRows){
thistotalRows=totalRows;
thiscurrentPage=;
hasPreviousPage=false;
if((totalRows%pageRecorders)==){
totalPages=totalRows/pageRecorders;
}else{
totalPages=totalRows/pageRecorders+;
}
if(totalRows>=pageRecorders){
hasNextPage=true;
nextPage=;
thispageEndRow=pageRecorders;
}else{
thispageEndRow=totalRows;
hasNextPage=false;
nextPage=;
}
thispageStartRow=;
previousPage=;
}
然后在按下一页或者上一页的时候需要如下函数处理
publicvoidnextPage(){
if(hasNextPage==true)
currentPage=currentPage+;
if((currentPage)>){
hasPreviousPage=true;
}else{
hasPreviousPage=false;
}
if(currentPage>=totalPages){
hasNextPage=false;
thisnextPage=currentPage;
}else{
hasNextPage=true;
nextPage=currentPage+;
}
thispageStartRow=(currentPage)*pageRecorders;
if(hasNextPage==true)
thispageEndRow=pageStartRow+;
else{
thispageEndRow=thistotalPages;
}
previousPage=currentPage;
}
publicvoidpreviousPage(){
if(hasPreviousPage==true)
currentPage=currentPage;
if(currentPage==){
currentPage=;
}
if(currentPage>=totalPages){
hasNextPage=false;
}else{
hasNextPage=true;
}
nextPage=currentPage+;
if((currentPage)>){
hasPreviousPage=true;
previousPage=currentPage;
}else{
hasPreviousPage=false;
previousPage=currentPage;
}
thispageStartRow=(currentPage)*pageRecorders;
if(hasNextPage==true)
thispageEndRow=pageStartRow+;
else{
thispageEndRow=thistotalPages;
}
}
在HTML中按下一页或者上一页的时候有如下代码
<logic:equalname=pageproperty=hasNextPagevalue=true>
<html:linkpage=/Listdo?action=nextPage>
nextPage
</html:link>
</logic:equal>
<logic:equalname=pageproperty=hasPreviousPagevalue=true>
<html:linkpage=/Listdo?action=previousPage>
PreviousPage
</html:link>
</logic:equal>
然后在Action中作如下处理
StringcurrentPage=requestgetParameter(currentPage);
HttpSessionsession=requestgetSession();
EmployeeFormemployeeForm=(EmployeeForm)form;
StringqueryString=null;
StringqueryCon=null;
Stringaction=employeeFormgetAction();
Listlist=newArrayList();
PageBeanpb=null;
EmployeeDaoemployeeDao=newEmployeeDao();
if(action==null||actionequals(null)){
inttotalRows=employeeDaogetTotalRows();
pb=newPageBean(totalRows);
sessionremoveAttribute(page);
queryString=employeeFormgetQueryString();
queryCon=employeeFormgetQueryCon();
sessionsetAttribute(queryStringqueryString);
sessionsetAttribute(queryConqueryCon);
list=employeeDaogetAllEmployee(queryStringqueryCon
StringvalueOf(pbgetPageStartRow())
StringvalueOf(pbgetPageRecorders()));
}elseif(actionequals(nextPage)){
queryString=(String)sessiongetAttribute(queryString);
queryCon=(String)sessiongetAttribute(queryCon);
employeeFormsetQueryString(queryString);
employeeFormsetQueryCon(queryCon);
pb=(PageBean)sessiongetAttribute(page);
pbnextPage();
list=employeeDaogetAllEmployee(queryStringqueryCon
StringvalueOf(pbgetPageStartRow())
StringvalueOf(pbgetPageRecorders()));
}elseif(actionequals(previousPage)){
queryString=(String)sessiongetAttribute(queryString);
queryCon=(String)sessiongetAttribute(queryCon);
employeeFormsetQueryString(queryString);
employeeFormsetQueryCon(queryCon);
pb=(PageBean)sessiongetAttribute(page);
pbpreviousPage();
list=employeeDaogetAllEmployee(queryStringqueryCon
StringvalueOf(pbgetPageStartRow())
StringvalueOf(pbgetPageRecorders()));
}
pbdescription();
sessionsetAttribute(pagepb);
requestsetAttribute(adminadmin);
requestsetAttribute(employeelist);
returnmappingfindForward(showlist);
然后在数据库查询中有如下代码
/**
*查询总记录数
*/
publicintgetTotalRows(){
inttotalRows=;
Stringsql=selectcount(*)fromemployee;//假设是员工表
Databasedb=newDatabase();
ResultSetrs=dbexecuteQuery(sql);
try{
while(rsnext()){
Stringid=(String)rsgetString();
totalRows=IntegerparseInt(id);
}
}catch(SQLExceptione){
eprintStackTrace();
}
dbclose();
returntotalRows;
}
/*
*查询每一页需要查询的页码
*/
publicListgetAllEmployee(StringqueryStringStringqueryConStringstartRowStringnum){
Listlist=newArrayList();
Stringsql=null;
if(queryString==null||queryStringequals()){
sql=select*fromemployeedept+
wheredeptId=employeedeptId+
orderbyemployeeidasc+limit+startRow++num;
}else{
sql=select*fromemployeedept+
wheredeptId=employeedeptIdorderbyemployee
+queryString++queryCon+limit+startRow++num;
}
Employeeemployee=null;
Databasedb=newDatabase();
ResultSetrs=dbexecuteQuery(sql);
try{
while(rsnext()){
Stringid=(String)rsgetString(employeeid);
Stringname=(String)rsgetString(employeename);
StringdeptId=(String)rsgetString(employeedeptId);
StringdeptName=(String)rsgetString(deptdeptName);
employee=newEmployee();
employeesetId(id);
employeesetName(name);
employeesetDeptId(deptId);
employeesetDeptName(deptName);
listadd(employee);
}
}catch(SQLExceptione){
eprintStackTrace();
}
dbclose();
returnlist;
}
这里我用了hibernate进行数据库操作你也可以用jdbc进行操作情况类似
二根据总的页数当前页
这样的话构造函数应该写成:
publicPageBean(inttotalRowsintcurrentPage){
thistotalRows=totalRows;
thiscurrentPage=currentPage;
if(currentPage<)
hasPreviousPage=false;
else
hasPreviousPage=true;
if((totalRows%pageRecorders)==){
totalPages=totalRows/pageRecorders;
}else{
totalPages=totalRows/pageRecorders+;
}
if(currentPage<totalPages){
hasNextPage=true;
nextPage=currentPage+;
pageStartRow=(currentPage)*pageRecorders;
thispageEndRow=pageStartRow+pageRecorders;
}elseif(currentPage==totalPages){
pageStartRow=(currentPage)*pageRecorders;
thispageEndRow=totalRows;
hasNextPage=false;
nextPage=currentPage;
}
if(currentPage<){
previousPage=currentPage;
hasPreviousPage=false;
}elseif(currentPage>){
previousPage=currentPage;
hasPreviousPage=true;
}
}
在action中应该写成
if(currentPage==null){
pb=newPageBean(totalRows);
sessionremoveAttribute(page);
queryString=employeeFormgetQueryString();
queryCon=employeeFormgetQueryCon();
sessionsetAttribute(queryStringqueryString);
sessionsetAttribute(queryConqueryCon);
list=employeeDaogetAllEmployee(queryStringqueryCon
StringvalueOf(pbgetPageStartRow())
StringvalueOf(pbgetPageRecorders()));
}
else{
pb=newPageBean(totalRowsIntegerparseInt(currentPage));
queryString=employeeFormgetQueryString();
queryCon=employeeFormgetQueryCon();
sessionsetAttribute(queryStringqueryString);
sessionsetAttribute(queryConqueryCon);
list=employeeDaogetAllEmployee(queryStringqueryCon
StringvalueOf(pbgetPageStartRow())
StringvalueOf(pbgetPageRecorders()));
}
sessionsetAttribute(pagepb);
requestsetAttribute(adminadmin);
requestsetAttribute(employeelist);
returnmappingfindForward(showlist);
在jsp中应该写成
<logic:equalname=pageproperty=hasNextPagevalue=true>
<aListdo?currentPage=<bean:writename=pageproperty=nextPage/>>
nextPage
</a>
</logic:equal>
<logic:equalname=pageproperty=hasPreviousPagevalue=true>
|
<a/test/Listdo?currentPage=<bean:writename=pageproperty=previousPage/>>
PreviousPage
</a>
</logic:equal>
数据库查询部分依然适用
尽管洋洋洒洒贴了一部分代码不过好像不太想看包括我也比较讨厌看一些烦琐的代码所以如果你想要源代码进行探讨研究的话欢迎随时找我那就总结一下这两种方法吧
首先这两种方法都是取需要显示的数据显示这样在数据库庞大的情况下比一次性把所有数据都取出来的效率要高
第一种方法是把PageBean存在了一个HttpSession中在进入到显示列表的时候就进行了初始化在jsp页面传递的参数action是固定的三个值:nullnextPagepreviousPage这样虽然比较容易理解但是我发现一个BUG就是如果你按刷新他也会翻页因为他的url就是do?aciton=nextPage这样的话你传进去的action还是有一个值这样就会导致翻页
第二种方法是考虑了第一种方法的BUG在jsp页面传递的参数currentPage的值是bean中的nextPage的值或者previousPage里的值用了struts标签库嵌套把值赋予currentPage这样的话currentPage的值是totalPages之间这样的话你即使按刷新按钮他也是当前页因为他的url就是do?currentPage=someNumber(someNumber是到totalPages中的一个值)但是这样的话Pagebean在每次访问的时候都要重新生成一个对象该对象也是根据totalRows(总数据数)currentPage(当前页数)进行构造从而设置其他的一些属性个人比较推荐第二种方法