SSM 04 - 改造查询,变成一个页面的异步请求查询

提问:当前所编写的前端代码只适用与B/S架构中,当安卓用户和IOS用户也想访问这些数据时该怎么办?
答:让服务器将数据进行JSON化处理(JSON是各种客户端都能进行接收的数据格式)

因为要将数据专为JSON 格式,所以要引入jack son的jar 包

    <!-- 将返回的数据封装成JSON格式 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.8.8</version>
    </dependency>

EmployeeController:

package com.jy.crud.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jy.crud.bean.Employee;
import com.jy.crud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @RequestMapping("/emps")
    @ResponseBody
    public PageInfo getEmpsWithJson(@RequestParam(value = "pn",defaultValue = "1") Integer pageNum){
        //引入PageHelper 来进行分页查询
        //如何使用?
        //在查询之前只需要调用startPage
        //第一个参数:从第几页开始查
        //第二个参数:一页有几条数据
        PageHelper.startPage(pageNum,5);
        //startPage 后面紧跟的查询就是分页查询
        List<Employee> all = employeeService.getAll();

        //使用PageInfo 包装查询后的结果,然后将它返回给list.jsp就行了
        //5 : 页面导航区中需要连续显示的页数
        PageInfo<Employee> page = new PageInfo<>(all,5);

        return page;
    }

关于@ResponseBody:
 @responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML

数据,需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
代码说明:
  @RequestMapping("/login")
  @ResponseBody
  public User login(User user){
    return user;
  }
  User字段:userName pwd
  那么在前台接收到的数据为:’{“userName”:“xxx”,“pwd”:“xxx”}’

效果等同于如下代码:
  @RequestMapping("/login")
  public void login(User user, HttpServletResponse response){
    response.getWriter.write(JSONObject.fromObject(user).toString());
  }

请求页面返回的数据就会变成这样:
在这里插入图片描述

Controller 返回PageInfo 对象,该对象不具有通用性。比如:在客户端进行增删改的时候该对象并没有对这三者的状态进行保存,所以客户端是不清楚当前操作是否正确或者完成,所以就要设计一个通用的,带有状态和数据信息的类

package com.jy.crud.bean;

import java.util.HashMap;
import java.util.Map;

/**
 * 这是一个通用的类
 */
public class Msg {

    //状态码   100-成功    200-失败
    private int code;
    //提示信息
    private String msg;

    //用户要返回给浏览器的数据
    private Map<String, Object> extend = new HashMap<String, Object>();

    public static Msg success(){
        Msg result = new Msg();
        result.setCode(100);
        result.setMsg("处理成功!");
        return result;
    }

    public static Msg fail(){
        Msg result = new Msg();
        result.setCode(200);
        result.setMsg("处理失败!");
        return result;
    }

    public Msg add(String key,Object value){
        this.getExtend().put(key, value);
        return this;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Map<String, Object> getExtend() {
        return extend;
    }

    public void setExtend(Map<String, Object> extend) {
        this.extend = extend;
    }
}



Controller 的方法就只用返回Msg:

package com.jy.crud.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jy.crud.bean.Employee;
import com.jy.crud.bean.Msg;
import com.jy.crud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @RequestMapping("/emps")
    @ResponseBody
    public Msg getEmpsWithJson(@RequestParam(value = "pn",defaultValue = "1") Integer pageNum){
        //引入PageHelper 来进行分页查询
        //如何使用?
        //在查询之前只需要调用startPage
        //第一个参数:从第几页开始查
        //第二个参数:一页有几条数据
        PageHelper.startPage(pageNum,5);
        //startPage 后面紧跟的查询就是分页查询
        List<Employee> all = employeeService.getAll();

        //使用PageInfo 包装查询后的结果,然后将它返回给list.jsp就行了
        //5 : 页面导航区中需要连续显示的页数
        PageInfo<Employee> page = new PageInfo<>(all,5);

        return Msg.success().add("pageInfo",page);
    }

那么现在的请求过程就不是: 访问index.jsp -> index.jsp 发送请求给Controller -> Controller 将请求数据返回给list.jsp
而是:访问index.jsp -> index.jsp 通过JS 发送Ajax 请求 -> Ajax 请求通过Controller 要到分页的数据(Msg) -> index.jsp 的JS 对象获取到Msg,然后解析JSON 数据

<%--
  Created by IntelliJ IDEA.
  User: Hasee
  Date: 2020/8/13
  Time: 17:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>

<%--因为要显示的数据是需要遍历出来的,所以就要用到c:foreach标签--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>员工列表</title>
    <%
        pageContext.setAttribute("APP_PATH",request.getContextPath());
    %>
    <script type="text/javascript" src="${APP_PATH}/static/js/jquery-1.12.4.min.js"></script>
    <%--引入样式--%>
    <link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet" />
    <script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>

<%--搭建显示页面--%>
<div class="container">
    <%--第一列:标题--%>
    <div class="row">
        <%--12 : 总共有12,再用占12--%>
        <div class="col-md-12">
            <h1>SSM-CRUD</h1>
        </div>
    </div>
    <%--第二列:新增,删除按钮--%>
    <div class="row">
        <%--这个div占领了4(col-md-4),又偏移了8(col-md-offset-8)--%>
        <div class="col-md-4 col-md-offset-8">
            <%--btn btn-primary: 蓝色, btn btn-dangger: 红色--%>
            <button class="btn btn-primary">新增</button>
            <button class="btn btn-dangger">删除</button>
        </div>
    </div>
    <%--显示信息--%>
    <div class="row">
        <%--第三列:显示数据--%>
        <div class="col-md-12">
            <%--让表格拥有间隔并且鼠标悬停到表格的每一行数据上会有阴影效果--%>
            <table class="table table-hover" id="emps_table">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>empName</th>
                        <th>gender</th>
                        <th>email</th>
                        <th>deptName</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>

