0%

Mybatis分页

  • 分页的原因在于,有时候数据量太大,全部一次性展现给用户,用户体验感不好,所以将数据分页显示,用户交互友好。

    实际上每一次进行分页请求发送的时候,都是要发送两个数据给服务器的:

    • 页码 pageNum
    • 每页显示的记录条数 pageSize

    前端提交表单的话,数据格式:uri?pageNum=1&pageSize=10

十六、Mybatis分页

  • 分页的原因在于,有时候数据量太大,全部一次性展现给用户,用户体验感不好,所以将数据分页显示,用户交互友好。

    实际上每一次进行分页请求发送的时候,都是要发送两个数据给服务器的:

    • 页码 pageNum
    • 每页显示的记录条数 pageSize

    前端提交表单的话,数据格式:uri?pageNum=1&pageSize=10

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Mybatis/分页1.png)

16.1 limit分页

  • 在 mysql 中,分页 sql 该怎么写呢?

    • limit 关键字。

      • limit 语法格式:limit startIndex, pageSize

        • 第一个数字:startIndex(起始下标,下标从 0 开始)
        • 第二个数字:pageSize(每页显示的记录条数)

        注意:mysql 当中起始行的下标从 0 开始,第一条记录的下标是 0。

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Mybatis/分页2.png)

    • pageNum 页数据:limit (pageNum-1)*pageSize, pageSize

      • 所以,标准通用的 mysql 分页 SQL:

        1
        2
        3
        4
        5
        6
        select 
        *
        from
        tableName ......
        limit
        (pageNum - 1) * pageSize, pageSize
  • mybatis 三步走:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Car;
    import org.apache.ibatis.annotations.Param;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/1/13 14:20
    */
    public interface CarMapper {
    /**
    * 分页查询
    *
    * @param startIndex 起始下标
    * @param pageSize 每页显示的记录条数
    * @return
    */
    List<Car> selectByPage(@Param("startIndex") Integer startIndex, @Param("pageSize") Integer pageSize);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.CarMapper">
    <select id="selectByPage" resultType="Car">
    SELECT *
    FROM t_car
    LIMIT #{startIndex}, #{pageSize}
    </select>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.f.mybatis.test;

    import com.f.mybatis.mapper.CarMapper;
    import com.f.mybatis.pojo.Car;
    import com.f.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/1/13 16:24
    */
    public class CarMapperTest {
    @Test
    public void testSelectByPage() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    int pageNum = 3; // 显示第几页:页码
    int pageSize = 5; // 获取每页显示的记录条数
    int startIndex = (pageNum - 1) * pageSize; // 计算开始下标
    List<Car> cars = mapper.selectByPage(startIndex, pageSize);
    cars.forEach(car -> {
    System.out.println(car);
    });
    SqlSessionUtil.close(sqlSession);
    }
    }

    注意:前端传过来的参数是页码 pageNum 和**每页显示的记录条数 pageSize**。

    而在 sql 语句中 limit 后面写的是记录开始的下标 startIndex 和**每页显示的记录条数 pageSize**。

    • startIndexpageNumpageSize 的关系是:
      • startIndex = (pageNum - 1) * pageSize
  • 其实获取数据不难,难的是获取分页相关的数据。例如有没有上一页,有没有下一页,可以分多少页等等。

    可以借助 mybatis 的 PageHelper 插件。

16.2 PageHelper插件

  • 使用 PageHelper 插件进行分页,更加的便捷。

    • 第一步:引入 pagehelper 依赖:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      ...
      <dependencies>
      ...
      <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.3.1</version>
      </dependency>
      </dependencies>
      ...
    • 第二步:在 mybatis-config.xml 文件中配置插件:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <!--mybatis-config.xml文件-->
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
      ...
      <!--mybatis分页的拦截器-->
      <plugins>
      <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
      </plugins>
      ...
      </configuration>
    • 第三步:编写三步走代码:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      package com.f.mybatis.mapper;

      import com.f.mybatis.pojo.Car;
      import org.apache.ibatis.annotations.Param;

      import java.util.List;

      /**
      * @author fzy
      * @date 2024/1/13 14:20
      */
      public interface CarMapper {
      /**
      * 查询所有的Car信息,并使用分页查询插件PageHelper
      *
      * @return
      */
      List<Car> selectAllByPageHelper();
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.f.mybatis.mapper.CarMapper">
      <select id="selectAllByPageHelper" resultType="Car">
      SELECT *
      FROM t_car
      </select>
      </mapper>
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      @Test
      public void testSelectAllByPageHelper() {
      SqlSession sqlSession = SqlSessionUtil.openSession();
      CarMapper mapper = sqlSession.getMapper(CarMapper.class);

      // 注意:在执行DQL语句之前,开启分页功能
      int pageNum = 3;
      int pageSize = 5;
      PageHelper.startPage(pageNum, pageSize);

      List<Car> cars = mapper.selectAllByPageHelper();
      cars.forEach(car -> {
      System.out.println(car);
      });
      SqlSessionUtil.close(sqlSession);
      }

      关键点:

      • 在 DQL 查询语句执行之前使用 PageHelper 开启分页功能

16.3 PageInfo对象

  • 在 DQL 查询语句执行之后可以封装 PageInfo 对象(PageInfo 对象可以存储到 request 域当中,以便在前端使用)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @Test
    public void testSelectAllByPageHelperAndPageInfo() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(CarMapper.class);

    // 注意:在执行DQL语句之前,开启分页功能
    int pageNum = 3;
    int pageSize = 5;
    PageHelper.startPage(pageNum, pageSize);

    List<Car> cars = mapper.selectAllByPageHelper();

    // 注意:在DQL语句执行之后,封装分页信息对象PageInfo
    // PageInfo对象是PageHelper插件提供的,用来封装分页相关信息的对象
    PageInfo<Car> carPageInfo = new PageInfo<>(cars, 5);
    System.out.println(carPageInfo);
    // PageInfo{pageNum=3, pageSize=5, size=2, startRow=11, endRow=12, total=12, pages=3,
    // list=Page{count=true, pageNum=3, pageSize=5, startRow=10, endRow=15, total=12, pages=3, reasonable=false, pageSizeZero=false}
    // [Car{id=16, carNum='6567', brand='蔚来', guidePrice=36.0, produceTime='2020-11-01', carType='新能源'},
    // Car{id=17, carNum='1234', brand='宝马', guidePrice=44.0, produceTime='2020-11-01', carType='汽油'}],
    // prePage=2, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,
    // hasNextPage=false, navigatePages=5, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]}
    SqlSessionUtil.close(sqlSession);
    }
    • PageInfo 有一堆的方法来得到相关信息,例如 getPrePage()getNavigatePages() 等等。
---------------The End---------------