| |
说到分页算法,一般web开发都会用到,我只是在我的实现技术上用了struts框架,其实原理都一样的。 看了网上相当多的分页算法,有对的也有好多是错的,更有好多是不太优化的。还有以前自己在augmentum做的一个分页算法,总结了一些不足。决定重新再写一个分页算法。 首先,应该写个bean来记录存储一些页面的属性 分页大致需要如下属性:
private int currentpage = 1; // 当前页
private int totalpages = 0; // 总页数
private int pagerecorders = 5;// 每页5条数据
private int totalrows = 0; // 总数据数
private int pagestartrow = 0;// 每页的起始数
private int pageendrow = 0; // 每页显示数据的终止数
private boolean hasnextpage = false; // 是否有下一页
private boolean haspreviouspage = false; // 是否有前一页 private int nextpage = 0;//下一页的页码 private int previouspage = 0;//上一页的页码
然后这些属性之间是有联系的,我们可以在构造函数的时候就初始化一些属性 有两种方法: 一,根据总的页数,(假设当前页为1) public pagebean(int totalrows){ this.totalrows = totalrows; this.currentpage = 1; haspreviouspage = false; if ((totalrows % pagerecorders) == 0) { totalpages = totalrows / pagerecorders; } else { totalpages = totalrows / pagerecorders + 1; } if (totalrows >= pagerecorders) { hasnextpage = true; nextpage = 2; this.pageendrow = pagerecorders; } else { this.pageendrow = totalrows; hasnextpage = false; nextpage = 1; } this.pagestartrow = 0; previouspage = 1; } 然后在按下一页或者上一页的时候需要如下函数处理: public void nextpage() { if(hasnextpage == true) currentpage = currentpage + 1; if ((currentpage - 1) > 0) { haspreviouspage = true; } else { haspreviouspage = false; } if (currentpage >= totalpages) { hasnextpage = false; this.nextpage = currentpage; } else { hasnextpage = true; nextpage = currentpage+1; } this.pagestartrow = (currentpage -1) * pagerecorders; if(hasnextpage == true) this.pageendrow = pagestartrow + 5; else{ this.pageendrow =this.totalpages; } previouspage = currentpage - 1; } public void previouspage() { if(haspreviouspage == true) currentpage = currentpage - 1; if (currentpage == 0) { currentpage = 1; } if (currentpage >= totalpages) { hasnextpage = false; } else { hasnextpage = true; } nextpage = currentpage + 1; if ((currentpage - 1) > 0) { haspreviouspage = true; previouspage = currentpage - 1; } else { haspreviouspage = false; previouspage = currentpage; } this.pagestartrow = (currentpage -1) * pagerecorders; if(hasnextpage == true) this.pageendrow = pagestartrow + 5; else{ this.pageendrow =this.totalpages; } }
在html中按下一页或者上一页的时候有如下代码: <logic:equal name="page" property="hasnextpage" value="true"> <html:link page="/list.do?action=nextpage"> nextpage </html:link> </logic:equal> <logic:equal name="page" property="haspreviouspage" value="true"> <html:link page="/list.do?action=previouspage"> previouspage </html:link> </logic:equal> 然后在action中作如下处理: string currentpage = request.getparameter("currentpage"); httpsession session = request.getsession(); employeeform employeeform = (employeeform) form; string querystring = null; string querycon = null; string action = employeeform.getaction(); list list = new arraylist(); pagebean pb = null; employeedao employeedao = new employeedao(); if(action == null || action.equals("null")){ int totalrows = employeedao.gettotalrows(); pb = new pagebean(totalrows); session.removeattribute("page"); querystring = employeeform.getquerystring(); querycon = employeeform.getquerycon(); session.setattribute("querystring",querystring); session.setattribute("querycon",querycon); list = employeedao.getallemployee(querystring, querycon, string.valueof(pb.getpagestartrow()), string.valueof(pb.getpagerecorders())); }else if(action.equals("nextpage")){ querystring = (string)session.getattribute("querystring"); querycon = (string)session.getattribute("querycon"); employeeform.setquerystring(querystring); employeeform.setquerycon(querycon); pb = (pagebean)session.getattribute("page"); pb.nextpage(); list = employeedao.getallemployee(querystring, querycon, string.valueof(pb.getpagestartrow()), string.valueof(pb.getpagerecorders())); }else if(action.equals("previouspage")){ querystring = (string)session.getattribute("querystring"); querycon = (string)session.getattribute("querycon"); employeeform.setquerystring(querystring); employeeform.setquerycon(querycon); pb = (pagebean)session.getattribute("page"); pb.previouspage(); list = employeedao.getallemployee(querystring, querycon, string.valueof(pb.getpagestartrow()), string.valueof(pb.getpagerecorders())); } pb.description(); session.setattribute("page",pb); request.setattribute("admin", "admin"); request.setattribute("employee", list); return mapping.findforward("showlist"); 然后在数据库查询中有如下代码: /** *查询总记录数 */ public int gettotalrows() { int totalrows = 0; string sql = "select count(*) from employee";//假设是员工表 database db = new database(); resultset rs = db.executequery(sql); try { while (rs.next()) { string id = (string) rs.getstring(1); totalrows = integer.parseint(id); } } catch (sqlexception e) { e.printstacktrace(); } db.close(); return totalrows; } /* *查询每一页需要查询的页码 */ public list getallemployee(string querystring, string querycon,string startrow,string num) { list list = new arraylist(); string sql = null; if (querystring == null || querystring.equals("")) { sql = "select * from employee,dept " + "where dept.id = employee.deptid " + "order by employee.id asc"+ " limit "+startrow+","+num; } else { sql = "select * from employee,dept " + "where dept.id = employee.deptid order by employee." + querystring + " " + querycon + " limit "+startrow+","+num; } employee employee = null; database db = new database(); resultset rs = db.executequery(sql); try { while (rs.next()) { string id = (string) rs.getstring("employee.id"); string name = (string) rs.getstring("employee.name"); string deptid = (string) rs.getstring("employee.deptid"); string deptname = (string) rs.getstring("dept.deptname"); employee = new employee(); employee.setid(id); employee.setname(name); employee.setdeptid(deptid); employee.setdeptname(deptname); list.add(employee); } } catch (sqlexception e) { e.printstacktrace(); } db.close(); return list; } 这里我用了hibernate进行数据库操作,你也可以用jdbc进行操作,情况类似。
二,根据总的页数,当前页 这样的话构造函数应该写成: public pagebean(int totalrows,int currentpage) { this.totalrows = totalrows; this.currentpage = currentpage; if(currentpage < 2) haspreviouspage = false; else haspreviouspage = true; if ((totalrows % pagerecorders) == 0) { totalpages = totalrows / pagerecorders; } else { totalpages = totalrows / pagerecorders + 1; } if (currentpage < totalpages) { hasnextpage = true; nextpage = currentpage + 1; pagestartrow = (currentpage - 1)*pagerecorders; this.pageendrow = pagestartrow + pagerecorders; } else if(currentpage == totalpages){ pagestartrow = (currentpage - 1)*pagerecorders; this.pageendrow = totalrows; hasnextpage = false; nextpage = currentpage; } if(currentpage < 2){ previouspage = currentpage; haspreviouspage = false; }else if(currentpage > 1){ previouspage = currentpage-1; haspreviouspage = true; } }
在action中应该写成 if(currentpage == null){ pb = new pagebean(totalrows); session.removeattribute("page"); querystring = employeeform.getquerystring(); querycon = employeeform.getquerycon(); session.setattribute("querystring",querystring); session.setattribute("querycon",querycon); list = employeedao.getallemployee(querystring, querycon, string.valueof(pb.getpagestartrow()), string.valueof(pb.getpagerecorders())); } else{ pb = new pagebean(totalrows,integer.parseint(currentpage)); querystring = employeeform.getquerystring(); querycon = employeeform.getquerycon(); session.setattribute("querystring",querystring); session.setattribute("querycon",querycon); list = employeedao.getallemployee(querystring, querycon, string.valueof(pb.getpagestartrow()), string.valueof(pb.getpagerecorders())); } session.setattribute("page",pb); request.setattribute("admin", "admin"); request.setattribute("employee", list); return mapping.findforward("showlist");
在jsp中应该写成: <logic:equal name="page" property="hasnextpage" value="true"> <a href="list.do?currentpage=<bean:write name="page" property="nextpage"/>"> nextpage </a> </logic:equal> <logic:equal name="page" property="haspreviouspage" value="true"> | <a href="/test/list.do?currentpage=<bean:write name="page" property="previouspage"/>"> previouspage </a> </logic:equal> 数据库查询部分依然适用。
尽管洋洋洒洒贴了一部分代码,不过好像不太想看,包括我,也比较讨厌看一些烦琐的代码,所以如果你想要源代码进行探讨研究的话,欢迎随时找我。那就总结一下这两种方法吧 首先这两种方法都是取需要显示的数据显示,这样,在数据库庞大的情况下,比一次性把所有数据都取出来的效率要高。 第一种方法是把pagebean存在了一个httpsession中,在进入到显示列表的时候就进行了初始化,在jsp页面传递的参数action是固定的三个值:null,nextpage,previouspage.这样虽然比较容易理解,但是我发现一个bug,就是如果你按刷新,他也会翻页,因为他的url就是 .do?aciton=nextpage,这样的话你传进去的action还是有一个值,这样就会导致翻页。 第二种方法是考虑了第一种方法的bug,在jsp页面传递的参数currentpage的值是bean中的nextpage的值或者previouspage里的值,用了struts标签库嵌套,把值赋予currentpage,这样的话currentpage的值是:1,2,3,4...totalpages之间。这样的话你即使按刷新按钮,他也是当前页,因为他的url就是.do?currentpage=somenumber(somenumber是1到totalpages中的一个值)。但是这样的话pagebean在每次访问的时候都要重新生成一个对象,该对象也是根据totalrows(总数据数),currentpage(当前页数)进行构造,从而设置其他的一些属性。个人比较推荐第二种方法。
|
|