一、为什么要分页

数据特别多的时候,单次请求返回大量的数据接口会非常慢。
对于数据量特别大的查询,我们都会采用分页查询

二、怎么设计分页

  • 每页有多少个
  • 当前是在第几页
  • 数据的总数
  • 数据列表

基于这些属性设计分页的实体类

  1. @Data
  2. public class PageInfo<T> {
  3. /**
  4. * 每页有多少个
  5. */
  6. private int pageSize;
  7. /**
  8. * 当前是在第几页
  9. */
  10. private int currentPage;
  11. /**
  12. * 数据的总数
  13. */
  14. private int total;
  15. /**
  16. * 数据列表
  17. */
  18. private List<T> list;
  19. // 获取偏移量
  20. public int getOffset() {
  21. return (this.currentPage - 1) * this.pageSize;
  22. }
  23. }

三、实现分页功能

创建分页查询的方法

  1. /**
  2. * 分页查询
  3. *
  4. * @param user 查询条件
  5. * @param offset 起始位置
  6. * @param pageSize 每页容量
  7. * @return 用户列表
  8. */
  9. List<User> page(@Param("user") User user, @Param("offset") int offset, @Param("pageSize") int pageSize);
  10. /**
  11. * 统计总数
  12. *
  13. * @param user 查询条件
  14. * @return 总数
  15. */
  16. int count(@Param("user") User user);
  1. <select id="page" resultType="User">
  2. select *
  3. from t_user
  4. <where>
  5. <if test="user.nickname != null and user.nickname != ''">
  6. and nickname like concat('%',#{user.nickname},'%')
  7. </if>
  8. <if test="user.username != null and user.username != ''">
  9. and username = #{user.username}
  10. </if>
  11. </where>
  12. limit #{offset},#{pageSize};
  13. </select>
  14. <select id="count" resultType="int">
  15. select count(*)
  16. from t_user
  17. <where>
  18. <if test="user.nickname != null and user.nickname != ''">
  19. and nickname like concat('%',#{user.nickname},'%')
  20. </if>
  21. <if test="user.username != null and user.username != ''">
  22. and username = #{user.username}
  23. </if>
  24. </where>
  25. </select>

测试

    @Test
    public void page(){
        PageInfo<User> pageInfo = new PageInfo<User>();
        pageInfo.setCurrentPage(1);
        pageInfo.setPageSize(10);
        User user = new User();
        user.setNickname("尚云");
        // 加上筛选条件,根据nickname 或 username进行筛选
        List<User> list = userMapper.page(user,pageInfo.getOffset(),pageInfo.getPageSize());
        pageInfo.setList(list);
        pageInfo.setTotal(userMapper.count(user));
        System.out.println(pageInfo);
    }

四、分页插件

https://pagehelper.github.io/

1. 引入依赖

 <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>

2. 配置拦截器

在mybatis的配置文件中增加插件

<!--
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

3. 配置插件

https://pagehelper.github.io/docs/howtouse/#2-%E9%85%8D%E7%BD%AE%E6%8B%A6%E6%88%AA%E5%99%A8%E6%8F%92%E4%BB%B6

4. 使用插件

    @Test
    public void testList() throws IOException {
        SqlSession session = MybatisUtils.openSession();
        User condition = new User();
        // 插件里提供的分页工具,在要查询之前,执行一下PageHelper.startPage(当前页数,每页的容量), 当使用工具时候,会导致懒加载失败
        // 加了这个操作,插件就会在sql语句中拼接limit限制,并且还会统计总个数
        PageHelper.startPage(1,5);
        List<User> users = session.getMapper(IUserMapper.class).list(condition);
        // 拿到结果之后通过PageInfo.of() 的方法,获得pageInfo
        com.github.pagehelper.PageInfo<User> list = com.github.pagehelper.PageInfo.of(users);
        System.out.println(users);
    }

五、在springboot中分页

1. 引入依赖

别的版本可能导致无法分页

  <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.0</version>
</dependency>

2.配置controller

    @GetMapping("/list")
    public String pro(ModelMap modelMap,Integer pageNum,Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Technology> technologiesList = technologyService.list();
        PageInfo<Technology> pageInfo=PageInfo.of(technologiesList);
        modelMap.addAttribute("pageInfo",pageInfo);
        return "technology/technology-list";
    }

3.修改list页面

<tr th:each="technology:${pageInfo.list}" th:object="${technology}">

引入分页按钮

 <!--                分页按钮-->
<div class="layui-card-body ">
    <div class="page" id="page">

    </div>
</div>

image.png
修改body中layui操作

layui.use(['laydate','form','laypage'], function(){
        var laydate = layui.laydate;
        var form = layui.form;
        var basePath = [[${#httpServletRequest.getContextPath()}]];
        var laypage = layui.laypage;
        //执行一个laydate实例
        laydate.render({
            elem: '#start' //指定元素
        });

        //执行一个laydate实例
        laydate.render({
            elem: '#end' //指定元素
        });
        laypage.render({

            elem: 'page', //注意,这里的 test1 是 ID,不用加 # 号
            //数据总数,从服务端得到
            count: [[${pageInfo.total}]],
            limit: [[${pageInfo.pageSize}]],
            curr: [[${pageInfo.pageNum}]],
            jump(obj, first) {

                //首次不执行
                if (!first) {
                    // 做一个界面跳转
                    window.location.href = basePath + "/product/list?pageNum=" + obj.curr + "&pageSize=" + obj.limit;
                }
            }
        });
    });

修改index链接

<li>
            <a th:onclick="|xadmin.add_tab('工艺管理','@{/technology/list?pageNum=1&pageSize=5}')|">
                <i class="iconfont">&#xe6a7;</i>
                    <cite>工艺管理</cite></a>
</li>