public class ArrayListHandler implements ResultSetHandler<List<Area>> {
/**
* 处理dao里面查询的结果集 rs
* @param rs 结果集
* @return
* @throws SQLException
*/
public List<Area> handle(ResultSet rs) throws SQLException{
//定义一个大的结果集
List<Area> areas = new ArrayList<Area>();
//定义一个小的实体对象
Area area = null;
//从结果集中取对应的字段
while(rs.next()){
area = new Area(rs.getString("code"), rs.getString("name"), rs.getInt("layer"));
areas.add(area);
}
return areas;
}
}
public List <Area>
handle(ResultSet rs) throws SQLException{注意这里在ArrayListHandler里面的定义的方法名字必须为handle,不能改成其他的名字,然后方法的参数是result set结果集
函数的具体过程和之前DAO方法里面一样。同时还要注意的是这里是通过columname来取value值的,所以在选rs.getstring()的时候应该注意选参数为string类型的
现在我们通过参数pagesize和curpage拿到了当前页面需要显示的信息
那么下面我们还需要拿到页面总数,通过area表中的总条数以及每页显示的条数来拿到页面总数
/**
* 得到页面总数
* @param pageSize 每页显示的条数
* @throws SQLException
*/
public Integer getPageCount(int pageSize){
String sql = " select ceil(count(1)/?) pageCount from area ";
try {
Map<String, Object> map = qr.query(JDBCUtil.getConnection(), sql , new MapHandler(),pageSize);
return ((BigDecimal)map.get("PAGECOUNT")).intValue();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
因为我们有了dbutils的工具类,这里我们同样只需要直接准备SQL语句,然后利用qr.query执行就可以了,注意这里因为我们还是要得到数据库的连接,所以要选择带有connection的qr.query的的方法,然后这里因为只有一条结果 pagecount,所以我们采用map<string,object>
来获取返回的查询结果。不过就算是多条数据也可以用map来接收,这样我们就不用在result handler里面重新写一个方法来处理query方法的结果集了,但是通过map获取到的value值是一个对象,我们要得到pagecount还得需要转化为int类型
但是object没有直接转为int类型的函数,还得需要先转为decimal对象,然后调用decimal的方法intvalue()来转为int类型
现在我们准备好了后台的所有数据,包括每页显示的数据,以及页面总数
那么现在我们来写前台的页面
这里我们调用bootstrap的方法来写前端的页面,注意这里的bootstrap文件需要添加到webroot的下一级文件下面,是webroot的子文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>分页</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="bootstrap-3.3.7-dist/js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/area.js"></script>
<link rel="stylesheet" type="text/css" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style type="text/css">
#page{
margin:50px
}
.pageInfo{
width:50%
}
</style>
</head>
<body>
<div id="page">
<div class = "pageInfo">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>地址编码</th>
<th>地址名称</th>
<th>地址等级</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="pageIndex">
<ul class="pagination">
<li class="active"><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li><a href="#">6</a></li>
<li><a href="#">7</a></li>
<li><a href="#">8</a></li>
<li><a href="#">9</a></li>
<li><a href="#">10</a></li>
</ul>
</div>
</div>
</body>
</html>
.pageInfo{50%}将表格的宽度设置为屏幕宽度的50%
这里用一个大的div将table和ul包起来,然后table和ul分别用一个div包起来
最大的div一般用id,然后两个小的div用class属性
接下来就是利用页面加载事件来显示第一页,
在js里面写一个页面加载事件,从servlet里面获取到第一页的数据,显示在jsp页面
在这之前我们需要先写一个servlet来从前台接收参数,然后从数据库从提取数据
从前台接收的数据包括当前的页数,curpage,以及pagesize
然后根据这两个参数从后台DAO里面取出对应页面的数据
//从js请求里面获取Ajax传递的参数pagesize curpage
int pageSize = Integer.parseInt(req.getParameter("pageSize")) ;
int curPage = Integer.parseInt(req.getParameter("curPage"));
通过req.parameter传递过来的参数都是string类型的,这里需要通过integer类的函数parseint()解析为int类型
//先将对象areaInfo转为JSON格式的数据
String areaInfo = new Gson().toJson(areas);
实例化一个Gson,调用tojson的方法,将对象areas转为json类型的字符串
//再将pagecount和area info合并成一个json对象
//JSON格式的对象是一个字符串,所以除了pageCount,areaInfo(变量)都是字符串(常量)
areaInfo ="{"pageCount:"+pageCount+"pageInfo:"+areaInfo}";
对于JSON类型的字符串areainfo,本身就是一个字符串,所以需要用一个双引号括起来,表示这是一个字符串,然后里面的JSON格式是需要{“key”: value}
样式的数据,所以里面的引号是一直需要保留的,所以需要一个斜杠进行一个转义
package com.cr.servlet;
import java.io.IOException;
import java.io.PrintWriter;
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.cr.dao.AreaDAO;
import com.cr.entity.Area;
import com.google.gson.Gson;
public class AreaPageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//请求和响应的乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//从js请求里面获取Ajax传递的参数pagesize curpage
int pageSize = Integer.parseInt(req.getParameter("pageSize")) ;
int curPage = Integer.parseInt(req.getParameter("curPage"));
//调用DAO的查询方法
AreaDAO ad = new AreaDAO();
//当前的页面信息
List<Area> areas = ad.getAreaInfo(pageSize, curPage);
//获取页面总数
Integer pageCount = ad.getPageCount(pageSize);
//将查询的数据返回给页面
//这里返回的数据相当于有两张表
//一张是当前的页面信息,一张是页面的总数
//我们需要将之合并成一个JSON对象通过resp返回到页面
//先将对象areaInfo转为JSON格式的数据
String areaInfo = new Gson().toJson(areas);
//再将pagecount和area info合并成一个json对象
//JSON格式的对象是一个字符串,所以除了pageCount,areaInfo(变量)都是字符串(常量)
areaInfo ="{"pageCount:"+pageCount+"pageInfo:"+areaInfo}";
//准备好返回的数据还需要利用resp设置返回数据的格式为json格式
resp.setContentType("text/json");
//这里我们不仅要返回,还需要将返回的数据打印到当前的页面
//所以这里我们还需要resp设置一个输出的函数
PrintWriter out = resp.getWriter();
//将areainfo输出
out.print(areaInfo);
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
这里重新了两个方法分别是dopost和doget,用来处理客户端页面的请求
我们主要是在dopost里面写的方法,然后在doget里面调用dopost方法
实现的是和dopost里面一样的方法
只是为了防止页面如果采用的是get方式的请求,就可以调用doget方法,然后doget方法继续调用dopost方法
这里我们已经将数据返回回来了,那么在页面就需要通过Ajax来对servlet返回的数据进行接收,然后在页面显示出来
Ajax百度百科
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。
AJAX 是一种用于创建快速动态网页的技术。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。[1]
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。
这里我们利用Ajax的异步刷新以及部分刷新的功能实现页面信息的替换过程,点击不同的页面,就替换当前页面的信息
//发送请求
function sendPageAjax(){
$.post("AreaPageServlet",{"pageSize":pageSize,"curPage":Curpage},function(data){
});
}
在js里面利用jQuery.post()发送请求,里面的参数包括三部分,第一个是请求数据的地址,也就是我们的servlet,第二个是传递的参数,这里需要传入两个参数一个是pagesize,一个是curpage,我们利用json格式传递到servlet,然后servlet那边可以通过req.getparameter直接进行获取
第三部分是请求成功的回调函数,一定注意回调函数携带的参数为data,data里面存储了所有的数据。js需要从data里面来获取数据
返回的servlet查询的数据
这里的data一定不要写掉了function(data){});
那么如何对返回的数据进行处理,只需要在回调函数里面进行操作就行了
areaInfo = "{"pageCount":"+pageCount+","pageInfo":"+areaInfo+"}";
这里的书写格式一定要注意
首先把最原始的JSON格式写出来,然后再根据哪些逗号需要进行转义
areaInfo = "{"pageCount":pageCount,"pageInfo":areaInfo}";
这是我们需要进行封装的最原始的字符串对象,返回的是一个字符串,一定要注意了,所以最外面是一对双引号
areaInfo = "{"pageCount":"+pageCount+","pageInfo":"+areaInfo+"}";
然后提取变量,拼接字符串,这里的value值都是变量,需要用"+value+"拼接起来
areaInfo = "{"pageCount":"+pageCount+","pageInfo":"+areaInfo+"}";
接下来就是对于必须存在的引号进行转义,由于JSON里面的key是必须要用引号括起来的,所以需要对key的引号进行一个转义
由于在servlet里面封装的JSON数据,是这样的格式,那么我们从js里面取数据的时候就是直接通过data.key就可以取出对应的数据了
但是对于pageinfo,相当于value里面还有一个JSON,所以要取出value里面的value,还得遍历外层value,然后通过area.key进行取值
并且所有的数据都是存放在data里面的
第四个部分是返回的数据格式,这里返回的是json格式的
//定义全局变量
var pageSize = 10,curPage = 1,pageCount = 0;
window.onload = sendPageAjax;
//发送请求
function sendPageAjax(){
$.post("AreaPageServlet",{"pageSize":pageSize,"curPage":curPage,"random":Math.random()},function(data){
//取出pagecount
pageCount = data.pageCount;
alert(pageCount);
//取出pageInfo里面的10条数据显示 包括code name layer
$.each(data.pageInfo,function(index,area){
$("tbody").append("<tr><td>"+area.code+"</td>" +
"<td>"+area.name+"</td>" +
"<td>"+area.layer+"</td>" +
"<td hrea='#'>修改</td></tr>");
});
},"json");
}
window.onload = sendPageAjax;
//发送请求
function sendPageAjax(){
这里通过window.onload函数来加载第一页的地区信息
然后就不用在jsp页面上给具体的body添加一个onload的事件了
那么接下来我们的任务是给每一个页码添加一个点击事件,点击页码,就显示对应的页面的信息,这里有十个页码,如果还有很多数据的话,我们不可能给每一个li元素添加一个onchange事件,所以需要通过$.(“li”)来获取标签,添加事件
这里我们需要获取到所有的li元素,然后添加点击事件
//给每个li元素添加一个点击事件
//点击的时候获取到当前页面的数值curpage,然后将curpage和pagesize
//作为参数传递给servlet进行当前页面的数据查询
function clickIndex(){
$(".pagination>li").click(function(){});
}
选中ul下面的所有li元素.pagination>li,$(“label”) 选中页面的标签
调用点击事件的时候,参数为function方法
相当于click的参数是一个方法
click方法是一个闭包调用
function clickIndex(){
$(".pagination>li").click(function(){
//获取到点击的页面的数值
var curPage = $(this).text()*1;
sendPageAjax();
});
}
要通过点击事件拿到当前的的curpage,需要通过jQuery方法拿到当前对象的文本,这里的当前的文本表示,点击哪个就是哪个li,然后通过$(this).text()方法拿到li里面的文本值,注意是text,不是Text,还有括号,拿文本是一个方法。
同时还需要注意的是这里拿到的curpage是一个var类型的数据,是字符串类型的,这里我们还需要转化为int类型,在js里面将字符串转为int类型数值类型,只需要*1就可以了。
然后将拿到的curpage传递给sendpageajax去获取对应页面的数据
同时还需要注意的是,这里的点击事件需要放在sendpageajax的回调函数里面
相当于clickindex将curpage传递给sendpageajax函数进行请求数据查询数据,查询成功,添加到页面的表格中,然后还要继续调用点击函数,获取另外的点击事件,这是一个循环的过程。
因为这里和后台servlet交互的过程只有dopost在工作,所以这里相当于是一个递归调用,函数里面调用函数
js所有的函数方法都需要放在包含了dopost的函数里面才能够工作,然后可能其他的函数也会调用包含了dopost的函数,这里就形成了函数的递归调用
//定义全局变量
var pageSize = 10,curPage = 1,pageCount = 0;
window.onload = sendPageAjax;
//发送请求
function sendPageAjax(){
$.post("AreaPageServlet",{"pageSize":pageSize,"curPage":curPage,"random":Math.random()},function(data){
//取出pagecount
pageCount = data.pageCount;
// alert(pageCount);
//取出pageInfo里面的10条数据显示 包括code name layer
$.each(data.pageInfo,function(index,area){
$("tbody").append("<tr><td>"+area.code+"</td>" +
"<td>"+area.name+"</td>" +
"<td>"+area.layer+"</td>" +
"<td hrea='#'>修改</td></tr>");
});
clickIndex();
},"json");
}
//给每个li元素添加一个点击事件
//点击的时候获取到当前页面的数值curpage,然后将curpage和pagesize
//作为参数传递给servlet进行当前页面的数据查询
function clickIndex(){
$(".pagination>li").click(function(){
//获取到点击的页面的数值
var curPage = $(this).text()*1;
sendPageAjax();
});
}
然后这里有个问题是如果页面不刷新的话,就会存在点击一个页码查询出对应的信息,但是我上次点击的页码查询的信息并没有在页面清除,所以再添加下一个页面的信息之前,需要将tbody里面的所有信息清除
$("tbody").html("");
这里我们只需要选中tbody标签,然后将他的所有的html元素清空就可以了
这里的清空利用空串进行清空
所以这种含有局部清除表的body的页面,一般都要将表头和body区分开来方便操作