通用分页.

通用分页
一、核心思想:将上一次查询请求再发一次,只不过页码变了
二、分页三要素:(PageBean)
page 页码 视图层传递过来
rows 页大小 视图层传递过来
total 总记录数 后台查出来
三、后台
entity
dao
四、视图层:(PageTag)

1、准备工作:
导入jar包:

2、建包建类:

3、utils包里的各个类,都有各自不同的作用:
连接数据库—DBAccess

package com.xieying.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 提供了一组获得或关闭数据库对象的方法
 * 
 */
public class DBAccess {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;

    static {// 静态块执行一次,加载 驱动一次
        try {
            InputStream is = DBAccess.class
                    .getResourceAsStream("config.properties");

            Properties properties = new Properties();
            properties.load(is);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("pwd");

            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 获得数据连接对象
     * 
     * @return
     */
    public static Connection getConnection() {
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void close(ResultSet rs) {
        if (null != rs) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    public static void close(Statement stmt) {
        if (null != stmt) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    public static void close(Connection conn) {
        if (null != conn) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        close(rs);
        close(stmt);
        close(conn);
    }

    public static boolean isOracle() {
        return "oracle.jdbc.driver.OracleDriver".equals(driver);
    }

    public static boolean isSQLServer() {
        return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
    }
    
    public static boolean isMysql() {
        return "com.mysql.jdbc.Driver".equals(driver);
    }

    public static void main(String[] args) {
        Connection conn = DBAccess.getConnection();
        DBAccess.close(conn);
        System.out.println("isOracle:" + isOracle());
        System.out.println("isSQLServer:" + isSQLServer());
        System.out.println("isMysql:" + isMysql());
        System.out.println("数据库连接(关闭)成功");
    }
}

package com.xieying.utils;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 中文乱码处理
 * 
 */
@WebFilter(filterName="encodingFilter",urlPatterns="*.action")
public class EncodingFilter implements Filter {

    private String encoding = "UTF-8";// 默认字符集

    public EncodingFilter() {
        super();
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        // 中文处理必须放到 chain.doFilter(request, response)方法前面
        res.setContentType("text/html;charset=" + this.encoding);
        if (req.getMethod().equalsIgnoreCase("post")) {
            req.setCharacterEncoding(this.encoding);
        } else {
            Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
            Set set = map.keySet();// 取出所有参数名
            Iterator it = set.iterator();
            while (it.hasNext()) {
                String name = (String) it.next();
                String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
                for (int i = 0; i < values.length; i++) {
                    values[i] = new String(values[i].getBytes("ISO-8859-1"),
                            this.encoding);
                }
            }
        }

        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
        if (null != s && !s.trim().equals("")) {
            this.encoding = s.trim();
        }
    }

}

package com.xieying.utils;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *
 */
public class PageBean {

    private int page = 1;// 页码

    private int rows = 10;// 页大小

    private int total = 0;// 总记录数
    
    //上一次查询的URL
    private String url;
    
    //上一次查询所携带的查询条件
    private Map<String, String[]> parameterMap=new HashMap<String, String[]>();
    
    //对pagebean进行初始化
    public void setRequest(HttpServletRequest req) {
        //初始化jsp界面传递过来的当前页
        this.setPage(req.getParameter("page"));
        //初始化jsp界面传递过来的页大小
        this.setRows(req.getParameter("rows"));
        //初始化jsp页面传递过来是否分页
        this.setPagination(req.getParameter("pagination"));
        //保留上一次的查询请求
        this.setUrl(req.getRequestURL().toString());
        //保留上一次的查询条件
        this.setParameterMap(req.getParameterMap());
        
    }
    
    private void setPagination(String pagination) {
        //
    }
    
    private void setRows(String rows) {
        if(StringUtils.isNotBlank(rows)) {
            this.setRows(Integer.valueOf(rows));
        }
    }
    
    private void setPage(String page) {
        if(StringUtils.isNotBlank(page)) {
            this.setPage(Integer.valueOf(page));
        }
    }
    
    private boolean pagination = true;// 是否分页

    public PageBean() {
        super();
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public void setTotal(String total) {
        this.total = Integer.parseInt(total);
    }

    public boolean isPagination() {
        return pagination;
    }

    public void setPagination(boolean pagination) {
        this.pagination = pagination;
    }

    
    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Map<String, String[]> getParameterMap() {
        return parameterMap;
    }

    public void setParameterMap(Map<String, String[]> parameterMap) {
        this.parameterMap = parameterMap;
    }

    /**
     * 获得起始记录的下标
     * 
     * @return
     */
    public int getStartIndex() {
        return (this.page - 1) * this.rows;
    }

    @Override
    public String toString() {
        return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
    }

    //上一页
    public int getPrevPage() {
        return this.page > 1 ? this.page -1 : this.page;
    }
    //下一页
    public int getNextPage() {
        return this.page < this.getMaxPage() ? this.page + 1 : this.page;
    }
    
    //最大页
    public int getMaxPage() {
        return this.total % this.rows == 0 ? this.total / this.rows : (this.total / this.rows) + 1;
        
    }
    
}

package com.xieying.entity;

public class Book {
    private int bid;
    private String bname;
    private float price;

    @Override
    public String toString() {
        return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
    }

    public int getBid() {
        return bid;
    }

    public void setBid(int bid) {
        this.bid = bid;
    }

    public String getBname() {
        return bname;
    }

    public void setBname(String bname) {
        this.bname = bname;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public Book(int bid, String bname, float price) {
        super();
        this.bid = bid;
        this.bname = bname;
        this.price = price;
    }

    public Book() {
        
    }
    
}

package com.xieying.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.xieying.entity.Book;
import com.xieying.utils.BaseDao;
import com.xieying.utils.DBAccess;
import com.xieying.utils.PageBean;
import com.xieying.utils.StringUtils;

public class BookDao extends BaseDao<Book>{
    
    //通过反射改装后的通过分页的写法
    public List<Book> list(Book b,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
        String sql="select * from t_mvc_book where true";
        String bname=b.getBname();
        if(StringUtils.isNotBlank(bname)) {
            sql +=" and bname like '%"+bname+"%'";
        }
        return super.executeQuery(Book.class,sql, pagebean);
    }
    
    public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException {
        BookDao bd=new BookDao();
        Book b=new Book();
        b.setBname("绝望教室");
        PageBean pb=new PageBean();
        pb.setPage(2);
        pb.setPagination(false);
        
        List<Book> list = bd.list(b, pb);
        for (Book book : list) {
            System.out.println(book);
        }
        System.out.println(pb);
    }
    
    
}

package com.xieying.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.xieying.entity.Book;

public class BaseDao<T> {

    public List<T> executeQuery(Class clz, String sql,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
        List<T> list=new ArrayList<T>();
        Connection con = DBAccess.getConnection();
        PreparedStatement ps=con.prepareStatement(sql);
        ResultSet rs=ps.executeQuery();
        
        if(pagebean !=null &&pagebean.isPagination()) {
            //想要分页-->列表需求
            //查询出符合分页的总记录数
            String countSql=getCountSql(sql);
            ps=con.prepareStatement(countSql);
            rs=ps.executeQuery();
            if(rs.next()) {
                pagebean.setTotal(rs.getObject(1).toString());
            }
            //展示想要看到的数据,就比如说第三页的第十条数据
            String pageSql=getPageSql(sql,pagebean);
            ps=con.prepareStatement(pageSql);
            rs=ps.executeQuery();
        }else {
            //不想分页-->下拉需求
            ps=con.prepareStatement(sql);
            rs=ps.executeQuery();
        }
        
        
        
        while(rs.next()) {
            //list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
            /**
             * Book b=new Book();
             * b.setBid(rs.getInt("bid"));
             * b.setBname(rs.getString("bname"));
             * b.setPrice(rs.getFloat("price"));
             * list.add(b);
             * 
             * 实例化了一个对象
             * 给这一个空对象的每一个属性赋值
             * 将赋值完的对象添加到list集合中返回
             */
                T t=(T)clz.newInstance();
                Field[] declaredFields = clz.getDeclaredFields();//拿到所有属性对象
                for (Field f : declaredFields) {
                    f.setAccessible(true);
                    f.set(t, rs.getObject(f.getName()));
                }
                list.add(t);
        }
        DBAccess.close(con, ps, rs);
        return list;
    }

    private String getPageSql(String sql, PageBean pagebean) {

        return sql + " limit "+pagebean.getStartIndex()+","+pagebean.getRows();
    }

    private String getCountSql(String sql) {
        
        return "select count(1) form ("+sql+") t";
    }
    
    /**
     * sql=select * from t_mvc_book where true and bname like '"绝望"'
     * countSql=select count(1) form (select * from t_mvc_book where true and bname like '"绝望"')
     * pageSql=select * from t_mvc_book where true and bname like '"绝望"' limit 10,10
     * 
     */
    
    
    
    
}

package com.xieying.tag;

import java.util.Map;
import java.util.Set;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.xieying.utils.PageBean;

public class PageTag extends BodyTagSupport{

    private static final long serialVersionUID = 5173138912016761869L;

    private PageBean pagebean;

    public PageBean getPagebean() {
        return pagebean;
    }

    public void setPagebean(PageBean pagebean) {
        this.pagebean = pagebean;
    }
    
    @Override
    public int doStartTag() throws JspException {
        JspWriter out=pageContext.getOut();
        try {
            out.print(toHTML());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return super.doStartTag();
    }

    private String toHTML() {
        StringBuilder sb = new StringBuilder();

//        这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
        sb.append("<form id='pageBeanForm' action='"+pagebean.getUrl()+"' method='post'>");
        sb.append("<input type='hidden' name='methodName' value='list'>");
        sb.append("<input type='hidden' name='page'>");
//        重要设置拼接操作,将上一次请求参数携带到下一次
        Map<String, String[]> paMap = pagebean.getParameterMap();
        if(paMap !=null && paMap.size()>0){
            Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
            for (Map.Entry<String, String[]> entry : entrySet) {
                if (!"page".equals(entry.getKey()) ) {
                    for(String val : entry.getValue()){
                        sb.append("<input type='hidden'  value='"+val+"' name='"+entry.getKey()+"'>");
                    }
                }
            }
        }
        sb.append("</form>");

        //默认展示前四页,当前页,后面5页
        int page = pagebean.getPage();
        int max = pagebean.getMaxPage();
        int before = page > 4 ? 4 : page-1;
        int after = 10 - 1 - before;
        after = page+after > max ? max-page : after;
        //用来控制下一页的点击控制特效的
        boolean afterFlag = page > 1;
        //用来控制上一页的点击控制特效的
        boolean startFlag = page < max;
       

        //拼接分页条
        sb.append("<ul class='pagination'>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pagebean.getPrevPage()+")'>&lt;</a></li>");

//        代表了当前页的前4页
        for (int i = before; i > 0 ; i--) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page-i)+")'>"+(page-i)+"</a></li>");
        }

        sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage("+pagebean.getPage()+")'>"+pagebean.getPage()+"</a></li>");

//        代表了当前页的后5页
        for (int i = 1; i <= after; i++) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page+i)+")'>"+(page+i)+"</a></li>");
        }

        sb.append("<li class='page-item "+(afterFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pagebean.getNextPage()+")'>&gt;</a></li>");
        sb.append("<li class='page-item "+(afterFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pagebean.getMaxPage()+")'>尾页</a></li>");
        sb.append("<li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页</b></li>");
        sb.append("<li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
        sb.append("<li class='page-item'><b>共"+pagebean.getTotal()+"条</b></li>");
        sb.append("</ul>");

//        拼接分页的js代码
        sb.append("<script type='text/javascript'>");
        sb.append("function gotoPage(page) {");
        sb.append("document.getElementById('pageBeanForm').page.value = page;");
        sb.append("document.getElementById('pageBeanForm').submit();");
        sb.append("}");
        sb.append("function skipPage() {");
        sb.append("var page = document.getElementById('skipPage').value;");
        sb.append("if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > "+max+") {");
        sb.append("alert('请输入1~N的数字');");
        sb.append("return;");
        sb.append("}");
        sb.append("gotoPage(page);");
        sb.append("}");
        sb.append("</script>");

        return sb.toString();
    }
}


BookAction

package com.xieying.web;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.xieying.dao.BookDao;
import com.xieying.entity.Book;
import com.xieying.utils.PageBean;

@WebServlet(name="book",urlPatterns="/book.action")
public class BookAction extends HttpServlet{

    private static final long serialVersionUID = 7857580259883137815L;
    private BookDao bd=new BookDao();
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doPost(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        Book b=new Book();
        b.setBname(req.getParameter("bname"));
        PageBean pagebean =new PageBean();
        pagebean.setRequest(req);
        try {
            List<Book> list=this.bd.list(b, pagebean);
            req.setAttribute("booklist", list);
            req.setAttribute("pagebean", pagebean);
            req.getRequestDispatcher("/booklist.jsp").forward(req, resp);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
    }
            
    
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
   <%@taglib prefix="x" uri="/xieying" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">              
    .page-item input {
    padding: 0;
    width: 40px;
    height: 100%;
    text-align: center;
    margin: 0 6px;
}

.page-item input,
.page-item b {
    line-height: 38px;
    float: left;
    font-weight: 400;
}

.page-item.go-input {
    margin: 0 10px;
}
    
</style>
</head>
<body>

<form class="form-inline" action="${pageContext.request.contextPath }/book.action" method="post">
  <div class="form-group mb-2">
    <input type="text" readonly class="form-control-plaintext" id="bname" placeholder="请输入书籍名称">
  </div>
  <button type="submit" class="btn btn-primary mb-2">查询</button>
</form>
    <table class="table table-striped">
  <thead>
    <tr>
      <th scope="col">书籍</th>
      <th scope="col">书名 </th>
      <th scope="col">价格</th>
    </tr>
  </thead>
  
  
  <tbody>
  <c:forEach var="b" items="${bookList }">
      <tr>
      <td>${b.bid }</td>
      <td>${b.bname }</td>
      <td>${b.price }</td>
    </tr>
  </c:forEach>
   
    
  </tbody>
</table>


    <x:page pageBean="${pageBean }"></x:page>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值