SpringBoot 项目返回结果如何使用 PageInfo 类进行手动分页


大型项目中获取数据的体量一般很大,在前段界面进行展示时为了保障展示效果,会要求接口快速返回,这时候后端一般会选择分页获取数据,只传递要查询的页码数据就可以。这种情况就避免了大部分的问题,达到快速返回的效果。

现阶段常用的分页有两种:

  • MyBatis 分页插件:PageHelper ,这个插件很常用,支持多数据库分页,无需修改SQL语句即可实现分页功能。
    • 注意:这个插件的功能相当于在你代码中的第一个 SQL 语句的后面加上 LIMIT [offset], [limit] 子句,例如 LIMIT 20, 10 ,表示从21条记录开始,获取10条记录。
    • 这个插件 只会在你的第一条语句后面添加子句 ,如果代码后面还存在其他的 SQL 则会不生效。
    • 如果你使用这个插件获取 UserId 列表,并用该列表进行后续操作,要注意返回的顺序问题 。
    • 详细了解请查看文章:SpringBoot 项目如何使用 MyBatis 的分页插件 PageHelper 做分页处理
  • 手动分页:PageInfo 类。这个类也是 MyBatis 分页插件中的类,只不过是手动赋值。
    • 手动分页适合数据量小的情况,因为需要预先加载所有数据,例如预先加载所有 UserId ,对 UserId 进行划分数量,根据请求的分页参数查询处在不同数量位置的 UserId

本文只介绍分页类 PageInfo ,包括创建方式,代码示例和验证结果展示等。


一、分页信息封装类 PageInfo 是什么?

我们在使用 MyBatis 分页时,不论是使用自动分页还是手动分页都会使用 PageInfo 对象作为承接介质。

PageInfo 是一个分页信息封装类,通常用于Web应用中的分页数据展示。它可以将分页查询结果和分页参数封装在一个对象中,便于传输和使用。我们使用时会遇到以下属性:

1、存储和管理分页相关的参数,自动分页时会自动设置,而手动分页时需要手动设置。

