分页工具代码重构

发布于:2025-02-10 ⋅ 阅读:(49) ⋅ 点赞:(0)

1.common-mybatis-plus-starter

1.目录

CleanShot 2024-10-26 at 20.01.51@2x

2.PageInfo.java
package com.sunxiansheng.mybatis.plus.page;

import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.io.Serializable;

/**
 * Description: 分页请求的基础参数
 *
 * @Author sun
 * @Create 2024-10-23 22:27:32
 * @Version 1.1
 */
@EqualsAndHashCode
@ToString
public class PageInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 页码,默认为1
     */
    private Long pageNo = 1L;

    /**
     * 每页显示的记录数,默认为20
     */
    private Long pageSize = 20L;

    public Long getPageNo() {
        return (pageNo == null || pageNo < 1) ? 1 : pageNo;
    }

    public Long getPageSize() {
        return (pageSize == null || pageSize < 1) ? 20 : pageSize;
    }

    public PageInfo setPageNo(Long pageNo) {
        this.pageNo = pageNo;
        return this;
    }

    public PageInfo setPageSize(Long pageSize) {
        this.pageSize = pageSize;
        return this;
    }
}
3.PageResult.java
package com.sunxiansheng.mybatis.plus.page;

import lombok.*;

import java.io.Serializable;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
 * Description: 分页返回的实体
 *
 * @Author sun
 * @Create 2024-10-23 22:27:33
 * @Version 1.1
 */
@EqualsAndHashCode
@ToString
@NoArgsConstructor
@Getter
public class PageResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    // 当前页码
    private Long pageNo;

    // 每页显示的记录数
    private Long pageSize;

    // 总记录条数
    private Long total;

    // 总页数
    private Long totalPages;

    // 当前页的记录列表
    private List<T> result;

    // 表示当前页是从分页查询结果的第几条记录开始,下标从1开始
    private Long start;

    // 表示当前页是从分页查询结果的第几条记录结束,下标从1开始
    private Long end;

    // 是否有下一页
    private  boolean hasNextPage;

    // 是否有上一页
    private  boolean hasPreviousPage;

    // 私有构造函数,使用Builder创建实例
    private PageResult(Builder<T> builder) {
        this.pageNo = builder.pageNo;
        this.pageSize = builder.pageSize;
        this.total = builder.total;
        this.result = builder.result;
        // 计算总页数
        calculateTotalPages();
        // 计算起始和结束位置
        calculateStartAndEnd();
        // 判断是否有上一页和下一页
        this.hasPreviousPage = this.pageNo > 1;
        this.hasNextPage = this.pageNo < this.totalPages;
    }

    // Builder 模式实现
    public static class Builder<T> {
        private Long pageNo;
        private Long pageSize;
        private Long total;
        private List<T> result;

        public Builder<T> pageNo(Long pageNo) {
            this.pageNo = requireNonNull(pageNo, "Page number cannot be null");
            return this;
        }

        public Builder<T> pageSize(Long pageSize) {
            this.pageSize = requireNonNull(pageSize, "Page size cannot be null");
            return this;
        }

        public Builder<T> total(Long total) {
            this.total = requireNonNull(total, "Total count cannot be null");
            return this;
        }

        public Builder<T> result(List<T> result) {
            this.result = requireNonNull(result, "Result list cannot be null");
            return this;
        }

        public PageResult<T> build() {
            // 校验参数
            if (pageNo < 1) {
                throw new IllegalArgumentException("Page number must be greater than zero.");
            }
            if (pageSize < 1) {
                throw new IllegalArgumentException("Page size must be greater than zero.");
            }
            return new PageResult<>(this);
        }
    }

    // 计算总页数
    private void calculateTotalPages() {
        if (this.pageSize > 0) {
            this.totalPages = (this.total / this.pageSize) + (this.total % this.pageSize == 0 ? 0 : 1);
        } else {
            // 如果 pageSize 小于 0,总页数为 0
            this.totalPages = 0L;
        }
    }

    // 计算起始和结束位置
    private void calculateStartAndEnd() {
        if (this.pageSize > 0) {
            this.start = (this.pageNo - 1) * this.pageSize + 1;
            this.end = Math.min(this.pageNo * this.pageSize, this.total);
        } else {
            // 如果 pageSize 小于 0,起始位置为 1,结束位置为总记录数
            this.start = 1L;
            this.end = this.total;
        }
    }
}
4.SunPageHelper.java
package com.sunxiansheng.mybatis.plus.page;

import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
 * Description: 分页逻辑封装
 *
 * @Author sun
 * @Create 2024-10-23 22:27:33
 * @Version 1.0
 */
public class SunPageHelper {

    /**
     * 执行分页操作
     *
     * @param pageNo          页码
     * @param pageSize        每页记录数
     * @param totalSupplier   获取总记录条数的逻辑
     * @param recordsSupplier 获取记录列表的逻辑
     * @param <T>             记录的类型
     * @return 分页结果
     */
    public static <T> PageResult<T> paginate(Long pageNo, Long pageSize,
                                             Supplier<Long> totalSupplier,
                                             BiFunction<Long, Long, List<T>> recordsSupplier) {
        // 计算总记录数
        Long total;
        try {
            total = totalSupplier.get();
        } catch (Exception e) {
            throw new RuntimeException("Failed to get total count", e);
        }

        // 如果总记录数为0,返回空的 PageResult
        if (total == 0) {
            return new PageResult.Builder<T>()
                    .pageNo(pageNo)
                    .pageSize(pageSize)
                    .total(total)
                    .result(Collections.emptyList()) // 空列表
                    .build();
        }

        // 计算 offset,表示从第几条记录开始查询
        Long offset = calculateOffset(pageNo, pageSize);

        // 获取当前页的记录列表
        List<T> records;
        try {
            records = recordsSupplier.apply(offset, pageSize);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get records", e);
        }

        // 使用 Builder 模式创建 PageResult 对象并返回
        return new PageResult.Builder<T>()
                .pageNo(pageNo)
                .pageSize(pageSize)
                .total(total)
                .result(records)
                .build();
    }

    /**
     * 计算分页的 offset
     *
     * @param pageNo   页码
     * @param pageSize 每页记录数
     * @return offset
     */
    public static Long calculateOffset(Long pageNo, Long pageSize) {
        // offset 计算公式:(当前页码 - 1) * 每页记录数
        return (pageNo - 1) * pageSize;
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到