分页工具代码重构

news2025/1/14 15:55:29

文章目录

    • 1.common-mybatis-plus-starter
        • 1.目录
        • 2.PageInfo.java
        • 3.PageResult.java
        • 4.SunPageHelper.java

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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2276550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue学习二——创建登录页面

前言 以一个登录页面为例子&#xff0c;这篇文章简单介绍了vue&#xff0c;element-plus的一些组件使用&#xff0c;vue-router页面跳转&#xff0c;pinia及持久化存储&#xff0c;axios发送请求的使用。后面的页面都大差不差&#xff0c;也都这么实现&#xff0c;只是内容&am…

初始Django框架

初识Django Python知识点&#xff1a;函数、面向对象。前端开发&#xff1a;HTML、CSS、JavaScript、jQuery、BootStrap。MySQL数据库。Python的Web框架&#xff1a; Flask&#xff0c;自身短小精悍 第三方组件。Django&#xff0c;内部已集成了很多组件 第三方组件。【主要…

深度学习每周学习总结R4(LSTM-实现糖尿病探索与预测)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客R6中的内容&#xff0c;为了便于自己整理总结起名为R4&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结1. LSTM介绍LSTM的基本组成部分如何理解与应用LSTM 2. 数据预处理3. 数…

虚假星标:GitHub上的“刷星”乱象与应对之道

在开源软件的世界里&#xff0c;GitHub无疑是最重要的平台之一。它不仅是一个代码托管平台&#xff0c;也是一个社交网络&#xff0c;允许开发者通过“点赞”&#xff08;即加星&#xff09;来表达对某个项目的喜爱和支持&#xff0c;“星标”&#xff08;Star&#xff09;则成…

前端笔记----

在我的理解里边一切做页面的代码都是属于前端代码。 之前用过qt框架&#xff0c;也是用来写界面的&#xff0c;但是那是用来写客户端的&#xff0c;而html是用来写web浏览器的&#xff0c;相较之下htmlcssJavaScript写出来的界面是更加漂亮的。这里就记录我自个学习后的一些笔…

【面试题】技术场景 4、负责项目时遇到的棘手问题及解决方法

工作经验一年以上程序员必问问题 面试题概述 问题为在负责项目时遇到的棘手问题及解决方法&#xff0c;主要考察开发经验与技术水平&#xff0c;回答不佳会影响面试印象。提供四个回答方向&#xff0c;准备其中一个方向即可。 1、设计模式应用方向 以登录为例&#xff0c;未…

2025华数杯国际赛A题完整论文讲解(含每一问python代码+数据+可视化图)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2025“华数杯”国际大学生数学建模竞赛A题Can He Swim Faster的完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文…

关闭window10或11自动更新和自带杀毒

关闭window10或11自动更新和自带杀毒 1.关闭系统更新**修改组策略关闭自动更新****修改服务管理器关闭自动更新** 2.关闭系统杀毒 为什么需要关闭更新和杀毒 案例&#xff1a; #装完驱动隔一段时间就掉 #一些设置隔一段时间就重置了 #防止更新系统后有时卡 1.关闭系统更新 我…

解析OVN架构及其在OpenStack中的集成

引言 随着云计算技术的发展&#xff0c;虚拟化网络成为云平台不可或缺的一部分。为了更好地管理和控制虚拟网络&#xff0c;Open Virtual Network (OVN) 应运而生。作为Open vSwitch (OVS) 的扩展&#xff0c;OVN 提供了对虚拟网络抽象的支持&#xff0c;使得大规模部署和管理…

【ArcGIS技巧】如何给CAD里的面注记导入GIS属性表中

前面分享了GIS怎么给田块加密高程点&#xff0c;但是没有分享每块田的高程对应的是哪块田&#xff0c;今天结合土地整理软件GLAND做一期田块的属性怎么放入GIS属性表当中。 1、GLAND数据 杭州阵列软件&#xff08;GLand&#xff09;是比较专业的土地整理软件&#xff0c;下载之…

Excel中SUM求和为0?难道是Excel有Bug!

大家好&#xff0c;我是小鱼。 在日常工作中有时会遇到这样的情况&#xff0c;对Excel表格数据进行求和时&#xff0c;结果竟然是0&#xff0c;很多小伙伴甚至都怀疑是不是Excel有Bug&#xff01;其实&#xff0c;在WPS的Excel表格中数据求和&#xff0c;结果为0无法正确求和的…

Spring MVC简单数据绑定

【图书介绍】《SpringSpring MVCMyBatis从零开始学&#xff08;视频教学版&#xff09;&#xff08;第3版&#xff09;》_springspringmvcmybatis从零开始 代码、课件、教学视频与相关软件包下载-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)&#xff08;第3版&…

蓝桥杯备考:数据结构之栈 和 stack

目录 栈的概念以及栈的实现 STL 的stack 栈和stack的算法题 栈的模板题 栈的算法题之有效的括号 验证栈序列 后缀表达式 括号匹配 栈的概念以及栈的实现 栈是一种只允许在一端进行插入和删除的线性表 空栈&#xff1a;没有任何元素 入栈&#xff1a;插入元素消息 出…

使用Dify创建个问卷调查的工作流

为啥要使用Dify创建工作流呢&#xff1f;一个基于流程的智能体的实现&#xff0c;特别是基于业务的实现&#xff0c;使用Dify去实现时&#xff0c;通常都是一个对话工作流&#xff0c;当设计到相对复杂一些的流程时&#xff0c;如果将所有逻辑都放在对话工作流中去实现&#xf…

QT Quick QML 实例之椭圆投影,旋转

文章目录 一、前言二、演示三、部分代码与分析 QML 其它文章请点击这里: QT QUICK QML 学习笔记 国际站点 GitHub: https://github.com/chenchuhan 国内站点 Gitee : https://gitee.com/chuck_chee 一、前言 此 Demo 主要用于无人机吊舱视角的模拟&#xf…

高通,联发科(MTK)等手机平台调优汇总

一、常见手机型号介绍&#xff1a; ISP除了用在安防行业&#xff0c;还有手机市场&#xff0c;以及目前新型的A/VR眼睛&#xff0c;机器3D视觉机器人&#xff0c;医疗内窥镜这些行业。 下面是一些最近几年发布的,,,旗舰SOC型号&#xff1a; 1.联发科&#xff1a;天玑92…

AI的崛起:它将如何改变IT行业的职业景象?

随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;许多人开始担忧其对IT行业的影响&#xff0c;担心AI的出现可能会导致大量IT从业者失业。然而&#xff0c;事实并非如此简单&#xff0c;AI的崛起将为IT行业带来深刻的变革&#xff0c;既有挑战&#xff0c;也有机…

【25考研】西南交通大学软件工程复试攻略!

一、复试内容 复试对考生的既往学业情况、外语听说交流能力、专业素质和科研创新能力&#xff0c;以及综合素质和一贯表现等进行全面考查,主要考核内容包括思想政治素质和道德品质、外语听说能力、专业素质和能力&#xff0c;综合素质及能力。考核由上机考试和面试两部分组成&a…

玩转大语言模型——langchain调用ollama视觉多模态语言模型

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 langchain调用ollama视觉多模态语言模型 系列文章目录前言使用Ollama下载模型查找模型下载模型 测试模型ollama测试langchain测试加载图片加载模型…

Android Dex VMP 动态加载加密指令流

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 上一篇【详解如何自定义 Android Dex VMP 保护壳】实现了 VMP 保护壳。 为了进一步加强对 dex 指令的保护&#xff0c;实现指令流加密和动态加载&#xff0c;…