码迷,mamicode.com
首页 > 编程语言 > 详细

Java 分页

时间:2017-11-26 21:51:19      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:each   isp   不能   import   last   width   turn   begin   math   

1. 为什么要使用分页?

a) 当数据量比较大的时候, 一次性查找所有数据会带来一些问题

b) 数据库压力会比较大

c) 数据的显示会很慢, 造成用户体验度不高

d) 为了更方便的显示数据, 并且减小数据库的压力, 就会使用分页的技术

2. 如何实现分页查询

a) MySql中分页查询的实现方式

-- limit用于分页查询, 后面有两个数字

-- 第一个数字表示查询起始位置的索引(从0开始)

-- 第二个数字表示每次查询数据的个数

select * from emp limit 10,10;

 

-- 必须知道当前页数(page), 每页显示的条数(size)

-- select * from emp limit (page-1)*size,size;

3. 分页的代码实现

a) 定义分页实体类, 用于封装分页相关属性, 方便后续的分页实现, 代码如下(省略Getter和Setter方法)

package com.bjsxt.pojo;

 

import java.util.List;

 

public class Pagination<T> {

 

// 当前页数

private int page;

// 每页显示多少条数据

private int size;

// 总记录数

private int totalCount;

// 总页数

private int totalPage;

// 每次查询的起始位置

private int start;

// 是否有上一页

private boolean hasPrev;

// 上一页

private int prevPage;

// 是否有下一页

private boolean hasNext;

// 下一页

private int nextPage;

// 首页

private int firstPage;

// 尾页

private int lastPage;

// 分页导航块的个数

private int navCount;

// 导航的起始位置

private int navBegin;

// 导航的结束位置

private int navEnd;

// 查询结果对应的list集合

private List<T> list;

 

public Pagination(String page, String size, int totalCount) {

// 当前页数

this.page = null != page ? Integer.parseInt(page) : 1;

// 每页显示多少条数据

this.size = null != size ? Integer.parseInt(size) : 10;

// 总记录数

this.totalCount = totalCount;

// 总页数

this.totalPage = (int) Math.ceil(this.totalCount * 1.0 / this.size);

// 当前页数不能大于总页数

if(this.page > this.totalPage && this.totalPage > 0) {

this.page = this.totalPage;

}

// 每次查询的起始位置

this.start = (this.page - 1) * this.size;

if (this.page > 1) {

// 是否有上一页

this.hasPrev = true;

// 上一页

this.prevPage = this.page - 1;

}

if (this.page < this.totalPage) {

// 是否有下一页

this.hasNext = true;

// 下一页

this.nextPage = this.page + 1;

}

// 首页

this.firstPage = 1;

// 尾页

this.lastPage = this.totalPage;

// 分页导航块的个数

this.navCount = 10;

// 导航的起始位置

// if (this.page > this.totalPage - this.navCount) {

// this.navBegin = this.totalPage - this.navCount + 1;

// } else {

this.navBegin = this.page - this.navCount / 2 < 1 ? 1 : this.page - this.navCount / 2;

// }

// 导航的结束位置

this.navEnd = this.navBegin + this.navCount - 1 > this.totalPage ? this.totalPage

this.navBegin + this.navCount - 1;

}

// 省略getter和setter方法

}

 

b) 在实体类中, 提供了一个构造器, 有三个参数, 分别为当前页page, 每页显示条数size和总记录数totalCount, 提供这三个参数, 是因为只要知道了这三个数据, 分页相关的其他数据都可以确定

c) 分页实体类的使用, 在Servlet中接收相关参数, 封装为实体类对象, 之后调用service, service再调用dao即可, 代码如下:

public void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String page = req.getParameter("page");

String size = req.getParameter("size");

int totalCount = es.queryCount();

// 创建分页对象

Pagination<Emp> p = new Pagination<Emp>(page, size, totalCount);

// 调用service中的方法, 完成后查询的结果自动设置到p对象中

es.queryAll(p);

    // 将p对象存储到作用域中, 方便jsp中使用

req.setAttribute("p", p);

// 请求转发

req.getRequestDispatcher("/emplist.jsp").forward(req, resp);

}

@Override

public void queryAll(Pagination<Emp> p) {

    // 调用dao

dao.queryAll(p);

}

@Override

public void queryAll(Pagination<Emp> p) {

p.setList(query(Emp.class, "select * from emp limit ?,?", p.getStart(), p.getSize()));

}

d) jsp中分页的实现代码

为您查询到 <font color="blue">${p.totalCount }</font> 条记录, 当前第 <font color="blue">${p.page }</font> 页, 共有 <font color="blue">${p.totalPage }</font> 页

<table>

<tr>

<td>编号</td>

<td>姓名</td>

<td>薪资</td>

<td>入职日期</td>

<td>操作</td>

</tr>

<c:forEach items="${p.list }" var="e">

<tr>

<td>${e.empno }</td>

<td>${e.ename }</td>

<td>${e.sal }</td>

<td>${e.hiredate }</td>

<td><a href="query.sxt?op=queryByEmpno&empno=${e.empno }&page=${p.page}&size=${p.size}">修改</a> / <a href="query.sxt?op=deleteEmp&empno=${e.empno }&page=${p.page}&size=${p.size}" onclick="return confirm(‘确定删除吗?‘);">删除</a></td>

</tr>

</c:forEach>

</table>

<a href="query.sxt?op=queryAll&page=${p.firstPage }&size=${p.size}">首页</a> |

<a href="query.sxt?op=queryAll&page=${p.prevPage }&size=${p.size}" onclick="return ${p.hasPrev?true:false}">上一页</a> |

<c:forEach begin="${p.navBegin }" end="${p.navEnd }" var="each">

<c:choose>

<c:when test="${p.page==each }">

<a href="query.sxt?op=queryAll&page=${each }&size=${p.size}"><font color="red" size="5">${each }</font></a> 

</c:when>

<c:otherwise>

<a href="query.sxt?op=queryAll&page=${each }&size=${p.size}">${each }</a> 

</c:otherwise>

</c:choose>

</c:forEach> |

<a href="query.sxt?op=queryAll&page=${p.nextPage }&size=${p.size}" onclick="return ${p.hasNext?true:false}">下一页</a> |

<a href="query.sxt?op=queryAll&page=${p.lastPage }&size=${p.size}">尾页</a>

4. 在删除中, 分页遇到的问题

a) 删除成功后, 如何继续停留在当前页面. 可以在删除时携带当前页数和每页显示记录数, 代码如下

<a href="query.sxt?op=deleteEmp&empno=${e.empno }&page=${p.page}&size=${p.size}" onclick="return confirm(‘确定删除吗?‘);">删除</a>

b) 删除最后一页的最后一条数据后, 保证回到前一页. 其实就是要求当前页数不能大于总页数, 并且总页数要大于0.

// 当前页数不能大于总页数

if(this.page > this.totalPage && this.totalPage > 0) {

this.page = this.totalPage;

}

5. 在修改中分页问题

a) 保证修改后留在当前页, 因为要跳转两个页面, 所以需要传值两次

<a href="query.sxt?op=queryByEmpno&empno=${e.empno }&page=${p.page}&size=${p.size}">修改</a>

<input type="hidden" name="page" value="${param.page }" />

<input type="hidden" name="size" value="${param.size }" />

Java 分页

标签:each   isp   不能   import   last   width   turn   begin   math   

原文地址:http://www.cnblogs.com/dudadi/p/7900431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!