分页是web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的,不可能把这么多的数据一次显示在浏览器上面。一般根据每行数据在页面上所占的空间每页显示若干行,比如一般20行是一个比较理想的显示状态。
分页的方法主要有以下两种思路:
(1)取出符合条件的数据,放到数据集或者内存当中,然后逐页浏览。例如,有可能每页只浏览20条记录,但使用这种分页方法需要把所有记录取出来。这种分页的方法叫做“指针分页”。指针分页法主要是利用数据集的指针(或者说集合的下标)来标识。比如分页要显示20条数据,那么第一页的指针从1开始,第二页的指针从(2-1)*20+1开始到2*20结束,依次类推。“指针分页”适合数据量和并发量不是很高的应用程序,不适合海量的数据查询。
(2)对于海量的数据查询,看多少就取多少,显然是最佳的解决方法,假如某个表中有200万条记录,第一页取前20条,第二页取21~40条记录。此时可以使用:
select top 当前页*每页记录数查询字段列表 from 表A where 主键字段 not in (select top (当前页-1)*当前页记录数主键字段 from 表A)
这样的语句来实现,因为这种查询方式要使用主键,所以叫他做“主键分页”。(mysql可以使用select * from admin limit 2,2进行分页查询,从主键id=2+1开始(索引从下标为0开始数,第二条,就是id=3这条),往后2条)
对于一个完整的分页,应当包括记录数、页数、当前页数、上一页、下一页、首页、最后一页等。所以,无论是指针分页还是主键分页。需获获得一个类似“select count(*) as 记录总数 from 表名”这样的语句,从而获得记录数。
为了简便起见,这里就以一个电子商城中的分页显示作为一个案例,采用指针分页法。在新品展示页面中需要在页面显示的是originalList对象中的商品,设计每页从originalList对象中位置start开始,显示至位置over(不包含over)结束,则分页的主要工作在于确定start和over
<%
for(int i = start; i<over; i++){
GoodEntity originalGoods = (GoodEntity)originalList.get(i);
}
%>
分页步骤
(1)取得originalList对象中的商品的总条数,存放在页面的变量pageNumber中,并将此值作为总页数的初始值后,根据每页显示商品的数量在进行修改:
int pageNumber = originalList.size();
int sum = pageNumber;//记录总数
(2)初始化一些必要的参数,其中request.getParameter("pageNumber")是使用request内置对象的getParameter方法获取参数名为pageNum的请求参数值,这里是用户要显示的页码。
<% String strNumber=request.getParameter("pageNumber");
int number = 0;//待显示的页码,默认为第一页 if(strNumber==null||strNumber.equals("0")){//表明在QueryString中没有pageNum这一个参数,此时显示第 //一页的数据 number=1; }else{ number = Integer.parseInt(strNumber);//取的待显示页码,将字符串转换成整数 } int count = 5;//每页显示的条数 int maxPage;//最大页数 if(sum%5==0){//一页显示的记录数,目前设计为5条 maxPage = sum/5;//最多页数,能整除的,结果为页数 }else{ maxPage = sum/5+1;//不能整除的,结果加1 } int start = (number-1)*count;//开始记录数 int end = number*count;//结束记录数 if(end>sum-1){ end = sum;//防止越界 } %>
(3)分页显示:
<%
for(int i = start; i<over; i++){
GoodEntity originalGoods = (GoodEntity)originalList.get(i);
}
%>
(4)显示分页导航:
<tr align="center" valign="top">
实现页面显示页码总数、记录总数、和当前页码数,上一页,下一页:
<td colspan="11">共<%=maxPage %>页
共<%=sum %>有条记录
当前是第<%=num %>页 <a href="showGoods.jsp?pageNumber=<%=number-1 %>">上一页</a> <a href="showGoods.jsp?pageNumber=<%=number+1 %>">下一页</a> </td>
</tr>
这个分页导航中,假如我们是上一页,那么就是“number-1”,有些人就疑惑,number-1,不是-1了吗?当最初页再上一页,又是怎么显示回第一页的?我们可以看看上面的一处代码:
if(strNumber==null||strNumber.equals("0")){
number=1;
就是这个判断语句,当我们第一次来访问的时候,strNumber是null的,number就会被赋值为1,到了显示那里(number-1)*count就是等于0,然而number的值依然是1,到了导航那里,点击了“上一页”,number-1就会等于0,变量值传递回本页面的request接收,因此strNumber.equals("0")条件符合,number=1,还是第1页,到了显示那里(number-1)*count还是等于0。其中的小妙处慢慢体会。
下面分享一个实例代码,是一个人才管理系统中的一个删除功能的页面,显示所有人才信息,提供删除按钮,其中也用到分页技术,不是上面说的例子,不过道理一样,大家可以参考一下下的:
<%@ page contentType="text/html; charset=gb2312" %> < %@page import="com.communal.UserDao"%> < %@page import="java.util.List"%> < %@page import="com.communal.UserEntity"%> < html> <head> <title>My JSP 'updateUser1.jsp' starting page</title> <style type="text/css"> body { background-image: url(../pic/56923.jpg); background-position: center center; } </style> </head> <!-- "javascript:if(window.confirm('是否确认删除?')){window.location.href = 'User.jsp?form_insert=2&userid.value';}"
--> <body rightmargin=""> <form action="User.jsp?form_insert=2" name="form_delete" method="post" onsubmit="return submitting()">
<table border = "1" align="center" cellpadding="10" cellspacing="2"> <tr><th colspan="11"><font size="+3">人才信息删除</font></th></tr>
<tr> <td>待删除的记录</td> <td>人才id</td> <td>姓名</td> <td>性别</td> <td>出生年月</td> <td>最高学位</td>
<td>来公司日期</td> <td>转正日期</td> <td>隶属部门</td> <td>个人兴趣</td> <td>专业特长</td> </tr>
<tr> <% UserDao dao = new UserDao(); List userList = dao.showUser(); %>
<% int num;//当前页 String p=request.getParameter("p"); if(p==null||p.equals("0")){ num=1; }else{ num = Integer.parseInt(p);
} int count = 5;//每页显示的条数 int maxp;//最大页数 int sum = userList.size();//记录总数 if(sum%6==0){ maxp = sum/5; }else{ maxp = sum/5+1; }
int start = (num-1)*count;//开始记录数 int end = num*count;//结束记录数 if(end>sum-1){ end = sum; } %>
<% for(int i = start; i < end; i++){ UserEntity showUserEntity = (UserEntity)userList.get(i); %> <td align="center">
<input type="checkbox" name="userid" id="userid" value="<%=showUserEntity.getId() %>" style="zoom:180%;"> </td>
<td><div><%=showUserEntity.getId() %></div></td> <td><div><%=showUserEntity.getName() %></div></td>
<td><div><%=showUserEntity.getSex() %></div></td> <td><div><%=showUserEntity.getBirth() %></div></td>
<td><div><%=showUserEntity.getDegree() %></div></td> <td><div><%=showUserEntity.getIn_date() %></div></td>
<td><div><%=showUserEntity.getTrans_date() %></div></td> <td><div><%=showUserEntity.getDept() %></div></td>
<td><div><%=showUserEntity.getInterest() %></div></td> <td><div><%=showUserEntity.getSpecialty() %></div></td>
<tr> <%} %> <tr> <td colspan="11" align="center"> <input type ="reset" value="重置" name="reset">
<input type = "submit" name="submit" value="删除" >
</td> </tr> <tr align="center" valign="top"> <td colspan="11">共<%=maxp %>页 共<%=sum %>有条记录 当前是第<%=num %>页
<a href="deleteUser.jsp?p=<%=num-1 %>">上一页</a> <a href="deleteUser.jsp?p=<%=num+1 %>">下一页</a> </td> </tr>
<tr> <td colspan="11" align="right"><a href="index.html" >返回子系统页面</a></td> </tr> </table> </form>
<script type="text/javascript"> function submitting(){ if(!window.confirm('是否确认删除?')){ return false; }
/* if(form_delete.userid.value==""){ alert("你没有选择删除任何人!"); return false; }*/ return true; } </script>
</body> < /html>