分页显示管理员信息部分
目标
以分页的形式把管理员信息显示到页面上。特殊需求:兼顾关键词查询,让后端代码不管有没有查询条件都能够以分页形式显示数据。
思路
后端代码
AdminMapper.xml
<select id="selectAdminListByKeyword" resultMap="BaseResultMap">
select <include refid="Base_Column_List" />
from t_admin
where login_acct like CONCAT("%",#{keyword},"%")
or user_name like CONCAT("%",#{keyword},"%")
or email like CONCAT("%",#{keyword},"%")
</select>
AdminMapper中的抽象方法
List<Admin> selectAdminListByKeyword(String keyword);
准备 PageHelper 环境
<!-- MyBatis 分页插件 -->
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
配置 SqlSessionFactoryBean
<!-- 配置 SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 装配数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 指定 MyBatis 全局配置文件位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 指定 Mapper 配置文件位置 --> <property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/>
<!-- 配置 MyBatis 的插件 --> <property name="plugins">
<array>
<!-- 配置 PageHelper -->
<bean class="com.github.pagehelper.PageHelper">
<!-- 配置相关属性 --> <property name="properties"> <props>
<!-- 配置数据库方言,告诉 PageHelper 当前使用的具体数据库, -->
<!-- 让 PageHelper 可以根据当前数据库生成对应的分页 SQL 语 句 -->
<prop key="dialect">mysql</prop>
<!-- 配置页码的合理化修正 -->
<!-- 让 PageHelper 自动把浏览器传来的 PageNum 修正到 0~总页 数范围 --> <prop key="reasonable">true</prop> </props> </property> </bean> </array> </property> </bean>
AdminService 方法
@Override
public PageInfo<Admin> getAdminPage(String keyword, Integer pageNum, Integer pageSize) {
// 1.开启分页功能 PageHelper.startPage(pageNum, pageSize);
// 2.查询 Admin 数据
List<Admin> adminList = adminMapper.selectAdminListByKeyword(keyword);
// ※辅助代码:打印 adminList 的全类名
Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class); logger.debug("adminList 的全类名是:"+adminList.getClass().getName());
// 3.为了方便页面使用将 adminList 封装为
PageInfo PageInfo<Admin> pageInfo = new PageInfo<>(adminList);
return pageInfo
; }
AdminHandler 方法
@RequestMapping("/admin/page.html")
public String getAdminPage( /
/ 注意:页面上有可能不提供关键词,要进行适配
// 在@RequestParam注解中设置defaultValue属性为空字符串表示浏览器不提 供关键词时,keyword 变量赋值为空字符串
@RequestParam(value="keyword", defaultValue="") String keyword,
// 浏览器未提供 pageNum 时,默认前往第一页
@RequestParam(value="pageNum", defaultValue="1") Integer pageNum,
// 浏览器未提供 pageSize 时,默认每页显示 5 条记录
@RequestParam(value="pageSize", defaultValue="5") Integer pageSize, ModelMap modelMap ) {
// 查询得到分页数据
PageInfo<Admin> pageInfo = adminService.getAdminPage(keyword, pageNum, pageSize);
// 将分页数据存入模型
modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo); return "admin-page"; }
前端代码
抽取页面公共部分
head 标签部分
<%@ include file="/WEB-INF/include-header.jsp" %>
nav 标签部分
<%@ include file="/WEB-INF/include-nav.jsp" %>
sidebar 部分
<%@ include file="/WEB-INF/include-sidebar.jsp" %>
创建 JSP 模板
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh-CN">
<head> <%@include file="/WEB-INF/include-header.jsp" %>
</head> <body><%@include file="/WEB-INF/include-nav.jsp" %><div class="container-fluid">
<div class="row">
<%@include file="/WEB-INF/include-sidebar.jsp" %>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
</div>
</div>
</div>
</body>
</html>
在 admin-page 页面显示真实数据
加入 JSTL 依赖
<!-- JSTL 标签库 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<tbody>
<c:if test="${empty requestScope.pageInfo.list }">
<tr> <td colspan="2">抱歉!没有查询到相关的数据!
</td>
</tr>
</c:if>
<c:if test="${!empty requestScope.pageInfo.list }">
<c:forEach items="${requestScope.pageInfo.list }" var="admin" varStatus="myStatus"><tr> <td>${myStatus.count }</td>
<td><input type="checkbox"></td> <td>${admin.loginAcct }</td>
<td>${admin.userName }</td> <td>${admin.email }</td>
<td> <button type="button" class="btn btn-success btn-xs">
<i class=" glyphicon glyphicon-check"></i>
</button> <button type="button" class="btn btn-primary btn-xs">
<i class=" glyphicon glyphicon-pencil"></i>
</button> <button type="button" class="btn btn-danger btn-xs">
<i class=" glyphicon glyphicon-remove"></i>
</button>
</td>
</tr>
</c:forEach>
</c:if>
</tbody>
加入 Pagination 插件环境
把相关文件加入到工程
之后在有需要的页面进行引入
<link rel="stylesheet" href="css/pagination.css"> <script type="text/javascript" src="jquery/jquery.pagination.js"></script>
注意:Pagination在jQuery的后面!
HTML的代码所需要的准备
使用Pageination要求的div替换原有的页面代码
//要替换的代码块
<tfoot>
<tr>
<td colspan="6" align="center">
<ul class="pagination">
<li class="disabled"><a href="#">上一页</a></li>
<li class="active"><a href="#">1 <span
class="sr-only">(current)</span></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="#">下一页</a></li>
</ul>
</td>
</tr>
</tfoot>
//新代码块
<tfoot>
<tr>
<td colspan="6" align="center">
<div id="Pagination" class="pagination"><!-- 这里显示分页 --></div>
</td>
</tr>
</tfoot>
编写 Pagination 代码
$(function(){
// 调用后面声明的函数对页码导航条进行初始化操作
initPagination();
});
// 生成页码导航条的函数
function initPagination() {
// 获取总记录数
var totalRecord = ${requestScope.pageInfo.total};
// 声明一个JSON对象存储Pagination要设置的属性
var properties = {
num_edge_entries: 3, // 边缘页数
num_display_entries: 5, // 主体页数
callback: pageSelectCallback, // 指定用户点击“翻页”的按钮时跳转页面的回调函数
items_per_page: ${requestScope.pageInfo.pageSize}, // 每页要显示的数据的数量
current_page: ${requestScope.pageInfo.pageNum - 1}, // Pagination内部使用pageIndex来管理页码,pageIndex从0开始,pageNum从1开始,所以要减一
prev_text: "上一页", // 上一页按钮上显示的文本
next_text: "下一页" // 下一页按钮上显示的文本
};
// 生成页码导航条
$("#Pagination").pagination(totalRecord, properties);
}
// 回调函数的含义:声明出来以后不是自己调用,而是交给系统或框架调用
// 用户点击“上一页、下一页、1、2、3……”这样的页码时调用这个函数实现页面跳转
// pageIndex是Pagination传给我们的那个“从0开始”的页码
function pageSelectCallback(pageIndex, jQuery) {
// 根据pageIndex计算得到pageNum
var pageNum = pageIndex + 1;
// 跳转页面
window.location.href = "admin/get/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";
// 由于每一个页码按钮都是超链接,所以在这个函数最后取消超链接的默认行为
return false;
}
修改pagination源码
关键字的查询
页面上调整查询表单
页面:admin- page
修改后代码:`
<form action="admin/get/page.html" method="post" class="form-inline" role="form" style="float: left;"><div class="form-group has-feedback"> <div class="input-group"> <div class="input-group-addon">查询条件</div> <input name="keyword" class="form-control has-success" type="text" placeholder="请输入查询条件"> </div> </div> <button type="submit" class="btn btn-warning"> <i class="glyphicon glyphicon-search"></i> 查询 </button> </form>
在翻页时保持查询条件
window.location.href = "admin/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";
param将请求参数取出,jsp解析完后,此时换成具体的值,请求参数就会被带上
单条删除
删除功能的主体代码
调整删除按钮
原页面代码 admin-page.jsp
<button type="button" class="btn btn-danger btn-xs">
<i class=" glyphicon glyphicon-remove"></i>
</button>
修改后
<a href="admin/remove/${admin.id}.html" class="btn btn-danger btn-xs"> <i class=" glyphicon glyphicon-remove"></i></a>
文件名AdminHandler.java
@RequestMapping("/admin/remove/{adminId}/{pageNum}/{keyword}.html")
public String remove(
@PathVariable("adminId") Integer adminId,
@PathVariable("pageNum") Integer pageNum,
@PathVariable("keyword") String keyword
) {
//执行删除
adminService.remove(adminId);
// 页面的跳转:回到分页的页面
//方案一 :return "admin-page";
//方案二 return "forward:admin/get/page.html"; 一旦刷新页面会删除操作
//方案三重定向到地址,同时为了保持原本所在的页面和查询关键词再附加pageNum和keyword两个请求参数
return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}
AdminService.java
void remove(Integer adminId);
AdminServiceImpl
@Override
public void remove(Integer adminId) {
adminMapper.deleteByPrimaryKey(adminId);
}
方案一方式的效果
最终方案的效果
个人拓展:
1.删除是否为当前登录用户的校验和自定义异常
2.删除时确定删除的弹窗提示