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,这样就会省下很多麻烦

    时间: 2024-10-08 21:13:51

    JSP通用分页框架的相关文章

    分页框架(Pager-taglib)的使用

    页面中引入分页框架 <!-- 分页 -->     <ul class="pagination">         <jsp:include page="/WEB-INF/pages/inc/pager.jsp">             <jsp:param value="search.action" name="url"/>             <jsp:param

    分页框架pager-taglib学习笔记

    下面的笔记来自于孔浩老师的视频教程和我自己的开发实践. 使用Pager-taglib可以帮助我们快速开发分页处理. pager-taglib-2.0.war这是我们第1次直观地认识jar包.直接放到tomcat的webapp目录下面,就可以启动项目,查看帮助文档.说明:拷贝完之后,可以改一个名字,方便我们写访问的路径.使用的步骤:(1)将相应包拷贝到lib目录(pager-taglib.jar),另外一个是源码包,貌似可以不拷贝,我还没试过.(2)在jsp页面引入相应的分页标签库.引入标签 pr

    利用EF和C#泛型实现通用分页查询

    利用EF和C#泛型实现通用分页查询 Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (ORM) 解决方案,是微软的ORM框架.此框架将数据库中的表信息通过xml与实体类对象相关联,使得开发人员只需要关心实体对象,而不需要手动操作数据库,对实体对象的修改会映射到数据库中,这样大大提高了开发效率.以下代码使用了EF.泛型.泛型委托.lambda.匿名类.dynamic动态类型等知识完成了EF的crud,并且提供了一个高效的通用分页查询方法,采用了延时加载,

    通用分页后台显示

    通用分页 目的:作用通用的分页查询方法 它主要实现的就是通用,将普通查询方法进行反射优化,转变成一个可以被所有实体类dao层所继承的通用查询方法. 实例一 普通分页: 首先我们写一个普通的分页方法,然后再将其进行反射优化,之后就可以看出通用分页的优势了, 1.连接(关闭数据库),使用的是mysql数据库 package com.yuan.util; import java.io.InputStream; import java.sql.Connection; import java.sql.Dr

    通用分页2

    1.首页在我们通用分页1博客的基础上新建Servlet package com.zking.web; import java.io.IOException; import java.util.List; import java.util.Map; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.

    通用分页(二)

    通用分页核心思路:将上一次查询请求再发一次,只是当前页变了而已. 首页 1 2 3 4 … 100 末页 跳转 MySQL分页:select * from 表 limit 3,3 每页显示记录数 自己设置当前页 来自前端总页数 总记录数%每页显示记录数==0?总记录数/每页显示记录数:总记录数/每页显示记录数+1总记录数 数据库统计count()每页起始记录数   =(当前页-1)*每页显示记录数+1 总共101条记录,每页显示10条第一页: 1-10第二页: 11-20第三页: 21-30 每

    如何使用前端分页框架bootstrap paginator

    前端分页框架bootstrap paginator用于web前端页面快速实现美观大方的翻页功能.在实现交互良好的页面翻页功能时,往往还需要配合使用后端分页框架pagehelper.pagehelper框架于前端而言,主要作用是将分页数据pageInfo从后端传入到前端.接下来给一个应用小栗子:step1 我们需要在jsp页面所需要显示翻页选项的位置插入一个<ul>标签,并指定id,如下: <ul id="pagination"></ul> step2

    ibernate学习笔记5---实体类或属性名与数据库关键字冲突、hql命名参数、hql实现通用分页

    一.实体类或属性名与数据库关键字冲突问题1.实体类名与数据库中的关键字冲突比如:实体表User与oracle中的系统表冲突解决方式1:在xml中添加table属性,指定表名,使其不与name默认相等 [html] view plaincopyprint? <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hiber

    JSP自定义分页标签TAG

    首先我们需要在WEB-INF/tld/目录下创建page.tld文件 <?xml version="1.0" encoding="ISO-8859-1"?> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>page</short-name> <u