【SSM整合】3—分页
⭐⭐⭐⭐⭐⭐
Github主页👉https://github.com/A-BigTree
笔记链接👉https://github.com/A-BigTree/Code_Learning
⭐⭐⭐⭐⭐⭐
Spring专栏👉https://blog.csdn.net/weixin_53580595/category_12279588.html
SpringMVC专栏👉https://blog.csdn.net/weixin_53580595/category_12281721.html
Mybatis专栏👉https://blog.csdn.net/weixin_53580595/category_12279566.html
如果可以,麻烦各位看官顺手点个star~😊
如果文章对你有所帮助,可以点赞👍收藏⭐支持一下博主~😆
文章目录
3 分页
3.1 分页的概念
3.1.1 提出问题
如果应用程序显示数据不分页,会有三个问题:
- 用户查看数据非常不方便。
- 所有数据不分冷热全部显示出来,冷数据白白占用存储空间,浪费内存。
- 在服务器端查询全部数据占用内存很大,给整个系统增加了很大压力。
3.1.2 分页的概念
把系统中要显示的数据分成较小的单元,每个单元作为『一页』显示给用户。每次访问服务器只查询一页数据。
分页的好处:
- 用户体验较好。
- 服务器端每次只查询一部分数据,内存压力减小。
- 对冷数据减少查询的次数,据此对系统性能进行优化。
3.1.3 实现分页的基本逻辑
物理分页
具体数据库不同,分页语法有区别。下面我们以 MySQL 为例来说明。MySQL 的分页需要借助 LIMIT 子句来完成。
select emp_id,emp_name,emp_salary from t_emp limit 0,5; # 查询第一页数据
select emp_id,emp_name,emp_salary from t_emp limit 5,5; # 查询第二页数据
select emp_id,emp_name,emp_salary from t_emp limit 10,5;# 查询第三页数据
公式:
limit(pageNo−1)×pageSize,pageSizelimit\\ \\ (pageNo-1)\\times pageSize,pageSize limit (pageNo−1)×pageSize,pageSize
注意:在 SQL 的语法中,要么就不加LIMIT子句,如果非要写LIMIT子句,那么LIMIT子句必须出现在SQL语句最后,什么ORDER BY、GROUP BY、WHERE 等子句都必须在 LIMIT 子句前面。
逻辑分页
为了能够在页面上全面显示分页相关的细节数据,总页数需要计算得到。
分页流程
- 查询总记录数
- 查询当前页数据
- 根据总记录数和每页条数计算总页数
- 在1~总页数之间修正页码
- 封装上述所有数据,发送到页面显示
3.2 Mybatis分页插件
3.2.1 操作
导入依赖
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version>
</dependency>
配置
<!-- 配置 SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">……<!-- 在 plugins 属性中配置 Mybatis 插件 --><property name="plugins"><array><bean class="com.github.pagehelper.PageInterceptor"><property name="properties"><props><!-- 设置 reasonable 为 true 表示将页码进行合理化修正。页码的有效范围:1~总页数 --><prop key="reasonable">true</prop><!-- 数据库方言:同样都是 SQL 语句,拿到不同数据库中,在语法上会有差异 --><!-- 默认情况下,按照 MySQL 作为数据库方言来运行 --><prop key="helperDialect">mysql</prop></props></property></bean></array></property></bean>
非侵入式
开启分页功能,就在 SQL 语句后面附加 LIMIT 子句并查询总记录数;不开启就还是按照原样查询。分页功能对原有的 Mapper 接口、SQL 语句没有任何影响。这个效果可以称之为是非侵入式,也可以说是可插拔的。
3.3 案例中分页
3.3.1 首页超链接
<a th:href="@{/get/page/1}">显示分页数据</a>
3.3.2 处理方法
@RequestMapping("/get/page/{pageNo}")
public String getPage(@PathVariable("pageNo") Integer pageNo, Model model) {// PageInfo 对象封装了和分页相关的所有信息PageInfo<Emp> pageInfo = empService.getPageInfo(pageNo);// 将 PageInfo 对象存入模型model.addAttribute("pageInfo", pageInfo);return "emp-page";
}
3.3.3 Service方法
@Override
public PageInfo<Emp> getPageInfo(Integer pageNo) {// 1、确定每页显示数据的条数int pageSize = 5;// 2、设定分页数据:开启分页功能。开启后,后面执行的 SELECT 语句会自动被附加 LIMIT 子句,// 而且会自动查询总记录数PageHelper.startPage(pageNo, pageSize);// 3、正常执行查询List<Emp> empList = empMapper.selectAll();// 4、封装为 PageInfo 对象返回return new PageInfo<>(empList);
}
3.3.4 页面展示
显示数据
……<tr th:each="emp : ${pageInfo.list}">
……
显示翻页导航栏
<tr><td colspan="5"><span th:each="targetNum : ${pageInfo.navigatepageNums}"><!-- 不是当前页显示为超链接 --><a th:if="${targetNum != pageInfo.pageNum}"th:href="@{/employee/page/}+${targetNum}"th:text="'['+${targetNum}+']'">目标页面的页码</a><!-- 是当前页不需要显示为超链接 --><span th:if="${targetNum == pageInfo.pageNum}" th:text="'['+${targetNum}+']'">当前页页码</span></span></td>
</tr>
<tr><td colspan="5"><span th:if="${pageInfo.hasPreviousPage}"><a th:href="@{/employee/page/1}">首页</a><a th:href="@{/employee/page/}+${pageInfo.prePage}">上一页</a></span>[[${pageInfo.pageNum}]]/[[${pageInfo.pages}]][[${pageInfo.pageNum}+'/'+${pageInfo.pages}]]<span th:if="${pageInfo.hasNextPage}"><a th:href="@{/employee/page/}+${pageInfo.nextPage}">下一页</a><a th:href="@{/employee/page/}+${pageInfo.pages}">末页</a></span></td>
</tr>
<tr><td colspan="5"><!-- 绑定值改变事件响应函数 --><input id="jumpToPageNumInput" type="text" name="jumpToPageNum" placeholder="请输入您想直接跳转的页码" /></td>
</tr>
配套的JS代码
// 获取页码文本框的元素对象
var jumpPageNumEle = document.getElementById("jumpToPageNumInput");// 给页码文本框绑定值改变响应函数
jumpPageNumEle.onchange = function () {// 触发值改变响应函数后,获取当前文本框中用户输入的值var targetNum = this.value;// 检测用户输入的数据是否是数字if (isNaN(targetNum)) {// 如果不是数字则恢复文本框this.value = "";// 当前函数结束return ;}// 如果用户输入合法,则跳转页面// [[@{/employee/page/}]] 表示解析 Thymeleaf 表达式window.location.href = "[[@{/employee/page/}]]" + targetNum;};