形式: 共xx条记录 共xx页 首页 上一页 1 2 3 4 5 下一页 尾页
分页技术概述:
物理分页:
在 sql 查询时,从数据库只检索分页需要的数据
通常不同的数据库有着不同的物理分页语句
mysql 物理分页,采用 limit 关键字
例如,检索11-20条:select * from user limit 10,10; //第一个10 表示从第几条记录开始,第二个10 表示查出10条来
逻辑分页:基本不用,因为占内存,而且元数据库变化后,逻辑内存中的数据不会变化
在 sql 查询时,先从数据库检索出所有数据的结果集
在程序内,通过逻辑语句获得分页需要的数据
例如,检索11-20条 userList.subList(10,20)
在 index.jsp 中添加分页查询:
<a href="${pageContext.request.contextPath}/PageCustServlet? thispage=1">分页查询客户</a>
创建 Page.java 中:
public class Page {
private int thispage; // 当前页
private int rowperpage; // 每页记录数
private int countrow; // 一共多少行
private int countpage; // 一共多少页
private int firstpage; // 首页
private int lastpage; // 尾页
private int prepage; // 上一页
private int nextpage; // 下一页
private List<Cust> list; // 当前页的 Cust 信息
封装……
}
在 PageCustServlet 中
public class PageCustServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
CustService service = BasicFactory.getFactory().getInstance(CustService.class);
//1.获取当前要显示的页和每页记录数
int thispage = Integer.parseInt(request.getParameter("thispage"));
int rowperpage = 5;
//2.调用Service中分页查询客户的方法,查找出客户信息
Page page = service.pageCust(thispage, rowperpage);
//3.存入request域中,带到pageList.jsp页面中进行显示
request.setAttribute("page", page);
request.getRequestDispatcher("/pageList.jsp").forward(request, response);
}
}
在 CustServiceImpl 中:
public Page pageCust(int thispage, int rowperpage) {
Page page = new Page();
//--当前页
page.setThispage(thispage);
//--每页记录数
page.setRowperpage(rowperpage);
//--共有多少行
int countrow = dao.getCountRow();
page.setCountrow(countrow);
//--共有多少页
int countpage = countrow/rowperpage+(countrow%rowperpage==0?0:1);
page.setCountpage(countpage);
//--首页
page.setFirstpage(1);
//--尾页
page.setLastpage(countpage);
//--上一页
page.setPrepage(thispage==1?1:thispage-1);
//--下一页
page.setNextpage(thispage == countpage ? countpage : thispage+1);
//--当前页数据
List<Cust> list = dao.getCustByPage((thispage-1)*rowperpage,rowperpage);
page.setList(list);
return page;
}
在 CustDaoImpl 中:
public int getCountRow() {
String sql = "select count(*) from customer";
try{
QueryRunner runner = new QueryRunner(DaoUtils.getSource());
return ((Long)runner.query(sql, new ScalarHandler())).intValue();
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public List<Cust> getCustByPage(int from, int count) {
String sql = "select * from customer limit ?,?";
try{
QueryRunner runner = new QueryRunner(DaoUtils.getSource());
return runner.query(sql, new BeanListHandler<Cust>(Cust.class), from, count);
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
在 pageList.jsp 中:
分页逻辑:
if(总页码 <= 5){
显示所有页码
}else{
if(当前页码 <=3){
显示 1 到 5
}else if(当前页码>= 总页码-2){
总页码-4 到 总页码
}else{
当前页码 -2 到 当前页码 +2
}
}
<html>
<head>
<script type="text/javascript">
function changePage(obj){
if(isNaN(obj.value)){
alert("必须是数字!");
obj.value=${page.thispage}
return;
}else if(obj.value<=0 || obj.value>${page.countpage} ){
alert("页码必须在有效范围内!");
obj.value=${page.thispage}
return;
}else{
window.location.href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage="+obj.value;
}
}
</script>
</head>
<body style="text-align: center;">
<h1>分页查询客户信息</h1><hr>
<table border="1" width="100%">
<tr>
<th>客户姓名</th>
<th>客户性别</th>
<th>出生日期</th>
<th>手机号码</th>
<th>电子邮箱</th>
<th>客户爱好</th>
<th>客户类型</th>
<th>描述信息</th>
<th>修改</th>
<th>删除</th>
</tr>
<c:forEach items="${requestScope.page.list}" var="cust">
<tr>
<td><c:out value="${cust.name }"/></td>
<td><c:out value="${cust.gender }"/></td>
<td><c:out value="${cust.birthday }"/></td>
<td><c:out value="${cust.cellphone }"/></td>
<td><c:out value="${cust.email }"/></td>
<td><c:out value="${cust.preference }"/></td>
<td><c:out value="${cust.type }"/></td>
<td><c:out value="${cust.description }"/></td>
<td><a href="${pageContext.request.contextPath }/servlet/CustInfoServlet?id=${cust.id }">修改</a></td>
<td><a href="${pageContext.request.contextPath }/servlet/DelCustServlet?id=${cust.id }">删除</a></td>
</tr>
</c:forEach>
</table>
共${page.countrow }条记录
共${page.countpage }页
<a href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage=${page.firstpage }">首页</a>
<a href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage=${page.prepage }">上一页</a>
<!-- 分页逻辑开始 -->
<c:if test="${page.countpage<=5}">
<c:set var="begin" value="1" scope="page"></c:set>
<c:set var="end" value="${page.countpage}" scope="page"></c:set>
</c:if>
<c:if test="${page.countpage>5}">
<c:choose>
<c:when test="${page.thispage<=3}">
<c:set var="begin" value="1" scope="page"></c:set>
<c:set var="end" value="5" scope="page"></c:set>
</c:when>
<c:when test="${page.thispage>=page.countpage-2}">
<c:set var="begin" value="${page.countpage-4}" scope="page"></c:set>
<c:set var="end" value="${page.countpage}" scope="page"></c:set>
</c:when>
<c:otherwise>
<c:set var="begin" value="${page.thispage-2}" scope="page"></c:set>
<c:set var="end" value="${page.this page+2}" scope="page"></c:set>
</c:otherwise>
</c:choose>
</c:if>
<c:forEach begin="${begin}" end="${end}" step="1" var="i">
<c:if test="${i == page.thispage}">
${i }
</c:if>
<c:if test="${i != page.thispage}">
<a href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage=${i}">${i }</a>
</c:if>
</c:forEach>
<!-- 分页逻辑结束 -->
<a href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage=${page.nextpage }">下一页</a>
<a href="${pageContext.request.contextPath }/servlet/PageCustServlet?thispage=${page.lastpage }">尾页</a>
跳到<input type="text" value="${page.thispage }" style="width: 40px" οnchange="changePage(this)"/>页
</body>
</html>