分页是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>
这个分页导航中,假如我们是上一页,那么就是“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" οnsubmit="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>