当前页码(pageNum)、每页记录数(pageSize)、总记录数(total)、总页数(pages

2、分页导航信息参数

是否有上一页(hasPreviousPage)、是否有下一页(hasNextPage)、是否为第一页(isFirstPage)、是否为最后一页(isLastPage)、导航页码数组(navigatepageNums

3、PageInfo 作为后端返回给前端的标准分页数据格式,便于前端渲染分页组件。前端在使用时无需手动计算分页参数,如总页数、是否有下一页等,提高可读性和可维护性。

二、使用 pagehelper-spring-boot-starter 依赖引入

上篇文章 SpringBoot 项目如何使用 MyBatis 的分页插件 PageHelper 做分页处理 详细讲解了关于分页插件的依赖引用,这次只介绍一个大家最常使用的依赖。

SpringBoot 起步依赖封装了关于分页插件的依赖,需要在配置文件 application.propertiesapplication.yml 中进行配置。

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

配置文件内容:

pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true

三、创建示例展示使用分页插件

1、创建数据库表格示例

本文创建一个 tb_user 表,含有 idusernamepassword 字段。本文只做一个简单示例,不涉及复杂业务。

数据库表
使用 pagehelper-spring-boot-starter 依赖时进行的分页条件配置。

pagehelper:
  helper-dialect: mysql
  reasonable: true   // 规整页码范围
  support-methods-arguments: true   // 规整方法参数获取

下面代码中存在部分代码是项目中必须代码,如统一封装返回,MyBatis 项目搭建等就不在本文展示,有兴趣可查看以下文章。

关于统一 API 响应结果封装,代码示例在 SpringBoot 项目统一 API 响应结果封装

关于 MyBatis 的项目搭建在 SpringBoot 项目整合 MyBatis 框架

2、PageInfoController

package com.wen.controller;

import com.wen.data.Result;
import com.wen.data.ResultGenerator;
import com.wen.service.PageInfoService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/pageInfoTest")
public class PageInfoController {

    @Autowired
    private PageInfoService pageInfoService;

    @GetMapping("/select")
    public Result<?> selectUserByPage(@Param("pageSize") Integer pageSize, @Param("pageNumber") Integer pageNumber) {
        return ResultGenerator.genSuccessResult(pageInfoService.selectUserByPage(pageSize, pageNumber));
    }
}

3、PageInfoService

package com.wen.service;

import com.github.pagehelper.PageInfo;
import com.wen.dto.TbUser;

public interface PageInfoService {

    PageInfo<TbUser> selectUserByPage(Integer pageSize, Integer pageNumber);

}

4、PageInfoServiceImpl

package com.wen.service.impl;

import com.github.pagehelper.PageInfo;
import com.wen.dto.TbUser;
import com.wen.mapper.TbUserMapper;
import com.wen.service.PageInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PageInfoServiceImpl implements PageInfoService {

    @Autowired
    private TbUserMapper tbUserMapper;

    @Override
    public PageInfo<TbUser> selectUserByPage(Integer pageSize, Integer pageNumber) {
        // 1、先获取业务中使用所用ID等参数,用于确定返回顺序
        List<Integer> tbUserId = tbUserMapper.selectUserId();
        // 2、计算查询到的用户的总记录数
        int totalCount = tbUserId.size();
        // 3、手动分页,获取其中选取页的用户数据
        int start = (pageNumber - 1) * pageSize;
        int end = Math.min(start + pageSize, totalCount);
        // 4、分页过后需要查询获得数据的id
        List<Integer> pageId = tbUserId.subList(start, end);
        List<TbUser> tbUsers = tbUserMapper.selectUserByIdList(pageId);
        // 5、构建分页结果
        PageInfo<TbUser> pageInfo = new PageInfo<>(tbUsers);
        // 6、参数填写,用户传递给前端
        pageInfo.setTotal(totalCount);
        pageInfo.setPageNum(pageNumber);
        pageInfo.setPageSize(pageSize);
        return pageInfo;
    }
}

5、TbUserMapper

package com.wen.mapper;

import com.wen.dto.TbUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface TbUserMapper {

    List<Integer> selectUserId();

    List<TbUser> selectUserByIdList(@Param("idList") List<Integer> idList);

}

6、TbUserMapper.xml

<?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.wen.mapper.TbUserMapper">
   
    <select id="selectUserId" resultType="java.lang.Integer">
        SELECT id FROM tb_user
    </select>

    <select id="selectUserByIdList" resultType="com.wen.dto.TbUser">
        SELECT username, password FROM tb_user Where
        <if test="idList.size() > 0">
            id in
            <foreach collection="idList" open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </select>
</mapper> 

三、手动分页插件的结果展示

手动分页和使用自动分页插件展示的结果一样。

http://localhost:8080/pageInfoTest/select?pageSize=2&pageNumber=1
返回结果
由下面的 JSON 结果可以看到数据的总数,页数,每页数据数量等,还有导航页面数据。

{
    "code": 1,
    "message": "SUCCESS",
    "data": {
        "total": 6,
        "list": [
            {
                "id": 0,
                "username": "laowang",
                "password": "112233"
            },
            {
                "id": 0,
                "username": "zhangsan",
                "password": "221133"
            }
        ],
        "pageNum": 1,
        "pageSize": 2,
        "size": 2,
        "startRow": 0,
        "endRow": 1,
        "pages": 1,
        "prePage": 0,
        "nextPage": 0,
        "isFirstPage": true,
        "isLastPage": true,
        "hasPreviousPage": false,
        "hasNextPage": false,
        "navigatePages": 8,
        "navigatepageNums": [
            1
        ],
        "navigateFirstPage": 1,
        "navigateLastPage": 1
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值