MybatisPlus IPage分页查询工具类

#MybatisPlus IPage 分页查询

项目组的common中 要求用 MybatisPlus 做分页查询 ,由于MybatisPlus 查询出来的都是entity的集合,前端要求统一返回Ipage (Result<IPage<***>>) ,历史查询用的是Pagehelper分页 修改太多,所以创建了该工具类,便于改造旧方法,以及新方法的快速对接分页查询。

工具类

java 复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sjqd.bgsc.common.model.param.CommonQueryParam;

import java.util.ArrayList;
import java.util.List;

/**
 * MyBatis Plus 通用分页工具类(返回IPage<R>)
 * 优化点:页码超出总页数时,自动查询最后一页
 */
public class MyBatisPageUtils {
    /**
     * 通用分页查询方法(适配IPage<Entity>入参、List<Vo>返回,优化页码越界问题)
     * @param param 查询参数(含分页参数)
     * @param queryFunc 业务查询逻辑(入参IPage<E>,返回List<R>)
     * @param <P> 查询参数类型(继承CommonQueryParam)
     * @param <E> 分页对象的实体类型(如ReportWorkEntity)
     * @param <R> 返回列表的VO类型(如ReportWorkVo)
     * @return 分页结果(IPage<R>,兼容不分页/页码越界场景)
     */
    public static <P extends CommonQueryParam, E, R> IPage<R> pageMybatisQuery(
            P param,
            QueryFunction<P, E, R> queryFunc
    ) {
        // 1. 获取原始分页参数
        int current = param.getCurrent();
        int size = param.getSize();

        // 场景1:current和size都为0(都没传),取消分页查全部
        if (current <= 0 && size <= 0) {
            List<R> allRecords = queryFunc.apply(param, null);
            IPage<R> allPage = new Page<>(0, 0);
            allPage.setRecords(allRecords);
            allPage.setTotal(allRecords.size());
            return allPage;
        }

        // 2. 处理分页参数默认值
        int finalCurrent = current <= 0 ? 1 : current; // 传size没传current,默认第1页
        int finalSize = size <= 0 ? 10 : size;        // 传current没传size,默认每页10条

        // 3. 先查询总条数(仅查count,不查数据,避免无效数据查询)
        IPage<E> countPage = new Page<>(1, 0); // size=0时,MyBatis Plus仅查总条数
        queryFunc.apply(param, countPage);    // 执行查询,countPage的total会被填充
        long total = countPage.getTotal();

        // 4. 处理总条数为0的情况(直接返回空分页)
        if (total <= 0) {
            IPage<R> emptyPage = new Page<>(finalCurrent, finalSize);
            emptyPage.setTotal(0);
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }

        // 5. 计算总页数,修正越界页码(核心优化)
        long totalPage = (total + finalSize - 1) / finalSize; // 向上取整计算总页数
        if (finalCurrent > totalPage) {
            finalCurrent = (int) totalPage; // 页码超出,自动改为最后一页
        }

        // 6. 构建修正后的Entity分页对象,查询数据
        IPage<E> entityPage = new Page<>(finalCurrent, finalSize);
        List<R> voList = queryFunc.apply(param, entityPage);

        // 7. 封装为VO类型的分页对象返回
        IPage<R> resultPage = new Page<>();
        resultPage.setCurrent(entityPage.getCurrent());
        resultPage.setSize(entityPage.getSize());
        resultPage.setTotal(entityPage.getTotal());
        resultPage.setRecords(voList);

        return resultPage;
    }

    /**
     * 分页查询函数式接口(兼容Entity/Vo分离场景)
     * @param <P> 查询参数类型(继承CommonQueryParam)
     * @param <E> 分页对象的实体类型(如ReportWorkEntity)
     * @param <R> 返回列表的VO类型(如ReportWorkVo)
     */
    @FunctionalInterface
    public interface QueryFunction<P extends CommonQueryParam, E, R> {
        /**
         * 执行业务查询逻辑
         * @param param 查询参数
         * @param page 分页对象(泛型为Entity,null表示不分页;size=0时仅查总条数)
         * @return 查询结果列表(泛型为VO)
         */
        List<R> apply(P param, IPage<E> page);
    }
}

controller 调用

java 复制代码
 @PostMapping(value = "/list")
    public Result<IPage<RVo>> selectList(@RequestBody QueryParam params) {


        IPage<RVo> objectIPage = MyBatisPageUtils.<QueryParam, REntity, RVo>pageMybatisQuery(
                params, (param, page) -> Service.selectList(param, page)
        );
        return success(objectIPage);
    }

参数说明:

MyBatisPageUtils.<QueryParam, REntity, RVo>pageMybatisQuery

QueryParam:是工具类中通用的查询参数 继承CommonQueryParam 主要包含 分页参数(current,size)。

REntity :是MybatisPlus 查询的Entity

RVo:香前端返回的 集合的对象

查询方法 只需要查询出 list entity 转为 list<vo> 返回即可,不用考虑分页参数是否传递

service 方法实现

java 复制代码
 public List<RVo> selectList(QueryParam commonQueryParam, IPage<REntity> page) {

        QueryWrapper<REntity> queryWrapper = new QueryWrapper<>();
        
        List<REntity> list = this.list(page, queryWrapper);
        List<RVo> voList = new ArrayList<>();
        for (REntity rEntity : list) {
            RVo o = new RVo();
            BeanUtil.copyProperties(rEntity, o);
          
            
            voList.add(o);
        }
        return voList;
    }
相关推荐
小大宇9 分钟前
Python 集成 Conda
开发语言·python·conda
还是奇怪25 分钟前
Simon Willison 用 DSPy 优化 Datasette Agent 提示词:提示工程正在变成可测试的软件工程
java·开发语言·软件工程
zfoo-framework40 分钟前
1.ansible安装 2.虚拟机克隆
java
码上解惑1 小时前
从 Dify 工作流说起:常用节点怎么选、怎样组合?
java·人工智能·ai·agent·dify·智能体·spring ai
小大宇1 小时前
python flask框架 SSE流式返回、跨域、报错
开发语言·python·flask
Legendary_0082 小时前
LDR6500 设计指南:Type-C 音频快充二合一配件 PD 取电与插拔时序控制方案
c语言·开发语言·音视频
青山木2 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
柒星栈2 小时前
PHP 源码怎么加密防破解?三套方案实战指南
开发语言·php·android studio
勉灬之2 小时前
Next.js + Prisma 跨平台部署踩坑记
开发语言·javascript·ecmascript
程序员-珍2 小时前
报错下载android sdk失败
android·java