Java 常用的分页组件

Java 常用的分页组件

    概要

    在实际的 Java 项目开发中,分页查询是最常见的场景之一。现在普遍使用SpringBoot进行快速开发,而数据层主要整合SpringDataJPA和MyBatis两种框架,这两种框架都提供了相应的分页工具,使用方式也很简单。而使用 MyBatis-Plus 之后,分页支持变得非常轻松。

    本文将分享一套基于SpringBoot + MyBatis-Plus 分页能力 + 封装工具类(PageResult、Paginator、PageUtils) 的实战经验,供大家参考,帮助大家更优雅地实现分页逻辑。    

    一、依赖引入

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.5</version> <!-- 建议使用最新稳定版 -->
</dependency>

     二、分页结果封装

     分页结果是需要展示:分页信息(当前页码、每页记录数、总记录数、总页数)、分页列表

     参考代码如下:

@Data
@NoArgsConstructor
public class PageResult<T> {
    /**
     * 当前页的数据列表
     */
    private List<T> data;

    /**
     * 分页信息
     */
    private Paginator paginator;

    /**
     * 构造方法:通过数据列表和分页信息创建分页结果
     *
     * @param data      当前页的数据列表
     * @param paginator 分页信息
     */
    public PageResult(List<T> data, Paginator paginator) {
        this.data = data;
        this.paginator = paginator;
    }
}

     二、分页信息对象

    其中分页信息参考如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Paginator {
    // 当前页码
    private int pageNum;
    // 每页记录数
    private int pageSize;
    // 总记录数
    private long total;
    // 总页数
    private int totalPages;

    // 计算总页数
    public void calculateTotalPages() {
        if (this.pageSize > 0) {
            this.totalPages = (int) Math.ceil((double) this.total / this.pageSize);
        } else {
            this.totalPages = 0;
        }
    }

    // 重新设置分页信息
    public void setPaginator(int pageNum, int pageSize, long total) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.total = total;
        calculateTotalPages();
    }

    @Override
    public String toString() {
        return "Paginator{" +
                "pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                ", total=" + total +
                ", totalPages=" + totalPages +
                '}';
    }
}

    说明:总记录数在极端情况下可能会非常大(特别是对大数据量表做全量统计时),超过 2^31-1 的可能性更高,所以用 long 来避免溢出。

    三、分页工具类

    为了在项目中统一管理分页元信息(当前页码、每页记录数、总记录数、总页数等),我们可以封装一个 PageUtils 工具类,将 MyBatis-Plus 提供的 IPage<?> 对象快速转换成我们自定义的 Paginator

    参考代码如下:

package com.bqt.common.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bqt.common.page.PageResult;
import com.bqt.common.page.Paginator;

/**
 * 分页工具类*/
public class PageUtils {
    /**
     * 转换成自定义分页信息
     *
     * @param page 请求内容
     * @return 返回结果
     */
    public static Paginator transformToPaginator(IPage<?> page) {
        Paginator paginator = new Paginator();
        paginator.setPaginator(
                (int) page.getCurrent(),
                (int) page.getSize(),
                page.getTotal()
        );
        return paginator;
    }
}

    四、实践案例

    以项目中查询一个直播列表为例,参考代码如下:

    /**
     * 分页获取直播中的直播列表
     *
     * @param dto 请求内容
     * @return PlazaInfoDTO 返回参数 {@link PageResult<PlazaInfoDTO>}
     */
    @Override
    public PageResult<PlazaInfoDTO> listAllPlaza(PlazaPageQueryDTO dto) {
        LambdaQueryWrapper<BqtLiveEntity> queryWrapper = new LambdaQueryWrapper<BqtLiveEntity>()
                .select(BqtLiveEntity::getId, BqtLiveEntity::getOwnerId, BqtLiveEntity::getGroupId)
                .select(BqtLiveEntity::getStatus, BqtLiveEntity::getType)
                .eq(BqtLiveEntity::getStatus, LiveStatusEnum.LIVING.getCode())
                .orderByAsc(BqtLiveEntity::getId);

        IPage<BqtLiveEntity> pageData = this.bqtLiveMapper.selectPage(
                new Page<>(dto.getCurrentPage(), dto.getPageSize()),
                queryWrapper
        );

        Paginator paginator = PageUtils.transformToPaginator(pageData);
        List<PlazaInfoDTO> plazaInfoDTOS = LivePlazaListConverter.fromPlazaInfoDTOList(pageData.getRecords());

        return new PageResult<>(plazaInfoDTOS, paginator);
    }

    五、总结

    MyBatis-Plus 已经为我们做好了分页能力的基础工作,而通过这套封装的 PageResult + Paginator + PageUtils,可以让分页逻辑更清晰、更高效、更统一。

 
 
 
posted @ 2025-03-31 17:51  欢乐豆123  阅读(110)  评论(0)    收藏  举报