SSM整合-02 信息查询

项目完整实现代码下载地址:https://download.csdn.net/download/bingbeichen/10578683。

该部分主要实现员工信息的查询与显示,主要实现步骤包括:

  • 访问index.jsp页面,该页面发送查询员工列表的请求(URI为/emps);
  • 处理器EmployeeHandler来接收请求,查询出员工数据;
  • 返回到/WEB-INF/views/emp-list.jsp页面进行员工信息的显示;
  • 使用PageHelper分页插件完成分页查询功能。

###1. 分页查询后台代码实现
第一步,访问index.jsp页面,在该页面发送查询员工列表数据的请求,如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:forward page="/emps"></jsp:forward>

第二步,创建控制器EmployeeHandler来接收请求,查询出员工信息,如下:

// EmployeeHandler.java
@Controller
public class EmployeeHandler {

	@Autowired
	private EmployeeService employeeService;

	@RequestMapping("/emps")
	public String handleGetEmps() {
		// 查询所有员工信息(需要创建业务逻辑组件EmployeeService)
		List<Employee> emps = employeeService.getAll();
		// 返回到emp-list.jsp页面进行显示
		return "emp-list";
	}

}
// EmployeeService.java
@Service
public class EmployeeService {

	@Autowired
	private EmployeeMapper employeeMapper;

	public List<Employee> getAll() {
		List<Employee> emps = employeeMapper.selectByExampleWithDept(null);
		return emps;
	}
	
}

第三步, 使用PageHelper分页插件完成分页查询功能,该部分主要包括:
(1). 引入分页插件,即在pom.xml文件中添加如下依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper</artifactId>
	<version>5.1.4</version>
</dependency>

(2). 在MyBatis的全局配置文件mybatis-config.xml中,配置拦截器插件

<plugins>
	<!-- com.github.pagehelper为PageHelper类所在包名 -->
	<plugin interceptor="com.github.pagehelper.PageInterceptor">
		<!-- 分页合理化参数,默认值为false。
			当为true时,pageNum<=0 时查询第一页, pageNum>pages时查询最后一页。 
		 -->
		<property name="reasonable" value="true"/>
	</plugin>
</plugins>

(3). 在控制器EmployeeHandler中进行分页查询,并将查询结果封装在Map中

@Controller
public class EmployeeHandler {

	@Autowired
	private EmployeeService employeeService;
	
	@RequestMapping("/emps")
	public String handleGetEmps(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, Model model) {
		// 使用PageHelper组件获取第pageNum页,共6条内容
		PageHelper.startPage(pageNum, 6);
		// 紧跟的查询操作即为分页查询
		List<Employee> emps = employeeService.getAll();
		// 使用PageInfo对分页查询结果进行封装,以获取分页查询的详细信息,并传入可连续显示的页数
		PageInfo<Employee> pageInfo = new PageInfo<Employee>(emps, 6);
		// 将pageInfo对象传递到结果页面
		model.addAttribute("pageInfo", pageInfo);
		return "emp-list";
	}

}

第四步,使用Spring单元测试测试分页请求及其返回结果的正确性

package com.qiaobc.crud.test;

