Ajax实现分页二

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区分开来方便操作

欢迎关注我的公众号:小秋的博客 CSDN博客:https://blog.csdn.net/xiaoqiu_cr github:https://github.com/crr121 联系邮箱:rongchen633@gmail.com 有什么问题可以给我留言噢~
原文地址:https://www.cnblogs.com/flyingcr/p/10327117.html