编译软件:IntelliJ IDEA 2019.2.4 x64
操作系统:win10 x64 位 家庭版
Maven版本:apache-maven-3.6.3
Mybatis版本:3.5.6
一. 什么是分页?
以百度搜索为例,如下所示
二. 为什么使用分页?
👉好处
- 可以提高用户体验度
- 可以降低服务器端压力
三. 如何设计一个Page类(分页)?
👉举例,例如 47/60
- 47:当前页码
- 60:总页数
👉Mysql中分页查询代码如下
#x:开启下标 y:每页显示数据数量 SELECT * FROM tbl_employee WHERE 1=1 LIMIT x,y
👉需要明确Page类的相关参数
pageNum
:当前页码pages
:总页数【计算:总页数=总数据数量/每页显示数据数量】total
:总数据数量pageSize
:每页显示数据数量List\<T>
:当前页显示数据集合
四. PageHelper是什么?
👉概述
PageHelper是MyBatis中非常方便的第三方分页插件
👉官方参考文档
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
五. 如何使用PageHelper?(入门案例)
👉步骤
- 导入PageHelperE的相关jar包
- 在mybatis-config.xml中配置分页插件
- 在查询之前,设置分页条件
- 在查询之后,将结果封装Pagelnfo中,使用Pagelnfo实现后续分页效果
👉用法案例
查询所有的员工信息,使用PageHelper插件进行分页显示,暂定分页效果为显示第二页,展示4条数据
示例代码如下:
①导入PageHelper的相关jar包
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.0.0</version> </dependency>
②在mybatis-config.xml中配置分页插件
<!-- 配置分页插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
④在查询之前,设置分页条件
使用 PageHelper.startPage(2,4)并测试PageHelper相关使用方法
@Test public void test03(){ try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //通过SqlSessionFactory对象调用openSession(); SqlSession sqlSession = sqlSessionFactory.openSession(); //获取EmployeeMapper的代理对象 EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class); //在查询之前,设置分页条件 //显示第一页,展示3条数据 Page<Object> pages = PageHelper.startPage(2, 4); //员工的查询条件对象 EmployeeExample ee=new EmployeeExample(); //当员工的查询条件对象没有设任何属性值时,默认是查询所有的员工信息 List<Employee> employees = employeeMapper.selectByExample(ee); for (Employee employee : employees) { System.out.println(employee); } //实现类似 "2/3"的效果(当前页码/数据的总页数) System.out.println(pages.getPageNum()+"/"+pages.getPages()); System.out.println("总数据量 :"+pages.getTotal()); System.out.println("每页显示的数据量 :"+pages.getPageSize()); System.out.println("当前页显示的数据集合 :"+pages.getResult()); for (Object page : pages.getResult()) { System.out.println(page); } } catch (IOException e) { e.printStackTrace(); } }
⑤在查询之后,将结果封装Pagelnfo中,使用Pagelnfo实现后续分页效果
🤔为什么要使用Pagelnfo去封装分页的结果?
PageInfo就是用来封装分页信息的一个工具类,它能够将分页所需的所有信息组合在一起,并返回给前端或其他业务逻辑进行处理。
使用PageInfo去封装分页的结果可以带来以下好处:
- 方便管理分页相关的信息:PageInfo可以统一管理当前页码、每页记录数、总记录数、总页数等分页信息,使得代码更加清晰易读。
- 便于扩展和维护:当需求变化时,可以通过修改PageInfo类来快速实现新需求,而不需要对已有的代码进行大量修改,从而提高了系统的可维护性和扩展性。
- 更加灵活的分页展示效果:通过调整PageInfo中的参数设置,可以实现不同的分页展示效果,例如改变每页显示的记录数,调整页码的排列顺序等等。
@Test public void test04(){ try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //通过SqlSessionFactory对象调用openSession(); SqlSession sqlSession = sqlSessionFactory.openSession(); //获取EmployeeMapper的代理对象 EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class); //在查询之前,设置分页条件 //显示第一页,展示3条数据 Page<Object> pages = PageHelper.startPage(2, 4); //员工的查询条件对象 EmployeeExample ee=new EmployeeExample(); //当员工的查询条件对象没有设任何属性值时,默认是查询所有的员工信息 List<Employee> employees = employeeMapper.selectByExample(ee); //查询之后,将结果封装Pagelnfo中,使用Pagelnfo实现后续分页效果 PageInfo<Employee> pageInfo=new PageInfo<>(employees,5); //实现类似 "2/3"的效果(当前页码/数据的总页数) System.out.println(pageInfo.getPageNum()+"/"+pageInfo.getPages()); //展示当前页面所有显示的数据 for (Employee employee : pageInfo.getList()) { System.out.println(employee); } System.out.println("总数据量 :"+pageInfo.getTotal()); System.out.println("是否有上一页:"+pageInfo.isHasPreviousPage()); System.out.println("上一页是:"+pageInfo.getPrePage()); System.out.println("是否有下一页:"+pageInfo.isHasNextPage()); System.out.println("下一页是:"+pageInfo.getNextPage()); System.out.println("是否是第一页:"+pageInfo.isIsFirstPage()); System.out.println("是否是最后一页:"+pageInfo.isIsLastPage()); System.out.println("导航页的第一个页码是:"+pageInfo.getNavigateFirstPage()); System.out.println("导航页的最后一个页码是:"+pageInfo.getNavigateLastPage()); System.out.println("导航页的总页码是:"+pageInfo.getNavigatePages()); } catch (IOException e) { e.printStackTrace(); } }
六. 分页插件是根据什么样的页码逻辑去显示当前导航页的页码?
🤔假设
设置导航页只显示5个页码,然表中共有65条数据,按照每页只能显示5条数据,那么总页数为13页
具体分页页码逻辑如下:
当前页码 | 导航页显示的页码范围 |
1 | 1,2,3,4,5 |
2 | 1,2,3,4,5 |
3 | 1,2,3,4,5 |
4 | 2,3,4,5,6 |
5 | 3,4,5,6,7 |
6 | 4,5,6,7,8 |
… | … |
13 | 9,10,11,12,13 |
💡规律总结
为提高用户体验度,一般当前页码要满足【它要位于导航页显示的页码范围的中间】的布局条件。当前页码除(1,2,12,13)外,才适用以下规则生成相应的导航页。它+2与-2的两个页码值要分别成为导航页的第一个页码与最后一个页码,导航页要凑够5个页码,比如当前页码为3,那导航页显示的页码为(1,2,3,4,5),其他以此类推。当前页码要居于中间以满足布局要求。当前页码是逐步递增的,但它不能小于1(最小页码),不能大于13(最大页码),导航页显示的页码范围随着当前页码的变化而变化。
🤔为什么当前页码为(1,2,12,13)时,不适用上述生成规则生成导航页?
因为要想让它居于导航页的中间,它+2与-2的两个页码要么小于最小页码(1),要么大于最大页码(13),并且依据上述规则生成相应的导航页没有意义, 例如若它为1,则生成的导航页显示的是(-1,0,1,2,3),有意义吗?所以当当前页码为(1,2)时,相应导航页为(1,2,3,4,5),当前页码为(12,13),相应导航页为(9,10,11,12,13)。