JSP通用分页框架
写一个通用的分页框架,这样在项目里面如果想实现分页功能,只需要稍加改动参数就可以实现分页处理了。这样写了会节省很多时间。
一.分页类
既然要分页那么我们就要考虑建一个通用的分页类,里面需要的参数一般有:
总页数 totalpage
总共记录数 totalrecord
每页显示数 pagesize
当前页pageindex
承载当前页数据的集合 list datas
完整代码:page.java
import java.util.list; public class pager<e> { /** * 总共页数 */ private int totalpages; /** * 总共记录数 */ private int totalrecords; /** * 每页显示数量 */ private int pagesize; /** * 当前页 */ private int pageindex; /** * 当前页数据集合 */ private list<e> datas; public void settotalpages(int totalpages) { this.totalpages = totalpages; } public void settotalrecords(int totalrecords) { this.totalrecords = totalrecords; } public void setpagesize(int pagesize) { this.pagesize = pagesize; } public void setpageindex(int pageindex) { this.pageindex = pageindex; } public void setdatas(list<e> datas) { this.datas = datas; } public int gettotalpages() { return totalpages; } public int gettotalrecords() { return totalrecords; } public int getpagesize() { return pagesize; } public int getpageindex() { return pageindex; } public list<e> getdatas() { return datas; } }
二.用户类
这里以查询用户来做分页为例,所以就需要一个用户类
用户号 userid
用户姓名 username
用户密码 password
注册时间 regdate
完整代码
import java.sql.timestamp; public class user { private int userid;//用户id private string username;//用户名 private string password;//密码 private timestamp regdate;//注册时间 public int getuserid() { return userid; } public void setuserid(int userid) { this.userid = userid; } public string getusername() { return username; } public void setusername(string username) { this.username = username; } public string getpassword() { return password; } public void setpassword(string password) { this.password = password; } public timestamp getregdate() { return regdate; } public void setregdate(timestamp regdate) { this.regdate = regdate; } }
三.threadlocal提取公用参数
先说如果不提取公共参数,比如pagesize,pageindex,那么我们的查询方法应该是这样子:
public void getusers(string name,int pagesize,int pageindex)
如果以后再增加参数,无疑这里的参数会变的很多,所以我们利用threadlocal把pagesize和pageindex提取出来.
先写这个类
public class systemcontext { //页大小 private static threadlocal<integer> pagesize = new threadlocal<>(); //当前页 private static threadlocal<integer> pageindex = new threadlocal<>(); public static integer getpagesize() { return pagesize.get(); } public static void removepagesize(){ pagesize.remove(); } public static void setpagesize(int _pagesize) { pagesize.set(_pagesize); } public integer getpageindex() { return pageindex.get(); } public void setpageindex(int _pageindex) { pageindex.set(_pageindex); } public static void removepageindex(){ pageindex.remove(); } }
对于threadlocal,这个变量会在线程中一直存在,那么我们就可以在向服务器发送请求的时候添加参数,服务器返回数据的时候移除参数,一来一回的话,自然而然可以用过滤器
那么过滤器如下:
import com.dao.systemcontext; import javax.servlet.*; import java.io.ioexception; public class systemfilter implements filter{ int pagesize; int pageindex = 1; @override public void init(filterconfig filterconfig) throws servletexception { try { pagesize = integer.parseint(filterconfig.getinitparameter("pagesize")); } catch (numberformatexception e) { pagesize = 15; } } @override public void dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain filterchain) throws ioexception, servletexception { try { pageindex = integer.parseint(servletrequest.getparameter("pageindex")); }catch (numberformatexception e){ //什么也不做,pageindex=1 } try { //开始请求的时候配置参数 systemcontext.setpagesize(pagesize); systemcontext.setpageindex(pageindex); filterchain.dofilter(servletrequest,servletresponse); }finally { //请求返回的时候移除参数 systemcontext.removepageindex(); systemcontext.removepagesize(); } } @override public void destroy() { } }
用了过滤器,自然要在web.xml中配置过滤器
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <filter> <filter-name>systemfilter</filter-name> <filter-class>com.filter.systemfilter</filter-class> <!--配置没页大小--> <init-param> <param-name>pagesize</param-name> <param-value>15</param-value> </init-param> </filter> <filter-mapping> <filter-name>systemfilter</filter-name> <!--这里配置需要分页的页面--> <url-pattern>/index.jsp</url-pattern> </filter-mapping> </web-app>
这样的好处不言而喻,结构清晰,修改方便.接下来是分页代码
四.分页代码
分页代码应该写一个接口和实现类的,这里演示项目就写在了一起
import com.util.pager; import com.util.user; import java.sql.*; import java.util.arraylist; import java.util.list; public class userdao { private connection conn = null; private resultset rs = null; private preparedstatement ps = null; // public static void main(string[] args) { // userdao dao = new userdao(); // dao.getusers("",15,1); // dao.close(); // } public userdao() { string drivername = "com.mysql.jdbc.driver"; string url = "jdbc:mysql://localhost:3306/fenyedemo"; string user = "root";string password = "123456"; try { class.forname(drivername); conn = drivermanager.getconnection(url,user,password); } catch (classnotfoundexception e) { system.out.println("没有发现驱动"); e.printstacktrace(); } catch (sqlexception e) { system.out.println("获取连接失败"); e.printstacktrace(); } } /** * 具体分页实现代码 * @param name 查询条件 * @return */ public pager getusers(string name){ //获取分页参数 int pagesize = systemcontext.getpagesize(); int pageindex = systemcontext.getpageindex(); //分页具体sql语句 string sql = "select * from user "; string sqlcount = "select count(*) from user "; if (name!=null && !name.trim().equals("")){ sql += "where username like %"+name+"%"; sqlcount += "where username like %"+name+"%"; } sql += " limit ?,?"; //存放当前页的集合 list<user> datas = new arraylist<>(); //存放当前分页的集合 pager<user> pages = new pager<>(); user usertemp = null; try { ps = conn.preparestatement(sql); if(pageindex<=0) pageindex=1; //设置参数 ps.setint(1,(pageindex-1)*pagesize); ps.setint(2,pagesize); rs = ps.executequery(); //循环取出,添加到datas中 while (rs.next()){ usertemp = new user(); usertemp.setuserid(rs.getstring("id")); usertemp.setusername(rs.getstring("username")); usertemp.setpassword(rs.getstring("password")); usertemp.setregdate(rs.gettimestamp("regdate")); datas.add(usertemp); } //最后设置pages pages.setpageindex(pageindex); pages.setpagesize(pagesize); ps = conn.preparestatement(sqlcount); rs = ps.executequery(); while(rs.next()){ pages.settotalrecords(rs.getint(1)); pages.settotalpages((rs.getint(1)-1)/pagesize+1); } pages.setdatas(datas); } catch (sqlexception e) { system.out.println("获取出错"); e.printstacktrace(); } return pages; } public void close(){ try { if (rs!=null) rs.close(); rs = null; if (ps!=null) ps.close(); ps = null; if (conn!=null) conn.close(); conn = null; } catch (sqlexception e) { system.out.println("关闭失败"); e.printstacktrace(); } } }
五.jsp测试页面
普通页面就是显示数据,这个很简单,代码如下
<%@ page import="com.dao.userdao" %> <%@ page import="com.util.pager" %> <%@ page import="com.util.user" %> <%@ page import="java.util.iterator" %> <%@ page contenttype="text/html;charset=utf-8" language="java" %> <% string condition = request.getparameter("condition"); userdao userdao = new userdao(); pager<user> pages = null; if (condition!=null && !condition.trim().equals("")){ pages = userdao.getusers(condition); }else { pages = userdao.getusers(null); } userdao.close(); %> <html> <head> <title>测试用例</title> </head> <body> <h1 align="center">分页测试</h1> <table align="center" border="1" width="700"> <tr> <td colspan="100%"> <form method="get" action="index.jsp"> <input type="text" name="condition"> <input type="submit" value="查询"> </form> </td> </tr> <tr> <th>id</th> <th>username</th> <th>password</th> <th>data</th> </tr> <% for (iterator it = pages.getdatas().iterator(); it.hasnext() ; ) { user usertemp = (user) it.next(); %> <tr> <td><%=usertemp.getuserid()%></td> <td><%=usertemp.getusername()%></td> <td><%=usertemp.getpassword()%></td> <td><%=usertemp.getregdate()%></td> </tr> <% }%> </table> </body> </html>
此时已经有一些效果了
六.jsp页面添加控制选项
添加控制选项这里使用分页框架pager-taglib,也是为了更好的支持通用性.
首先在index.jsp页面查询之后静态引入一个新的页面,作为底部控制页面
使用方法,就是去下载相应的jar,然后引入到项目的lib中即可
<tr><td colspan="100%"> <jsp:include page="fenye.jsp"> <jsp:param name="items" value="<%=pages.gettotalrecords()%>"/> <jsp:param name="maxpageitems" value="<%=pages.getpagesize()%>"/> <jsp:param name="maxindexpages" value="10"/> <jsp:param name="params" value="condition"/> </jsp:include> </td></tr>
下面开始写fenye.jsp
<%@ page contenttype="text/html;charset=utf-8" language="java" pageencoding="utf-8" %> <% int items = integer.parseint(request.getparameter("items")); int maxpageitems = integer.parseint(request.getparameter("maxpageitems")); int maxindexpages = integer.parseint(request.getparameter("maxindexpages")); string params = request.getparameter("params"); %> <%--引入分页框架--%> <%@taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %> <%--参数依次是项目总数 每页显示数量 下方菜单显示数 当前页curpage--%> <pg:pager items="<%=items%>" maxpageitems="<%=maxpageitems%>" maxindexpages="<%=maxindexpages%>" export="curpage=pagenumber"> <pg:param name="<%=params%>"/> <pg:first> <a href="<%=pageurl%>">首页</a> </pg:first> <pg:prev> <a href="<%=pageurl%>">上一页</a> </pg:prev> <pg:pages> <% if(curpage==pagenumber) { %> [<%=pagenumber %>] <% } else { %> <a href="<%=pageurl%>"><%=pagenumber %></a> <% } %> </pg:pages> <pg:next> <a href="<%=pageurl %>">下一页</a> </pg:next> <pg:last> <a href="<%=pageurl %>">尾页</a> </pg:last> </pg:pager>
分页设计基本就是上面框架,重点是参数传递,这里参数传递利用静态引入的时候,配置jsp:param,然后到fenye,jsp中再取出.
其中pager-taglib中有一个标签是”/>,这个就是针对我的查询条件传递过来的参数,如果没传递,那么查询的话点击下一页也会出错,这里还有一个问题就是编码问题,pager-taglib默认编码是gb2312,你可以重新打包文件编译,也可以在tomcat的server.xml文件中配置urlencording=”utf-8”,这样就会没问题了.
七.总结
这样的一个框架,如果其他需要实现分页的就可以直接套用了,建立相应的实体类,写好分页代码,直接套用systemcontex.java和systemfilter.java(记得在web.xml配置相应的过滤文件),再jsp中可以直接使用fenye.jsp,这样就会省下很多麻烦