SSM-CRUD入门项目——查询
查询
1.基础查询
分析:访问项目主页 index.jsp 时应该跳转到列表页
我们可以在index.jsp发出查询员工列表请求,来到 list.jsp
使用插件 pageHelper 完成分页功能——使用pageHelper,给他需要的参数:我要查询第几页,每页几条记录,我要连续显示几条?
首先在首页页面直接转发:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <<jsp:forward page="/emps"></jsp:forward> <!-- <!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> <link href="static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> 先引入jQuery,再引入js <script type="text/javascript" src="static/bootstrap/js/jquery.min.js"> </script> <script src="static/bootstrap/js/bootstrap.min.js"></script> </head> <body> </body> </html> -->
编写一下转发的controller:
package cn.crud.controller; import java.util.List; 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 com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; import cn.crud.service.EmpService; /** * 处理员工的CRUD请求 * @author Administrator * */ @Controller public class EmpController { @Autowired private EmpService empService; /** * 分页查询员工数据 * @return */ @RequestMapping("/emps") public String getEmps(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); model.addAttribute("page", page); return "list"; } }
//分页插件pageHelper的使用以及引入等可以参照官方文档等,这里暂时不展开,待另外博客更新
由于controller中调用service,我们生成service:
package cn.crud.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.crud.bean.Employee; import cn.crud.dao.EmployeeMapper; @Service public class EmpService { @Autowired private EmployeeMapper employeeMapper; public List<Employee> getAll() { /** * 没有查询条件的查询所有,带部门信息 */ return employeeMapper.selectByExampleWithDept(null); } }
//service中调用dao的mapper:
在来到页面之前,我们先使用spring的单元测试进行测试,测试数据是否正常到达:
package cn.crud.tests; import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; /** * 使用spring的单元测试来进行模拟发送请求的测试 * @author Administrator * */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations={"classpath:applicationContext.xml", "file:src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml"}) public class MVCTest { //springMVC的IOC容器 @Autowired private WebApplicationContext context; //模拟MVC请求 private MockMvc mockMvc; @Before public void setup(){ mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); } @Test public void testPage() throws Exception{ //模拟请求拿到返回值 MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "2")) .andReturn(); //请求域中有pageInfo PageInfo page = (PageInfo) result.getRequest().getAttribute("page"); System.out.println(page.getPageNum()); System.out.println(page.getTotal()); //得到员工数据 List<Employee> list = page.getList(); for (Employee employee : list) { System.out.println("ID:"+employee.getdId()+" 性别:"+employee.getGender()); } } }
//尤其需要注意的是spring-test4的版本需要servlet3.0以上的版本,我们去仓库中第一个java servlet-api找到3.1的版本替换原来2.5的版本!
界面的搭建:
使用bootstrap的栅格系统快速搭建简单的界面框架
<%@ 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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover"> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> <tr> <td>1</td> <td>aa</td> <td>123@163.com</td> <td>M</td> <td>开发部</td> <td> <button type="button" class="btn btn-info btn-sm"> <span class="glyphicon glyphicon-penci" aria-hidden="true"></span> 编辑</button> <button type="button" class="btn btn-danger btn-sm"> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> 删除</button> </td> </tr> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息 --> <div class="col-md-6"> 当前记录数:xxx </div> <!-- 分页条 --> <div class="col-md-6"> <nav aria-label="Page navigation"> <ul class="pagination"> <li><a href="#">首页</a></li> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><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="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <li><a href="#">末页</a></li> </ul> </nav> </div> </div> </div> </body> </html>
//注意不要使用不带 / 的相对路径,而是使用带 / 的路径
使用maven分类博客中使用插件运行Maven项目:访问主页,成功!
接下来利用分页插件完成分页信息的查询,由于我们将分页信息都封装在pageInfo中,我们利用这个完成分页页面的搭建:
<%@ 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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover"> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> <c:forEach items="${pageInfo.list }" var="emp"> <tr> <td>${emp.empId}</td> <td>${emp.empName}</td> <td>${emp.email}</td> <!-- 三元运算符展示性别信息 --> <td>${emp.gender=="M"?"男":"女"}</td> <td>${emp.department.deptName}</td> <td> <button type="button" class="btn btn-info btn-sm"> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> 编辑</button> <button type="button" class="btn btn-danger btn-sm"> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> 删除</button> </td> </tr> </c:forEach> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6"> 当前第:${pageInfo.pageNum}页,总共:${pageInfo.pages}页,总共:${pageInfo.total}条记录 </div> <!-- 分页条 --> <div class="col-md-6"> <nav aria-label="Page navigation"> <ul class="pagination"> <li><a href="${path}/emps?pn=1">首页</a></li> <c:if test="${pageInfo.hasPreviousPage }"> <li> <a href="${path}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> </c:if> <c:forEach items="${pageInfo.navigatepageNums }" var="page_Num"> <c:if test="${page_Num == pageInfo.pageNum }"> <li class="active"><a href="#">${page_Num}</a></li> </c:if> <c:if test="${page_Num != pageInfo.pageNum }"> <li><a href="${path}/emps?pn=${page_Num}">${page_Num}</a></li> </c:if> </c:forEach> <c:if test="${pageInfo.hasNextPage }"> <li> <a href="${path}/emps?pn=${pageInfo.pageNum+1}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </c:if> <li><a href="${path}/emps?pn=${pageInfo.pages}">末页</a></li> </ul> </nav> </div> </div> </div> </body> </html>
//注意:
//使用PageHelper.startPage只是针对接下来的一条查询语句,
//如果又查询了一次数据,则还需要使用一次PageHelper.startPage
2.AJAX请求
浏览器的请求是可以正确完成相关的功能的,但是如果是安卓IOS等移动客户端,服务器再发送一个页面给移动设备解析的话,是比较费力的,交互体验也不是很好,于是,我们将请求更改为前台发AJAX请求,后台返回JSON数据
分析:首页index.jsp直接发送ajax请求进行员工分页信息的查询
服务器将查询的数据以JSON格式返回
前台使用js完成JSON的解析,通过DOM操作完成增删改查的操作。
回忆springMVC与JSON的交互,需要jackson的包,我们去中央仓库找到maven的坐标:
我们找到第一个数据绑定的包:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
之后我们将分页信息使用通用的信息类 Msg 进行包装,方便我们进行一些返回JSON的操作:
package cn.crud.bean; import java.util.HashMap; import java.util.Map; /** * 通用的返回信息的类 * */ public class Msg { //状态码,自定义一些状态码对应的状态 private int code; //提示信息 private String msg; //用户给浏览器的数据,比如说返回的PageInfo信息 private Map<String,Object> map = new HashMap<String,Object>(); /** * 操作成功的静态方法 * @return */ public static Msg success(){ Msg result = new Msg(); //这里100表示成功 result.setCode(100); result.setMsg("操作成功"); return result; } /** * 操作失败的静态方法 * @return */ public static Msg fail(){ Msg result = new Msg(); //这里100表示成功 result.setCode(200); result.setMsg("操作失败"); return result; } /** * 快捷添加信息的方法 * @return */ public Msg add(String key,Object value){ this.getMap().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> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } }
//Msg信息类中包含一些必要的属性与我们需要的静态方法
将controller中的返回分页信息方法进行改写,让他返回msg方便进行ajax的改造:
/** * 分页信息的AJAX请求 * @ResponseBody可以将返回的对象转为JSON字符串 * 此注解需要引入jackson的包(以及注解驱动的配置等,这里已经进行配置) * 将返回信息包装在msg里 */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); //直接将pageInfo对象进行返回 //将pageInfo放在msg里进行返回,链式操作返回对象本身 return Msg.success().add("pageInfo", page); }
然后,我们先将index.jsp重命名为index-old.jsp先放一边,new 一个index.jsp进行改造:
我们先用ajax改造表格的生成部分:
<%@ 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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</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>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6"> 当前第:页,总共:页,总共:条记录 </div> <!-- 分页条 --> <div class="col-md-6"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn=1", //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result) //2.解析生成分页信息 } }); }); //解析员工数据 function build_emps_table(result){ //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页导航信息 function build_pages_nav(result){ } </script> </body> </html>
//这里需要适当复习一下jQuery
我们再解析分页信息和分页条部分:
<%@ 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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</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>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn=1", //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); }); //解析员工数据 function build_emps_table(result){ //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果为当前页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } navUl.append(numLi); }); navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } </script> </body> </html>
//这样,加上一些页面的处理后,整个页面框架就搭建出来了
接下来我们进行一些事件的处理,例如导航条的页码,是点击后再发送ajax请求进行查询显示的,我们对页面再次进行改造:
我们对页码进行单击事件绑定与相关函数的抽取,完成后的index.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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</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>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } </script> </body> </html>
我们测试一下,很容易发现问题:
页面虽然数据正常返回,但由于是无刷新的返回数据,造成数据的追加而不是替换!我们再次进行改造:
在所有操作之前进行数据的清空,于是,改造页面如下:
<%@ 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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</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>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); } //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } </script> </body> </html>
为了页码的正常显示,我们在插件中配置一个合理化的参数,参数的具体作用请参见文档:
<!-- 分页插件的使用 --> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 配置合理化参数 --> <property name="reasonable" value="true"/> </plugin> </plugins>
我们把前面的代码稍微优化一下,如果按钮禁用了,就不绑定事件了,可用时才绑定事件:
<%@ 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"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary ">新增</button> <button type="button" class="btn btn-danger ">删除</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>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } </script> </body> </html>
至此,查询完成!