• SpringBoot实现分页的四种方式


    一 自己封装Page对象实现

    博客链接

    二 使用sql实现分页

    2.1 场景分析
    • 前段传递给给后台什么参数?
      • 当前页码currentPage
      • 每页显示条数pageSize
    • 后台给前端返回什么数据?
      • 当前页数据List
      • 总记录数totalCount
    2.2 前段代码
    <template>
       <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[5, 10, 15, 20]"
          :page-size="5"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalCount">
        el-pagination>
    template>
    <script>
      export default {
        methods: {
          handleSizeChange(val) {
            //console.log(`每页 ${val} 条`);
            // 重新设置每页显示的条数
            this.pageSize = val;
            this.selectAll();
          },
          handleCurrentChange(val) {
            // console.log(`当前页: ${val}`);
            // 重新设置当前页码
            this.currentPage = val;
            this.selectAll();
          }
        },
        data() {
          return {
            // 当前页码
            currentPage: 1,
            // 总记录数
            totalCount: 100,
            // 每页显示条数
            pageSize: 5,
            //接收当前页数据集合
            tableData:[]
          };
        },
        methods:{
    		// 分页查询
    		selectAll(){
    			axios({
    				method:"get",
    				url:'后端接口地址',
    			}).then(response => {
    				//设置表格数据
    				this.tableData = response.data.rows;
    				//设置总记录数
    				this.totalCount = response.data.totalCount
    			})
    		}
    	}
      }
    script>
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    2.3 后端代码
    PageBean
    // 分页查询JavaBean
    public class PageBean<T> {
        // 总记录数
        private int totalCount;
        // 当前页数据
        private List<T> rows;
        get,set...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    mapper
    // 分页查询
    @Select("select * from 表名 limit #{begin} , #{size}")
    List<T> selectByPage(@Param("begin") int begin,@Param("size") int size);
    
    // 查询总记录数
    @Select("select count(*) from 表名")
    int selectTotalCount();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    service
    // 分页查询 currentPage:当前页码  pageSize:每页展示条数
    PageBean<T> selectByPage(int currentPage,int pageSize);
    
    • 1
    • 2
    impl
    @Override
    public PageBean<T> selectByPage(int currentPage,int pageSize){
        // 计算开始索引
        int begin = (currentPage - 1) * pageSize;
        // 计算查询条目数
        int size = pageSize;
        // 查询当前页数据
        List<T> rows = mapper.selectByPage(begin,size);
        // 查询总记录数
        int totalCount = mapper.selectTotalCount();
        // 封装PageBean对象
        PageBean<T> pageBean = new PageBean<>();
        pageBean.setRows(rows);
        pageBean.setTotalCount(totalCount);
    
        return pageBean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    controller
    @GetMapping("/selectAll")
    public AjaxResult getApproveDataRes(ImportDataGetDto importDataGetDto){
    	//接收前段传递请求参数实体importDataGetDto
    	int currentPage = importDataGetDto.getCurrentPage();
    	int pageSize = importDataGetDto.getPageSize();
    	PageBean<T> pageBean = mapper.selectByPage(currentPage,pageSize)
        return pageBean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    三 使用PageHelper插件

    PageHelper官网

    3.1 导入依赖
    <dependencies>
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>1.2.3version>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    3.2 application.yml
    pagehelper:
      # 设置方言,此处指定 MySQL 数据库
      helper-dialect: mysql
      # 是否启动合理化,默认是 false。
      # 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages(最大页数)会查询最后一页。
      # 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据
      reasonable: true
      # 是否支持接口参数来传递分页参数,默认false
      support-methods-arguments: true
      # 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值
      params: count=countSql
      # 默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)
      page-size-zero: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    3.3 使用
    /**
    * service实现类
    * @param pageNumber    页码
    * @param pageSize      每页显示数目
    */
    public PageInfo<T> list(Integer pageNumber, Integer pageSize) { 
        // 设置分页
        PageHelper.startPage(pageNumber, pageSize);
     
        // 查询用户角色列表(需要分页的查询)
        List<T> list = userRoleService.queryList();
        PageInfo<T> pageInfo = new PageInfo<>(list);
     
        return pageInfo;
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意:PageHelper.startPage(页码, 每页显示数目); 这一句代码,必须放在需要分页的查询语句之前,否则会分页不生效

    3.4 分页失效情况

    分页设置与需要分页的查询之间存在其他查询,如下代码是一个错误示范,虽然在方法的开头设置了分页,但因为在【查询用户角色列表】之前,多查了一步【查询用户信息】,此时实际上分页针对的是【查询用户信息】进行分页,而并非对【查询用户角色列表】进行分页。

    public PageInfo<UserRole> list(Integer pageNumber, Integer pageSize, String userId) {
        // 设置分页
        PageHelper.startPage(pageNumber, pageSize);
     
        // 查询用户信息
        User user = userService.findById(userId);
     
        // 查询用户角色列表(需要分页的查询)
        List<UserRole> list = userRoleService.queryList();
        PageInfo<UserRole> pageInfo = new PageInfo<UserRole>(list);
     
        return pageInfo;
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    注意:startPage会寻找最近的一个查询方法执行分页

    在需要分页的查询后才设置分页,如下代码是一个错误示范,在【查询用户角色列表】后才进行分页设置,因为已进行的所有数据的查询,所以此时再设置分页已无任何意义,自然会分页失效

    public PageInfo<UserRole> list(Integer pageNumber, Integer pageSize) {
        // 查询用户角色列表(需要分页的查询)
        List<UserRole> list = userRoleService.queryList();
     
        // 设置分页
        PageHelper.startPage(pageNumber, pageSize);
        PageInfo<UserRole> pageInfo = new PageInfo<UserRole>(list);
     
        return pageInfo;
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    3.5 返回参数说明
    //当前页
    private int pageNum;
    //每页的数量
    private int pageSize;
    //当前页的数量
    private int size;
    //当前页面第一个元素在数据库中的行号
    private int startRow;
    //当前页面最后一个元素在数据库中的行号
    private int endRow;
    //总记录数
    private long total;
    //总页数
    private int pages;
    //结果集重要,通过getList获取结果集
    private List<T> list;
    
    //前一页
    private int prePage;
    //下一页
    private int nextPage;
    
    //是否为第一页
    private boolean isFirstPage = false;
    //是否为最后一页
    private boolean isLastPage = false;
    //是否有前一页
    private boolean hasPreviousPage = false;
    //是否有下一页
    private boolean hasNextPage = false;
    //导航页码数
    private int navigatePages;
    //所有导航页号
    private int[] navigatepageNums;
    //导航条上的第一页
    private int navigateFirstPage;
    //导航条上的最后一页
    private int navigateLastPage;
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    3.6 自定义返回参数
    //使用默认分页时
    PageHelper.startPage(page, size);
    List<DataBean> beans = mapper.selectByQuery(express);
    return new PageInfo<>(beans);
    
    • 1
    • 2
    • 3
    • 4

    根据上述代码可以发现,想要进行自定义分页的话,只需要重新定义一个PageInfo就可以了。保留当前页、每页数量、当前页数量、总记录数、总页数字段,其他参数全部干掉,拷贝下PageInfo,在实体目录下新建个PageBean,把PageInfo源码丢进去,删掉多余的参数就OK了

    public class PageBean<T> {
        private static final long serialVersionUID = 1L;
        //当前页
        private int pageNum;
        //每页的数量
        private int pageSize;
        //当前页的数量
        private int size;
        //总记录数
        private long total;
        //总页数
        private int pages;
        //结果集
        private List<T> list;
        get,set...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    然后分页代码把PageInfo改成自己的PageBean

    PageHelper.startPage(page, size);
    List<DataBean> beans = mapper.selectByQuery(express);
    return new PageBean<>(beans);
    
    • 1
    • 2
    • 3

    四 使用PagedListHolder类

    PagedListHolderSpring Framework中的一个分页辅助类,用于对列表进行分页显示和管理。它可以将一个列表对象进行分页处理,并提供了一些方法,用于管理分页的相关信息。使用PagedListHolder可以方便地对列表进行分页处理,包括获取当前页的数据、切换到下一页或上一页、设置每页显示的记录数等操作。它还提供了一些其他的方法,如获取总页数、获取当前页码等。

    代码演示
    前端(ElmentUI分页组件)
    <template>
       <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[5, 10, 15, 20]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalCount">
        el-pagination>
    template>
    <script>
      export default {
        methods: {
          handleSizeChange(val) {
            //console.log(`每页 ${val} 条`);
            // 重新设置每页显示的条数
            this.pageSize = val;
            this.selectAll();
          },
          handleCurrentChange(val) {
            // console.log(`当前页: ${val}`);
            // 重新设置当前页码
            this.currentPage = val;
            this.selectAll();
          }
        },
        data() {
          return {
            // 当前页码
            currentPage: 1,
            // 总记录数
            totalCount: 0,
            // 每页显示条数
            pageSize: 5,
            //接收当前页数据集合
            tableData:[]
          };
        },
        methods:{
        	 /*
        分页查询
        */
        handleSizeChange(val) {
            console.log(`每页 ${val}`);
            // 重新设置每页显示的条数
            this.pageSize = val;
            this.selectAll();
          	},
    	    handleCurrentChange(val) {
    	       console.log(`当前页: ${val}`);
    	      // 重新设置当前页码
    	      this.currentPage = val;
    	      this.selectAll();
    	    },
    		// 分页查询
    		selectAll(){
    			axios({
    				method:"get",
    				url:'后端接口地址',
    			}).then(response => {
    				//设置表格数据
    				this.tableData = response.data.rows;
    				//设置总记录数
    				this.totalCount = response.data.total
    			})
    		}
    	}
      }
    script>
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    后端

    dto实体

    @Data
    public class ApproveGetDto {
        ...
        // 当前页码
        private Integer currentPage;
        // 每页展示条数
        private Integer pageSize;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    vo实体

    @Data
    public class ApproveGetRes<T> {
    	...
        //分页查询:总记录数
        private Long total;
        //分页查询:当前页数据
        private T rows;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    controller

     @GetMapping("/getApproveDataRes")
     public AjaxResult getApproveDataRes(ApproveGetDto approveGetDto ){
     	 // 通过前端传递参数调用service获取数据
         List<ApproveGetRes> approveGetRes= lsjsService.getApproveDataRes(approveGetDto);
         // 设置要进行分页处理的数据源
         PagedListHolder<ApproveGetRes> plh = new PagedListHolder<>(approveGetRes);
         // 设置每页显示的记录数
         plh.setPageSize(approveGetDto.getPageSize());
         // 设置当前显示的页码,0代表第一页
         plh.setPage(approveGetDto.getCurrentPage()-1);
         // 创建vo对象
         ApproveGetRes dataRes = new ApproveGetRes();
         // 设置vo对象的总条数
         dataRes.setTotal(Long.valueOf(approveDataRes.size()));
         // plh.getPageList():获取当前页的数据列表
         dataRes.setRows(plh.getPageList());
         return AjaxResult.success("返回成功", dataRes);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    方法解释

    // 1. 设置要进行分页处理的源列表
    List<ApproveGetRes> approveGetRes= lsjsService.getApproveDataRes(approveGetDto);
    PagedListHolder<ApproveGetRes> pagedListHolder = new PagedListHolder<>(approveGetRes);
    // 2. 设置每页显示的记录数
    pagedListHolder.setPageSize(2);
    // 3. 设置当前显示的页码
    pagedListHolder.setPage(0);
    // 4. 获取当前页的数据列表
    List<String> currentPageData = pagedListHolder.getPageList();
    // 5. 切换到下一页
    pagedListHolder.nextPage();
    // 6. 切换到上一页
    pagedListHolder.previousPage();
    // 7. 获取总页数
    int totalPages = pagedListHolder.getPageCount();
    // 8. 获取当前页码
    int currentPage = pagedListHolder.getPage();
    // 9. 判断当前页是否为第一页
    boolean isFirstPage = pagedListHolder.isFirstPage();
    // 10. 判断当前页是否为最后一页
    boolean isLastPage = pagedListHolder.isLastPage();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    Docker的数据管理
    人才测评系统在企业招聘中的应用
    设计模式 - 责任链模式
    kafka-consumer-groups 命令行工具使用手册
    Seurat 中的数据可视化方法
    淘宝/天猫按关键字搜索淘宝商品 API 返回值说明
    python3- 模块
    编程-设计模式 11:享元模式
    把握市场潮流,溯源一流品质:在抖in新风潮 国货品牌驶过万重山
    iOS UWB——NI框架部分类
  • 原文地址:https://blog.csdn.net/weixin_46370595/article/details/132610516