1.先引入Spring 单元测试的依赖
<!--Spring-test -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
2.@ContextConfiguration指定Spring配置文件的位置
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
3.直接autowired要使用的组件即可
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class MapperTest {
@Autowired
DepartmentMapper departmentMapper;
@Autowired
EmployeeMapper employeeMapper;
@Autowired
SqlSession sqlSession;
/**
* 测试DepartmentMapper
*/
@Test
public void testCRUD(){
/* //1、创建SpringIOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//2、从容器中获取mapper
DepartmentMapper bean = ioc.getBean(DepartmentMapper.class);*/
System.out.println(departmentMapper);
//1、插入几个部门
// departmentMapper.insertSelective(new Department(null, "开发部"));
// departmentMapper.insertSelective(new Department(null, "测试部"));
//2、生成员工数据,测试员工插入
employeeMapper.insertSelective(new Employee(null, "Jerry", "M", "Jerry@atguigu.com", 1));
//3、批量插入多个员工;批量,使用可以执行批量操作的sqlSession。
// for(){
// employeeMapper.insertSelective(new Employee(null, , "M", "Jerry@atguigu.com", 1));
// }
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
for(int i = 0;i<1000;i++){
String uid = UUID.randomUUID().toString().substring(0,5)+i;
mapper.insertSelective(new Employee(null,uid, "M", uid+"@atguigu.com", 1));
}
System.out.println("批量完成");
}
}
注意:上面的操作中需要用到批量操作,这就要开启有批量操作功能的sqlSession,
在Spring配置文件(applicationContext.xml)中加入配置
<!-- 配置一个可以执行批量的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
然后通过Autowired 来从Spring容器中拿到批量的sqlSession
分页查询:
整体请求流程:先进入index.jsp,由index.jsp 直接用forward 请求到后台查询员工并进行分页,将分页结果返回到list.jsp 页面
因为要分页,所以可以使用PageHelper 插件进行分页
pagehelper 配置:
引入pagehelper 依赖
<!-- 引入pagehelper 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
在mybatis 全局配置文件中完成注册
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:forward page="/emps"></jsp:forward>
处理"/emps" 请求的控制器:
@Controller
public class EmployeeController {
@Autowired
EmployeeService employeeService;
/**
* 查询员工数据(分页查询)
* @return
*/
@RequestMapping("/emps")
//value = "pn",defaultValue = "1" : 接收从前端传来的pn的值,如果没有则默认为1
public String getEmps(@RequestParam(value = "pn",defaultValue = "1") Integer pageNum,
Model model){
//引入PageHelper 来进行分页查询
//如何使用?
//在查询之前只需要调用startPage
//第一个参数:从第几页开始查
//第二个参数:一页有几条数据
PageHelper.startPage(pageNum,5);
//startPage 后面紧跟的查询就是分页查询
List<Employee> all = employeeService.getAll();
//使用PageInfo 包装查询后的结果,然后将它返回给list.jsp就行了
//5 : 页面导航区中需要连续显示的页数
PageInfo<Employee> page = new PageInfo<>(all,5);
model.addAttribute("pageInfo",page);
return "list";
}
進行分頁查詢時候,就要進行流程分析:
1.訪問index.jsp
2.通过index.jsp发送向EmployeeController发送查询信息请求
3.EmployeeController接收请求,并查询数据
4.将数据发给list.jsp进行显示
index.jsp
因为查询的数据需要分页,所以要在pom.xml中引入pageHelper
<!-- 引入pagehelper 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
然后在mybatis 全局配置文件里面进行注册:
在进行页面请求之前要进行测试,但是测试这个代码是需要/emps 请求的,如何做到?
用Spring 提供的Spring-test 模块就行模拟请求
注意Spring4 整合的Junit 是需要servlet3.0支持的
所以要导入servlet3.0 的依赖
如果不引入会有报错:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
注意:在引入springmvc 配置文件时,如果配置文件是配置在src的webapp下的话,还是用的classpath: 进行引导
将webapp 文件右键 - Mark Directory as - Resources Root
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:WEB-INF/dispatcherServlet-serlvet.xml"})
MVCTest:
/**
* 使用Spring test 模块提供的测试功能来测试请求功能,检验crud的正确性
* 注意:Spring4 测试时候,需要servlet3.0 支持
*/
//设置用哪个单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration //获取WebApplicationContext 容器
@ContextConfiguration(locations = {"classpath:applicationContext.xml","classpath:dispatcherServlet-serlvet.xml"})
public class MVCTest {
//传入SpringMvc 的ioc
@Autowired
WebApplicationContext context;
//虚拟的mvc请求,获取到处理结果
MockMvc mockMvc;
//创建MockMvc
@Before //这是junit 的Before, 不是aop 的Before
public void initMockMvc(){
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void testPage() throws Exception {
//模拟请求拿到返回值
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "1")).andReturn();
//请求成功以后,请求域会有pageInfo, 我们可以取出pageInfo 进行验证
MockHttpServletRequest request = result.getRequest();
PageInfo pageInfo = (PageInfo) request.getAttribute("pageInfo");
System.out.println("当前页码:"+pageInfo.getPageNum());
System.out.println("总页码:"+pageInfo.getPages());
System.out.println("总记录数:"+pageInfo.getTotal());
System.out.println("在页面需要连续显示的页码");
int[] nums = pageInfo.getNavigatepageNums();
for (int num : nums){
System.out.print(" "+num);
}
//获取员工数据
List<Employee> list = pageInfo.getList();
for(Employee employee : list){
System.out.println("ID:"+employee.getdId()+",Name:"+employee.getEmpName());
}
}
测试成功:
当数据从Controller 传到list.jsp 时,list 就要将数据进行显示,所以就要对list 进行样式设置(利用Bootstrap框架)
代码如下:
<%--
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">
<tr>
<th>#</th>
<th>empName</th>
<th>gender</th>
<th>email</th>
<th>deptName</th>
<th>操作</th>
</tr>
<%--pageInfo.getList() 取出在pageInfo中的所有数据,把每一个数据取名为emp--%>
<c:forEach items="${pageInfo.list}" var="emp">
<tr>
<%--再从emp 中依次取出里面的信息--%>
<th>${emp.empId}</th>
<th>${emp.empName}</th>
<th>${emp.gender == "M"? "男":"女"}</th>
<th>${emp.email}</th>
<th>${emp.department.deptName}</th>
<th>
<button class="btn btn-primary btn-sm">
<%--这个span 会带有一个铅笔的图案,修饰编辑这个按钮--%>
<span class="glyphicon glyphicon-pencil"></span>
编辑
</button>
<%--btn-sm: 小尺寸--%>
<button class="btn btn-dangger btn-sm">
<%--这个span 会带有一个铅笔的图案,修饰编辑这个按钮--%>
<span class="glyphicon glyphicon-trash"></span>
删除
</button>
</th>
</tr>
</c:forEach>
</table>
</div>
</div>
<%--显示分页信息--%>
<div class="row">
<%--分页文字信息--%>
<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="${APP_PATH }/emps?pn=1">首页</a></li>
<%--在点击"上一页"箭头的时候要判断是否有上一页,这里可以用到PageHelper 插件提供的属性来简化此判断 --%>
<c:if test="${pageInfo.hasPreviousPage}">
<li><a href="${APP_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="${APP_PATH}//emps?pn=${page_Num}">${page_Num}</a></li>
</c:if>
</c:forEach>
<%--在点击"下一页"箭头的时候要判断是否有下一页,这里可以用到PageHelper 插件提供的属性来简化此判断 --%>
<c:if test="${pageInfo.hasNextPage }">
<li><a href="${APP_PATH }/emps?pn=${pageInfo.pageNum+1 }"
aria-label="Next"> <span aria-hidden="true">»</span>
</a></li>
</c:if>
<%--最后一页就是总页码--%>
<li><a href="${APP_PATH }/emps?pn=${pageInfo.pages }">末页</a></li>
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>
具体展示效果: