• 详解mybatis三种分页方式


    前言

    分页是我们在开发中绕不过去的一个坎!当你的数据量大了的时候,一次性将所有数据查出来不现实,所以我们一般都是分页查询的,减轻服务端的压力,提升了速度和效率!也减轻了前端渲染的压力!

    注意:由于 java 允许的最大整数为 2147483647,所以 limit 能使用的最大整数也是 2147483647,一次性取出大量数据可能引起内存溢出,所以在大数据查询场合慎重使用!

    一、Limit分页

    语法:

    limit ${startPos},${pageSize}
    

    在实际项目中我们一般会加上为空为null判断,如下:

    1. <if test="startPos!=null and pageSize!=null">
    2.     limit ${startPos},${pageSize}
    3. if>

    业务层代码:

    1. <select id="getUserInfo1" parameterType="map" resultType="dayu">
    2.     select * from user
    3.     <if test="startPos!=null and pageSize!=null">
    4.         limit ${startPos},${pageSize}
    5.     if>
    6. select>
    List getUserInfo1(Map map);
    
    1. @Test
    2.  public void selectUser() {
    3.      SqlSession session = MybatisUtils.getSession();
    4.      UserMapper mapper = session.getMapper(UserMapper.class);
    5.      //这里塞值
    6.       Map parms = new HashMap<>();
    7.       parms.put("startPos","0");
    8.       parms.put("pageSize","5");
    9.      List users = mapper.getUserInfo1(parms);
    10.      for (User map: users){
    11.          System.out.println(map);
    12.     }
    13.      session.close();
    14. }

    执行结果:

    传入0,10时:

     

    总结:

     

    • limit 0,10;

    • 0 代表从第0条数据开始

    • 10 代表查10条数据

    • 等到第二页的时候就是 limit 10,10;

    以此类推!

    这些内容其实就时MySQL中的内容,不作再详细讲解了。

    二、RowBounds分页(不推荐使用)

    RowBounds帮我们省略了limit的内容,我们只需要在业务层关注分页即可!无须再传入指定数据!

    但是,这个属于逻辑分页,即实际上sql查询的是所有的数据,在业务层进行了分页而已,比较占用内存,而且数据更新不及时,可能会有一定的滞后性!不推荐使用!

    RowBounds对象有2个属性,offset和limit。

    • offset:起始行数

    • limit:需要的数据行数

    因此,取出来的数据就是:从第offset+1行开始,取limit行

    业务层代码:

    1. @Test
    2. public void selectUserRowBounds() {
    3.     SqlSession session = MybatisUtils.getSession();
    4.     UserMapper mapper = session.getMapper(UserMapper.class);
    5.     // List users = session.selectList("com.dy.mapper.UserMapper.getUserInfoRowBounds",null,new RowBounds(0, 5));
    6.     List users = mapper.getUserInfoRowBounds(new RowBounds(0,5));
    7.     for (User map: users){
    8.         System.out.println(map);
    9.     }
    10.     session.close();
    11. }
    List getUserInfoRowBounds(RowBounds rowBounds);
    
    1. <select id="getUserInfoRowBounds" resultType="dayu">
    2.    select * from user
    3. select>

    执行查看结果:

    三、Mybatis_PageHelper分页插件

     

    官方GitHub地址:

    https://github.com/pagehelper/Mybatis-PageHelper

    引入jar包

    1.    com.github.pagehelper
    2.    pagehelper
    3.    5.1.7

    配置MyBatis核心配置文件

    1.     "com.github.pagehelper.PageInterceptor" />

    业务层代码

    1. @Test
    2. public void selectUserPageHelper() {
    3.     SqlSession session = MybatisUtils.getSession();
    4.     UserMapper mapper = session.getMapper(UserMapper.class);
    5.     //第二种,Mapper接口方式的调用,推荐这种使用方式。
    6.     PageHelper.startPage(13);
    7.     List list = mapper.getUserInfo();
    8.     //用PageInfo将包装起来
    9.     PageInfo page = new PageInfo(list);
    10.     for (User map: list){
    11.         System.out.println(map);
    12.     }
    13.     System.out.println("page:---"+page);
    14.     session.close();
    15. }

    执行结果

    总结:

     

    PageHelper还是很好用的,也是物理分页!

    实际上我们一般用第二种比较多:Mapper接口方式的调用

    1. //第一种,RowBounds方式的调用
    2. List list = sqlSession.selectList("x.y.selectIf"nullnew RowBounds(010));
    3. //第二种,Mapper接口方式的调用,推荐这种使用方式。
    4. PageHelper.startPage(110);
    5. List list = userMapper.selectIf(1);
    6. //第三种,Mapper接口方式的调用,推荐这种使用方式。
    7. PageHelper.offsetPage(110);
    8. List list = userMapper.selectIf(1);
    9. //第四种,参数方法调用
    10. //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
    11. public interface CountryMapper {
    12.     List selectByPageNumSize(
    13.             @Param("user") User user,
    14.             @Param("pageNum") int pageNum, 
    15.             @Param("pageSize") int pageSize);
    16. }
    17. //配置supportMethodsArguments=true
    18. //在代码中直接调用:
    19. List list = userMapper.selectByPageNumSize(user, 110);
    20. //第五种,参数对象
    21. //如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
    22. //有如下 User 对象
    23. public class User {
    24.     //其他fields
    25.     //下面两个参数名和 params 配置的名字一致
    26.     private Integer pageNum;
    27.     private Integer pageSize;
    28. }
    29. //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
    30. public interface CountryMapper {
    31.     List selectByPageNumSize(User user);
    32. }
    33. //当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
    34. List list = userMapper.selectByPageNumSize(user);
    35. //第六种,ISelect 接口方式
    36. //jdk6,7用法,创建接口
    37. Page page = PageHelper.startPage(110).doSelectPage(new ISelect() {
    38.     @Override
    39.     public void doSelect() {
    40.         userMapper.selectGroupBy();
    41.     }
    42. });
    43. //jdk8 lambda用法
    44. Page page = PageHelper.startPage(110).doSelectPage(()-> userMapper.selectGroupBy());
    45. //也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
    46. pageInfo = PageHelper.startPage(110).doSelectPageInfo(new ISelect() {
    47.     @Override
    48.     public void doSelect() {
    49.         userMapper.selectGroupBy();
    50.     }
    51. });
    52. //对应的lambda用法
    53. pageInfo = PageHelper.startPage(110).doSelectPageInfo(() -> userMapper.selectGroupBy());
    54. //count查询,返回一个查询语句的count数
    55. long total = PageHelper.count(new ISelect() {
    56.     @Override
    57.     public void doSelect() {
    58.         userMapper.selectLike(user);
    59.     }
    60. });
    61. //lambda
    62. total = PageHelper.count(()->userMapper.selectLike(user));

    拓展

    1. //获取第1页,10条内容,默认查询总数count
    2. PageHelper.startPage(110);
    3. List list = userMapper.selectAll();
    4. //用PageInfo对结果进行包装
    5. PageInfo page = new PageInfo(list);
    6. //测试PageInfo全部属性
    7. //PageInfo包含了非常全面的分页属性
    8. assertEquals(1, page.getPageNum());
    9. assertEquals(10, page.getPageSize());
    10. assertEquals(1, page.getStartRow());
    11. assertEquals(10, page.getEndRow());
    12. assertEquals(183, page.getTotal());
    13. assertEquals(19, page.getPages());
    14. assertEquals(1, page.getFirstPage());
    15. assertEquals(8, page.getLastPage());
    16. assertEquals(true, page.isFirstPage());
    17. assertEquals(false, page.isLastPage());
    18. assertEquals(false, page.isHasPreviousPage());
    19. assertEquals(true, page.isHasNextPage());

    这种方式十分方便快捷好用!推荐使用!

    篇幅有限,不可能所有用法都演示一遍!有兴趣的小伙伴可以自行测试一遍!

    悄悄的说,反正我是全部试了一遍,还整合了Spring,加了拦截器测试了!

  • 相关阅读:
    如何选择适合企业的ERP管理系统
    Go 程序打成 rpm 包
    Spark 源码分析-FIFO/FAIR调度策略
    移动开发技术
    高数 |【2020数一真题】部分错题及经典题自用思路整理
    Python量化投资——投资组合的评价和可视化(下):使用Matplotlib生成专业的投资回测数据可视化仪表盘【源码+详解】
    [InfoSec CTF 2022] Crypto,pwn都差一题
    六石管理学:垃圾场效应:工作不管理,就会变成垃圾场
    延时消息队列
    Android Studio支持预览Markdown文件
  • 原文地址:https://blog.csdn.net/qq_45637260/article/details/126126510