                </tbody>
            </table>
        </div>
    </div>
    <%--显示分页信息--%>
    <div class="row">
        <%--分页文字信息--%>
        <div class="col-md-6">
            当前页,总共页,总共记录数
        </div>

        <%--分页条(页码导航)信息--%>
        <div class="col-md-6">

        </div>
    </div>
</div>
    <script type="text/javascript">
        /*1. 页面加载完成以后, 直接去发送一个ajax 请求,要到分页数据*/
        $(function(){
            $.ajax({
                url:"${APP_PATH}/emps",
                data:"pn=1",
                type:"get",
                success:function (result) {
                    //请求成功以后(已经通过Controller 拿到了数据),开始解析JSON
                    //1. 解析出员工数据并显示
                    build_emps_table(result);
                    //2. 解析并显示分页信息
                }
            });
        });

        /*该函数用于构建员工数据信息的列表*/
        function build_emps_table(result) {
            /*先获取到Msg(result) 中的extend 下的list*/
            var emps = result.extend.pageInfo.list;
            //emps: 需要遍历的对象
            //function(index,item){...} : 遍历emps时需要执行的回调函数
            //index: emps中数据的索引, item: emps遍历出来的数据
            $.each(emps,function (index,item) {
                var empIdTd = $("<td></td>").append(item.empId);
                var empNameId = $("<td></td>").append(item.empName);
                var genderId = $("<td></td>").append(item.gender == 'M'?"男":"女");
                var emailId = $("<td></td>").append(item.email);
                var deptNameId = $("<td></td>").append(item.department.deptName);

                //每行数据都有的"编辑"和"删除"按钮
                var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
                var deleteBtn = $("<button></button>").addClass("btn btn-dangger btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
                var btn = $("<td></td>").append(editBtn).append(" ").append(deleteBtn); //将"编辑"和"删除"单元格合并到一个<td></td> 中,然后中间留空格

                $("<tr></tr>").append(empIdTd).append(empNameId).append(genderId).append(emailId).append(deptNameId).append(btn)
                .appendTo("#emps_table tbody"); //这个apppendTo(..):代表将this 添加到目标对象(""#emps_table tbody"")中
            });
        }

        function build_page_nav(result){

        }
    </script>
</body>
</html>


关于$.each(…) 的运用:
在这里插入图片描述

效果图:
在这里插入图片描述

开始设置分页记录数和导航栏数据

<%--
  Created by IntelliJ IDEA.
  User: Hasee
  Date: 2020/8/13
  Time: 17:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>

<%--因为要显示的数据是需要遍历出来的,所以就要用到c:foreach标签--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>员工列表</title>
    <%
        pageContext.setAttribute("APP_PATH",request.getContextPath());
    %>
    <script type="text/javascript" src="${APP_PATH}/static/js/jquery-1.12.4.min.js"></script>
    <%--引入样式--%>
    <link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet" />
    <script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>

<%--搭建显示页面--%>
<div class="container">
    <%--第一列:标题--%>
    <div class="row">
        <%--12 : 总共有12,再用占12--%>
        <div class="col-md-12">
            <h1>SSM-CRUD</h1>
        </div>
    </div>
    <%--第二列:新增,删除按钮--%>
    <div class="row">
        <%--这个div占领了4(col-md-4),又偏移了8(col-md-offset-8)--%>
        <div class="col-md-4 col-md-offset-8">
            <%--btn btn-primary: 蓝色, btn btn-dangger: 红色--%>
            <button class="btn btn-primary">新增</button>
            <button class="btn btn-dangger">删除</button>
        </div>
    </div>
    <%--显示信息--%>
    <div class="row">
        <%--第三列:显示数据--%>
        <div class="col-md-12">
            <%--让表格拥有间隔并且鼠标悬停到表格的每一行数据上会有阴影效果--%>
            <table class="table table-hover" id="emps_table">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>empName</th>
                        <th>gender</th>
                        <th>email</th>
                        <th>deptName</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>

                </tbody>
            </table>
        </div>
    </div>
    <%--显示分页信息--%>
    <div class="row">
        <%--分页文字信息--%>
        <div class="col-md-6" id="page_info_area">
            当前页,总共页,总共记录数
        </div>

        <%--分页条(页码导航)信息--%>
        <div class="col-md-6" id="page_nav_area">

        </div>
    </div>
</div>
    <script type="text/javascript">
        /*1. 页面加载完成以后, 直接去发送一个ajax 请求,要到分页数据*/
        $(function(){
            //一进入页面就去第一页
            to_page(1);
        });

        //因为后面还有点击其他按钮,所以就写一个通用的ajax请求
        function to_page(pn){
            $.ajax({
                url:"${APP_PATH}/emps",
                data:"pn="+pn,
                type:"get",
                success:function (result) {
                    //请求成功以后(已经通过Controller 拿到了数据),开始解析JSON
                    //1. 解析出员工数据并显示
                    build_emps_table(result);
                    //2. 解析并显示分页信息
                    build_page_info(result);

                    build_page_nav(result)
                }
            });
        }

        /*该函数用于构建员工数据信息的列表*/
        function build_emps_table(result) {
            //构建table 之前都先清空table里面的数据,以防与上次的数据叠加
            $("#emps_table tbody").empty();

            /*先获取到Msg(result) 中的extend 下的list*/
            var emps = result.extend.pageInfo.list;
            //emps: 需要遍历的对象
            //function(index,item){...} : 遍历emps时需要执行的回调函数
            //index: emps中数据的索引, item: emps遍历出来的数据
            $.each(emps,function (index,item) {
                var empIdTd = $("<td></td>").append(item.empId);
                var empNameId = $("<td></td>").append(item.empName);
                var genderId = $("<td></td>").append(item.gender == 'M'?"男":"女");
                var emailId = $("<td></td>").append(item.email);
                var deptNameId = $("<td></td>").append(item.department.deptName);

                //每行数据都有的"编辑"和"删除"按钮
                var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
                var deleteBtn = $("<button></button>").addClass("btn btn-dangger btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
                var btn = $("<td></td>").append(editBtn).append(" ").append(deleteBtn); //将"编辑"和"删除"单元格合并到一个<td></td> 中,然后中间留空格

                $("<tr></tr>").append(empIdTd).append(empNameId).append(genderId).append(emailId).append(deptNameId).append(btn)
                .appendTo("#emps_table tbody"); //这个apppendTo(..):代表将this 添加到目标对象(""#emps_table tbody"")中
            });
        }

        //解析显示分页信息(总记录数,共有几页...)
        function build_page_info(result){
            $("#page_info_area").empty();
            $("#page_info_area").append("当前"+result.extend.pageInfo.pageNum+"页,总"+result.extend.pageInfo.pages+"页,总"+result.extend.pageInfo.total+"条记录数");
        }

        //解析显示分页导航条,并且点击分页跳的按键能去到目标页
        function build_page_nav(result){
            //每一次的请求都要先清空上一次的数据
            $("#page_info_area").empty();

            //创建按键元素
            var ul = $("<ul></ul>").addClass("pagination");
            //首页键
            var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#"));
            //上一页键
            var prePageLi = $("<li></li>").append($("<a></a>").append("&laquo;"));

            //判断如果当前已经在第一页,就不能点击首页和上一页按键
            if(result.extend.pageInfo.hasPreviousPage == false){
                firstPageLi.addClass("disabled");
                prePageLi.addClass("disabled");
            }else{
                //为"首页""前一页"添加点击翻页事件
                firstPageLi.click(function(){
                    to_page(1);
                });

                prePageLi.click(function(){
                    to_page(result.extend.pageInfo.pageNum - 1);
                });
            }

            //下一页键
            var NextPageLi = $("<li></li>").append($("<a></a>").append("&raquo;"));
            //末页键
            var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#"));

            //判断如果当前已经在最后一页,就不能点击末页和下一页按键
            if(result.extend.pageInfo.hasNextPage == false){
                NextPageLi.addClass("disabled");
                lastPageLi.addClass("disabled");
            }else{
                //为"末页""下一页"添加点击翻页事件
                NextPageLi.click(function(){
                    to_page(result.extend.pageInfo.pageNum + 1);
                });
                lastPageLi.click(function(){
                    to_page(result.extend.pageInfo.pages);
                });
            }

            ul.append(firstPageLi).append(prePageLi);
            //中间还需要连续的5页数据
            //然后将按键进行高亮显示
            $.each(result.extend.pageInfo.navigatePage,function(index,item){
                var numLi = $("<li></li>").append($("<a></a>").append(item));
                if(result.extend.pageInfo.navigatePage == item){
                    numLi.addClass("active");
                }

                //为页码导航键添加事件,用于发ajax请求
                numLi.click(function(){
                    to_page(item);
                });
                ul.append(numLi);
            });
            ul.append(NextPageLi).append(lastPageLi);

            //把ul 加入到nav导航元素中
            var navEle = $("<nav></nav>").append(ul);

            //把导航条添加到div 元素中
            navEle.appendTo("#page_nav_area");
        }
    </script>
</body>
</html>


但是在点击“《”和“》”的时候还是会出现超出页码合理性的页数,所以就要在mybatis 全局配置文件中的pageHelper 插件中设置开启"页码合理参数"
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的使用SSM框架实现分页查询并带页面显示的示例。假设我们要查询一个名为"student"的表中的数据并进行分页显示,具体步骤如下: 1. 在mapper.xml文件中编写SQL语句实现分页查询功能,例如: ``` <!-- 分页查询学生信息,startIndex为起始位置,pageSize为每页显示的记录数 --> <select id="selectStudentsByPage" parameterType="map" resultMap="studentResultMap"> SELECT * FROM student LIMIT #{startIndex}, #{pageSize} </select> ``` 2. 在dao层接口中定义selectStudentsByPage方法,如下所示: ``` public interface StudentDao { List<Student> selectStudentsByPage(Map<String, Object> map); } ``` 3. 在service层中编写代码调用dao层的方法,实现分页查询并返回结果,如下所示: ``` public PageInfo<Student> findStudentsByPage(int pageNum, int pageSize) { //计算起始位置 int startIndex = (pageNum - 1) * pageSize; //查询数据 Map<String, Object> map = new HashMap<>(); map.put("startIndex", startIndex); map.put("pageSize", pageSize); List<Student> list = studentDao.selectStudentsByPage(map); //封装分页信息 PageInfo<Student> pageInfo = new PageInfo<>(list); return pageInfo; } ``` 4. 在controller层中编写代码获取前端传来的pageNum和pageSize参数,并调用service层的方法进行分页查询,如下所示: ``` @RequestMapping("/students") public ModelAndView findStudents(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize) { PageInfo<Student> pageInfo = studentService.findStudentsByPage(pageNum, pageSize); ModelAndView mv = new ModelAndView(); mv.addObject("pageInfo", pageInfo); mv.setViewName("studentList"); return mv; } ``` 5. 在jsp页面中使用jstl标签库进行页面显示,如下所示: ``` <c:forEach items="${pageInfo.list}" var="student"> <tr> <td>${student.id}</td> <td>${student.name}</td> <td>${student.age}</td> <td>${student.gender}</td> </tr> </c:forEach> ``` 以上就是使用SSM框架实现分页查询并带页面显示的简单示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值