当查询结果过多时,服务器需要更多的时间进行处理并返回数据;如果不使用分页技术,服务器会将查找到的数据一次性全返回给用户端,浏览器(用户端)加载全部数据的过程是很浪费资源与时间的;而分页技术则能很好的解决这个问题;分页可将服务器返回的数据分段展示给用户,不必一次返回全部数据,仅将用户查询的当页数据或上一页或下一页数据展示给用户;既提高了服务器响应的效率,减少了响应时间;又提升了用户体验,一举两得;
这篇博客简述一下分页的实现过程;我们要创建的浏览器用户端的界面是这样的;
其功能为:
-
第一次访问会显示前三条数据;
-
用户可通过上一页按钮浏览本页面之前的3条数据,当本页面处于第一页时,点击上一页按钮会提示相关信息;
-
用户可通过下一页按钮浏览本页面之后的3条数据,当本页面处于最后一页时,点击下一页按钮会提示相关信息;
-
用户可通过模糊查询(表格上面输入查询条件,点击搜索按钮)查询想要了解的数据;
首先在MySQL数据库中创建这么一个表:(后文查询用)
每三条数据分为一页,并在分页的基础上建立模糊查询功能;
在三级联动里已有很详细的准备工作(准备必要的jar包),这里不再详述,直接看代码;
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./js/jquery-1.8.3.min.js"></script>
</head>
<body>
<form>
<input name="name" placeholder="按名字搜索"/>
<input name="address" placeholder="按住址搜索"/>
<input type="button" value="搜索" onclick="search()"/>
</form>
<div id="data"></div>
<input type="button" value="上一页" onclick="up()"/><input type="button" value="下一页" onclick="down()"/>
<script>
var pageNo=1; //默认从第一页开始
var pageTotal=0; //默认总页数为0
function up(){
if(pageNo==1){
alert("当前已是首页!");
return;
}
pageNo--;
page();
}
function down(){
if(pageTotal==pageNo){ //总页数若等于当前页数,则为最后一页
alert("当前已是最后一页!");
return;
}
pageNo++;
page();
}
function page(){
var path= "./DataServlet?pageNo="+pageNo; //路径及传入参数
var name=$("[name='name']").val(); //获取模糊查询的条件,下一行代码同理
var address=$("[name='address']").val();
if(name!="" && name!=undefined){ //用户输入了模糊查询的条件
path=path+"&name="+name; //将模糊查询的条件添加到path中
}
if(address!="" && address!=undefined){ //同上
path=path+"&address="+address;
}
console.log(path);
var object={ //进行异步处理
url:path, //路径及传入值
success:function(data){
console.log(data);
$("#data").html(data); //将返回数据插入到id="data"的标签内
pageTotal=$("#pageTotal").val(); //获取总页数
}
}
$.ajax(object);
}
function search(){
pageNo=1; //重置当前页数,使每次查询都从第一页开始
page();
}
page();
</script>
</body>
</html>
DataServlet.java
package com.jd.servlet;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jd.vo.UserInfo;
import db.DBUtil;
import db.IRowMapper;
public class DataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name=request.getParameter("name");
String address=request.getParameter("address");
String where="where 1=1 "; //方便name和address判断语句的连接
if(name!=null) { //模糊查询,添加通配符
where=where+"and name like '%"+name+"%'";
}
if(address!=null) { //模糊查询,添加通配符
where=where+"and address like '%"+address+"%'";
}
int pageNo=Integer.parseInt(request.getParameter("pageNo"));
int pageSize=3; //每页显示的数据数量
class ListRowMapper implements IRowMapper{
List<UserInfo> list =new ArrayList<UserInfo>();
public void rowMapper(ResultSet resultSet) {
try {
while(resultSet.next()) {
list.add(new UserInfo(resultSet.getInt("id"),resultSet.getString("name"),resultSet.getString("mobile"),resultSet.getString("address")));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
ListRowMapper rowMapper = new ListRowMapper();
String sql = "select * from user_info "+where+" limit "+(pageNo-1)*pageSize+","+pageSize;
System.out.println(sql);
DBUtil.select(sql, rowMapper);
request.setAttribute("userInfoes",rowMapper.list );
class CountRowMapper implements IRowMapper{
List<UserInfo> list =new ArrayList<UserInfo>();
int count;
public void rowMapper(ResultSet resultSet) {
try {
if(resultSet.next()) {
count=(resultSet.getInt("count"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
CountRowMapper countRowMapper = new CountRowMapper();
sql="select count(id) count from user_info "+where;
System.out.println(sql);
DBUtil.select(sql, countRowMapper); //调用DBUtil中select方法
int count=countRowMapper.count;
int pageTotal = count%pageSize==0?count/pageSize:count/pageSize+1; //每页三条数据,计算总页数
request.setAttribute("pageTotal", pageTotal);
request.getRequestDispatcher("data.jsp").forward(request, response);
}
}
data.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<style>
table,th,td{
border:black 1px solid;
}
table{
border-spacing:0px;
border-collapse:collapse;
}
</style>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>mobile</th>
<th>address</th>
<th>操作</th>
</tr>
<c:forEach var="users" items="${userInfoes }">
<tr>
<td>${users.id }</td>
<td>${users.name }</td>
<td>${users.mobile }</td>
<td>${users.address }</td>
<td><a>查看</a><a>编辑</a><a>删除</a></td>
</tr>
</c:forEach>
</table>
<input type="hidden" id="pageTotal" value="${pageTotal }"/>
index.jsp即使用户在浏览器看到的界面;原理如下:
1、浏览器直接请求index.jsp页面,该页面执行page()方法,此时pageNo的值为1 ------> 向 DataServlet.java 发送请求,并将pageNo的值传过去 ------> DataServlet接收到数据,并根据pageNo的值返回第几页数据和总页数,通过request的请求转发的方式转发到data.jsp中 ------> data.jsp 根据转发的数据建立表单,并将整张表单返回至index.jsp中 ------> index.jsp 使用 $("#data").html(data); 语句将data.jsp返回的整张表单添加到事先准备好的空的 <div id="data"></div> 标签中;并获取总页数;
2、点击下一页;用户点击下一页,下一页的按钮直接调用down()方法,方法判断当前页码是否是最后一页,是则提示并返回,不是则 pageNo+1 并调用page()方法 ------>执行过程回到第一步,只不过此时pageNo发生了变化;
3、点击上一页;用户点击上一页,上一页的按钮直接调用up()方法。方法判断当前页码是否是第一页,是则提示并返回,不是则 pageNo-1 并调用 page()方法 ------>执行过程回到第一步,只不过此时pageNo发生了变化;
4、用户输入模糊查询条件并点击搜索 ------> 调用search()方法,方法中重置当前页数为1并调用page()方法 ------> 执行过程回到第一步,只不过此时pageNo发生了变化;
注意:
1、本表格的查看、编辑和删除功能均未实现;
2、page()方法中会将模糊查询的条件一并随同path(添加到path中了)向DataServlet发送请求 ------> DataServlet 将模糊查询的条件 添加到select查询语句中进行查询,并将所有匹配的数据和页数请求转发至 data.jsp中。