分页

实现思路

QQ截图20160725151218.png

分页语法

select ..... limit 参数1,参数2;
参数1 ,表示开始索引,从0开始。startIndex  ,算法 (pageNum - 1) * pageSize
参数2 ,表示每页显示个数。pageSize

Servlet的写法

/**
 * 查询所有--分页查询
 */
private void findAllWithPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    try {
        // 1.获得数据并封装
        // 获得当前页码
        String pageNumStr = request.getParameter("pageNum");
        int pageNum = 1;
        try {
            // 这种处理方式可以防止在地址栏里面输入非数字导致转化异常
            pageNum = Integer.parseInt(pageNumStr);
        } catch (Exception e){
        }

        // * 每页显示个数(固定值)
        int pageSize = 5;
        // 2.通知service查询所有
        CustomerServeice customerServeice = new CustomerServiceImpl();
        PageBean<Customer> pageBean = customerServeice.findAllCustomerWithPage(pageNum, pageSize);

        // 3.显示
        // 存放到request作用域中--每一次查询都是新的数据
        request.setAttribute("pageBean",pageBean);
        // servlet到jsp中显示,一次请求需要使用请求转发
        request.getRequestDispatcher("/pages/show_all_page.jsp").forward(request,response);
    } catch (Exception e){
        // 1.打印日志
        e.printStackTrace();
        // 2.请求转发到消息界面
        request.setAttribute("msg","查询失败,请稍后重试.");
        request.getRequestDispatcher("/pages/message.jsp").forward(request,response);
    }
}

Service写法

@Override
public PageBean<Customer> findAllCustomerWithPage(int pageNum, int pageSize) {
    // 一般分页的逻辑是要在service里面来写
    // 创建PageBean封装分页所有的数据,并将封装后的数据返回

    // 1.查询总记录数
    int totalRecord = customerDao.getTotalRecord();
    // 2.创建PageBean
    PageBean<Customer> pageBean = new PageBean<>(pageNum,pageSize,totalRecord);
    // 3.查询结果
    List<Customer> data = customerDao.findAll(pageBean.getStartIndex(), pageBean.getPageSize());
    pageBean.setData(data);
    return pageBean;
}

Dao写法

@Override
public List<Customer> findAll(int startIndex, int pageSize) {
    try {
        String sql = "select * from t_customer limit ?,?";
        Object[] params = {startIndex,pageSize};
        return runner.query(sql,new BeanListHandler<Customer>(Customer.class),params);
    } catch (Exception e){
        throw new DaoException(e);
    }
}

JSP界面

当前${pageBean.pageNum}页,共${pageBean.totalPage}页,总条数${pageBean.totalRecord}条<br/>

<c:url value="${pageContext.request.contextPath}/CustomerServlet" var="baseUrl">
    <c:param name="method" value="findAllWithPage"></c:param>
    <c:param name="pageNum" value=""></c:param>
</c:url>
<c:if test="${pageBean.pageNum > 1}">
    <a href="${baseUrl}1">首页</a>
    <a href="${baseUrl}${pageBean.pageNum-1}">上一页</a>
</c:if>
<c:forEach begin="${pageBean.start}" end="${pageBean.end}" var="num">
    <a href="${baseUrl}${num}">${num}</a>
</c:forEach>
<c:if test="${pageBean.pageNum < pageBean.totalPage}">
    <a href="${baseUrl}${pageBean.pageNum+1}">下一页</a>
    <a href="${baseUrl}${pageBean.totalPage}">尾页</a>
</c:if>

PageBean的封装

/**
 * 分页的封装类
 *      封装的两种思路:
 *          -- 集合Map(Android中常见的请求参数的封装)
 *          -- 自定义JavaBean对象
 * Created by lujiahao on 2016/7/25.
 */
public class PageBean<T> {

    // 分页必备选项,为下面计算提供数据
    private int pageNum;            // 当前页(第几页)
    private int pageSize;           // 每页显示个数
    private int totalRecord;        // 总记录数(总条数)---这个数据需要通过查询来获得

    // 通过计算获得的数据
    private int startIndex;         // 分页开始的索引
    private int totalPage;          // 总分页数

    // 分页查询的结果
    private List<T> data;           // 查询分页的数据--使用泛型的目的是为了方便复用

    // 导航条动态显示  首页 上一页 1 2 3 4 下一页 尾页
    private int start;              // 循环开始
    private int end;                // 循环结束

    public PageBean(int pageNum, int pageSize, int totalRecord) {
        // 构造方法中初始化三个必备选项
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;

        // 处理地址栏输入负页数
        if (this.pageNum < 1) {
            this.pageNum = 1;
        }

        // 计算分页开始的索引:(当前页 - 1) * 每页显示个数
        this.startIndex = (this.pageNum - 1) * this.pageSize;

        // 计算总分页数
        if (this.totalRecord % this.pageSize == 0){
            // 能整除,总分页数 = 总记录数 / 每页显示个数
            this.totalPage = this.totalRecord / this.pageSize;
        } else {
            // 不能整除,需要加一页用来存不够一页的数据
            this.totalPage = this.totalRecord / this.pageSize + 1;
        }
        // 上面的快捷算法---暂时理解不了啊
        //this.totalPage = (this.totalRecord + (this.pageSize - 1)) / this.pageSize;

        // 导航条动态显示  默认显示10页
        this.start = 1;
        this.end = 10;
        // 总页数不够10页
        if (this.totalPage <= 10){
            this.end = this.totalPage;
        } else {
            // 总页数大于10页
            // 页数要求 前五后四
            this.start = this.pageNum -5;
            this.end = this.pageNum +4;

            // 当pageNum=1时,其实页数至少是1
            if (this.start < 1){
                this.start = 1;
                this.end = 10;
            }

            // 当pageNum到最后一页事
            if (this.end > this.totalPage){
                this.end = this.totalPage;
                this.start = this.totalPage -9; // 9 = 5 + 4
            }
        }
    }
    ...get/set
}

注意点

容错的处理非常巧妙:
这是在Servlet中的处理方式

String pageNumStr = request.getParameter("pageNum");
int pageNum = 1;
try {
    // 这种处理方式可以防止在地址栏里面输入非数字导致转化异常
    pageNum = Integer.parseInt(pageNumStr);
} catch (Exception e){
}

这是在PageBean中的处理方式

// 处理地址栏输入负页数
if (this.pageNum < 1) {
    this.pageNum = 1;
}