/**
 * Spring4测试时需要servlet3.0支持
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({ "classpath:applicationContext.xml",
		"file:src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml" })
public class CRUDTest {

	@Autowired
	private WebApplicationContext context;

	// 虚拟MVC请求,获取请求结果
	private MockMvc mockMvc;

	@Before
	public void initMockMvc() {
		mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
	}

	@Test
	public void testGetAll() throws Exception {
		// 模拟请求并获取请求结果
		MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pageNum", "1")).andReturn();
		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.print("连续页面:");
		int[] nums = pageInfo.getNavigatepageNums();
		for (int i : nums) {
			System.out.print(i + "  ");
		}
		System.out.println();

		// 获取所有员工信息
		List<Employee> emps = pageInfo.getList();
		for (Employee emp : emps) {
			System.out.println(emp.getLastName());
		}
	}
}

至此为止,分页查询的后台代码和测试均已完成。


###2. 分页查询页面搭建与数据显示
基于Bootstrap前端框架搭建分页页面,并对分页数据进行整理显示,实现效果图如下:
这里写图片描述
查询结果显示页面emp-list.jsp的具体实现代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>员工信息显示</title>
<%
	pageContext.setAttribute("WEB_PATH", request.getContextPath());
%>
<script type="text/javascript"
	src="${WEB_PATH }/static/javascript/jquery-3.3.1.min.js"></script>
<link
	href="${WEB_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"
	rel="stylesheet">
<script
	src="${WEB_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>

	<!-- 搭建显示界面 -->
	<div class="container">
		<!-- 标题行 -->
		<div class="raw">
			<div class="col-md-12">
				<h1>SSM_CRUD</h1>
			</div>
		</div>
		<!-- 按钮行 -->
		<div class="raw">
			<div class="col-md-4 col-md-offset-8">
				<button class="btn btn-primary">新增</button>
				<button class="btn btn-danger">删除</button>
			</div>
		</div>
		<!-- 显示表格数据 -->
		<div class="raw">
			<div class="col-md-12">
				<table class="table table-striped">
					<tr>
						<th>工号</th>
						<th>姓名</th>
						<th>邮箱</th>
						<th>性别</th>
						<th>部门</th>
						<th>操作</th>
					</tr>
					<c:forEach items="${pageInfo.list }" var="emp">
						<tr>
							<td>${emp.id }</td>
							<td>${emp.lastName }</td>
							<td>${emp.email }</td>
							<td>${emp.gender == "F" ? "女" : "男" }</td>
							<td>${emp.dept.deptName }</td>
							<td>
								<button class="btn btn-info btn-sm">
									<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
									编辑
								</button>
								<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="raw">
			<!-- 分页文字信息 -->
			<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="${WEB_PATH }/emps?pageNum=1">首页</a></li>
						<c:if test="${pageInfo.hasPreviousPage }">
							<li><a
								href="${WEB_PATH }/emps?pageNum=${pageInfo.pageNum - 1}"
								aria-label="Previous"> <span aria-hidden="true">&laquo;</span>
							</a></li>
						</c:if>
						<c:forEach items="${pageInfo.navigatepageNums }" var="pn">
							<c:if test="${pn == pageInfo.pageNum}">
								<li class="active"><span>${pn } <span
										class="sr-only">(current)</span></span></li>
							</c:if>
							<c:if test="${pn != pageInfo.pageNum}">
								<li><a href="${WEB_PATH }/emps?pageNum=${pn }">${pn }</a></li>
							</c:if>
						</c:forEach>
						<c:if test="${pageInfo.hasNextPage }">
							<li><a
								href="${WEB_PATH }/emps?pageNum=${pageInfo.pageNum + 1}"
								aria-label="Next"> <span aria-hidden="true">&raquo;</span>
							</a></li>
						</c:if>
						<li><a href="${WEB_PATH }/emps?pageNum=${pageInfo.pages }">尾页</a></li>
					</ul>
				</nav>
			</div>
		</div>

	</div>

</body>
</html>

至此,员工信息的分页查询及显示功能已实现完毕,但该实现仅适用于浏览器-服务器结构,若实现移动端与服务器的交互则需要重新修改后台代码,在此可直接返回分页结果的JSON数据以使服务器适配不同的客户端。


###3. 返回分页结果的JSON数据
通过JSON的形式返回分页结果以实现员工信息的查询与显示,主要步骤包括:

  • index.jsp页面直接发送Ajax请求进行员工分页数据的查询;
  • 服务器将查出的数据,以JSON字符串的形式返回给客户端;
  • 客户端可以使用javascript对JSON字符串进行解析,并通过dom增删改来显示页面;
  • 返回JSON字符串串,可以实现客户端的无关性。

首先,在pom.xml文件中添加jackson包的依赖信息

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.6</version>
</dependency>

然后,修改控制器的目标方法,使其返回封装有分页信息的JSON字符串

@Controller
public class EmployeeHandler {

	@Autowired
	private EmployeeService employeeService;
	
	@RequestMapping("/emps")
	@ResponseBody
	public Message handleGetEmpsRtnJson(@RequestParam(value = "pageNum", defaultValue="1") Integer pageNum, Model model) {
		PageHelper.startPage(pageNum, 6);
		List<Employee> list = employeeService.getAll();
		PageInfo pageInfo = new PageInfo(list, 6);
		// 返回带状态码的JSON数据
		return Message.success().add("pageInfo", pageInfo);
	}
}
package com.qiaobc.crud.bean;
public class Message {
	
	// 状态码  100-成功  200-失败
	private Integer code;
	
	// 提示信息
	private String msg;
	
	// 待返回数据
	Map<String, Object> extend = new HashMap<String, Object>();
	
	// 成功
	public static Message success() {
		Message result = new Message();
		result.setCode(100);
		result.setMsg("操作成功");
		return result;
	}
	
	// 失败
	public static Message fail() {
		Message result = new Message();
		result.setCode(200);
		result.setMsg("操作失败");
		return result;
	}
	
	public Integer getCode() {
		return code;
	}

	public void setCode(Integer 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;
	}

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

}

最后,修改index.jsp显示页面,以解析返回的JSON字符串,并显示在页面上

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>员工信息显示</title>
<%
	pageContext.setAttribute("WEB_PATH", request.getContextPath());
%>
<script type="text/javascript"
	src="${WEB_PATH }/static/javascript/jquery-3.3.1.min.js"></script>
<link
	href="${WEB_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"
	rel="stylesheet">
<script
	src="${WEB_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>

	<!-- 搭建显示界面 -->
	<div class="container">
		<!-- 标题行 -->
		<div class="raw">
			<div class="col-md-12">
				<h1>SSM_CRUD</h1>
			</div>
		</div>
		<!-- 按钮行 -->
		<div class="raw">
			<div class="col-md-4 col-md-offset-8">
				<button class="btn btn-primary">新增</button>
				<button class="btn btn-danger">删除</button>
			</div>
		</div>
		<!-- 显示表格数据 -->
		<div class="raw">
			<div class="col-md-12">
				<table class="table table-striped" id="emps_table">
					<thead>
						<tr>
							<th>工号</th>
							<th>姓名</th>
							<th>邮箱</th>
							<th>性别</th>
							<th>部门</th>
							<th>操作</th>
						</tr>
					</thead>
					<tbody></tbody>
				</table>
			</div>
		</div>
		<!-- 显示分页信息 -->
		<div class="raw">
			<!-- 分页文字信息 -->
			<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">
		// 页面加载完成后,发送Ajax请求,获取分页数据
		$(function() {
			to_page(1);
		});

		function to_page(pn) {
			$.ajax({
				url : "${WEB_PATH}/emps",
				data : "pageNum=" + pn,
				type : "GET",
				success : function(result) {
					// console.log(result);
					//1.解析并显示员工数据
					build_emps_table(result);
					//2.解析并显示分页信息
					build_page_info(result);
					//3.解析显示分页条数据
					build_page_nav(result);
				}
			});
		};

		//解析并显示员工数据
		function build_emps_table(result) {
			$("#emps_table tbody").empty();
			var emps = result.extend.pageInfo.list;
			$.each(emps, function(index, item) {
				//alert(item.lastName);
				var idTd = $("<td></td>").append(item.id);
				var lastNameTd = $("<td></td>").append(item.lastName);
				var emailTd = $("<td></td>").append(item.email);
				var genderTd = $("<td></td>").append(
						item.gender == "M" ? "男" : "女");
				var deptNameTd = $("<td></td>").append(item.dept.deptName);
				/*
					<button class="btn btn-info btn-sm">
						<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
						编辑
					</button>
				 */
				var editBtn = $("<button></button>").addClass(
						"btn btn-info btn-sm").append(
						$("<span></span>").addClass(
								"glyphicon glyphicon-pencil")).append("编辑");
				var deleteBtn = $("<button></button>").addClass(
						"btn btn-danger btn-sm").append(
						$("<span></span>")
								.addClass("glyphicon glyphicon-trash")).append(
						"删除");
				var buttonsTd = $("<td></td>").append(editBtn).append(" ")
						.append(deleteBtn);

				$("<tr></tr>").append(idTd).append(lastNameTd).append(emailTd)
						.append(genderTd).append(deptNameTd).append(buttonsTd)
						.appendTo("#emps_table tbody");
			});
		}

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

		//解析并显示分页条数据
		function build_page_nav(result) {
			$("#page_nav_area").empty();

			var pageInfo = result.extend.pageInfo;

			var ul = $("<ul></ul>").addClass("pagination");

			var firstPageLi = $("<li></li>").append(
					$("<a></a>").append("首页").attr("href", "#"));
			var lastPageLi = $("<li></li>").append(
					$("<a></a>").append("尾页").attr("href", "#"));

			var prePageLi = $("<li></li>").append(
					$("<a></a>").append("&laquo;"));
			var nextPageLi = $("<li></li>").append(
					$("<a></a>").append("&raquo;"));

			if (result.extend.pageInfo.hasPreviousPage == false) {
				prePageLi.addClass("disabled");
				firstPageLi.addClass("disabled");
			} else {
				prePageLi.click(function() {
					to_page(result.extend.pageInfo.pageNum - 1);
				});
				firstPageLi.click(function() {
					to_page(1);
				});
			}
			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);

			$.each(result.extend.pageInfo.navigatepageNums, function(index,
					item) {
				var numLi = $("<li></li>").append($("<a></a>").append(item));
				if (result.extend.pageInfo.pageNum == item) {
					numLi.addClass("active");
				}
				numLi.click(function() {
					to_page(item);
				});
				ul.append(numLi);
			});

			ul.append(nextPageLi).append(lastPageLi);

			var navEle = $("<nav></nav>").append(ul);

			navEle.appendTo("#page_nav_area");

		}
	</script>


</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值