函数式接口实现分页查询

你提供的 PageResult 类是一个非常完整、功能齐全的分页结果封装类,它包含了:

  • 当前页数据(list
  • 总记录数(totalCount
  • 总页数(totalPage
  • 当前页码(pageNo
  • 每页数量(pageSize
  • 偏移量(offset

✅ 目标

我们要基于这个 PageResult<T> 类,写一个通用的分页工具方法,它可以:

  • 接收查询条件对象
  • 自动处理分页参数(如默认值)
  • 调用 Mapper 查询总数和当前页数据
  • 构造并返回 PageResult<T>

✅ 一、定义基础接口:PageQuery

为了统一处理分页参数,我们先定义一个接口:

public interface PageQuery {Integer getPageNo();void setPageNo(Integer pageNo);Integer getPageSize();void setPageSize(Integer pageSize);
}

你的查询参数类(比如 UserQuery)可以实现这个接口。


✅ 二、编写通用分页工具类:PageUtils

import java.util.function.Function;public class PageUtils {/*** 通用分页工具方法** @param query 查询条件对象,必须实现 PageQuery 接口* @param countFunc 查询总记录数的方法* @param listFunc 查询当前页数据的方法* @param <T> 实体类型* @param <Q> 查询条件类型* @return 分页结果 PageResult<T>*/public static <T, Q extends PageQuery> PageResult<T> buildPageResult(Q query,Function<Q, Integer> countFunc,Function<Q, List<T>> listFunc) {// 设置默认分页参数if (query.getPageNo() == null || query.getPageNo() < 1) {query.setPageNo(1);}if (query.getPageSize() == null || query.getPageSize() < 1) {query.setPageSize(PageResult.DEFAULT_PAGE_SIZE);}if(ObjectUtil.isEmpty(query)){throw new BussinessException("查询参数不能为空");}if (countFunc == null || listFunc == null) {throw new IllegalArgumentException("countFunc and listFunc cannot be null");
}// 查询总记录数Integer totalCount = countFunc.apply(query);// 查询当前页数据List<T> dataList = listFunc.apply(query);// 构造 PageResult 对象PageResult<T> pageResult = new PageResult<>();pageResult.init(query.getPageNo(), query.getPageSize(), totalCount, dataList);return pageResult;}
}

✅ 三、使用示例

1. 查询条件类:UserQuery.java

public class UserQuery implements PageQuery {private Integer pageNo;private Integer pageSize;private String username;// getter/setter
}

2. Mapper 接口

public interface UserMapper {Integer count(UserQuery query);List<User> list(UserQuery query);
}

3. Service 层调用示例

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public PageResult<User> getUsersByPage(UserQuery query) {return PageUtils.buildPageResult(query,userMapper::count,   // 查询总数userMapper::list     // 查询当前页数据);}
}

✅ 四、Controller 示例

@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/page")public PageResult<User> getUsers(@ModelAttribute UserQuery query) {return userService.getUsersByPage(query);}
}

✅ 五、优势总结

特性描述
✅ 通用性强支持任意实体类和查询条件
✅ 简洁易用Service 层只需一行代码即可完成分页
✅ 可维护性高分离了分页逻辑与业务逻辑
✅ 易于扩展可以增加排序、过滤等增强功能

✅ 六、可选优化建议

功能建议
排序字段PageQuery 中添加 orderBy, orderType 字段
多条件查询在 XML 中使用 <if> 标签动态构建 WHERE 条件
分页缓存对高频访问的数据进行 Redis 缓存
分页插件替代方案使用 PageHelper 替代手动计算 offset/limit

如果你愿意,我可以帮你把你的现有查询结构改造成这套标准模式,让所有模块都能复用这个通用的分页工具。只需要贴出你的 Mapper 和 Service 代码,我来一步步带你重构 😎

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

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

相关文章

Global Security Markets 第 10 章衍生品知识点总结​

一、衍生品的定义与本质 衍生品&#xff0c;作为一种金融工具&#xff0c;其价值并非独立存在&#xff0c;而是紧密依赖于其他资产&#xff0c;如常见的股票、债券、商品&#xff0c;或者市场变量&#xff0c;像利率、汇率、股票指数等。这意味着衍生品的价格波动&#xff0c;…

DJango知识-模型类

一.项目创建 在想要将项目创键的目录下,输入cmd (进入命令提示符)在cmd中输入:Django-admin startproject 项目名称 (创建项目)cd 项目名称 (进入项目)Django-admin startapp 程序名称 (创建程序)python manage.py runserver 8080 (运行程序)将弹出的网址复制到浏览器中…

八股学习-JS的闭包

一.闭包的定义 闭包是指函数和其周围的词法环境的引用的组合。 简单来说&#xff0c;就是函数可以记住并访问其在定义时的作用域内的变量&#xff0c;即使该函数在其它作用域调用。 也就是说&#xff0c;闭包让你可以在一个内层函数中访问到其外层函数的作用域。 function …

qt使用笔记二:main.cpp详解

Qt中main.cpp文件详解 main.cpp是Qt应用程序的入口文件&#xff0c;包含程序的启动逻辑。下面我将详细解析其结构和功能。 基本结构 一个典型的Qt main.cpp 文件结构如下&#xff1a; #include <QApplication> // 或者 QGuiApplication/QCoreApplication #include &…

如何构建船舵舵角和船的航向之间的动力学方程?它是一个一阶惯性环节吗?

提问 船舵和船的航向之间的动力学方程是什么&#xff1f;是一个一阶惯性环节吗&#xff1f; 回答 船舵和船的航向&#xff08;航向角&#xff09;之间的动力学关系并不是一个简单的一阶惯性环节&#xff0c;虽然在某些简化控制模型中可以近似为一阶系统。实际上&#xff0c;…

抖去推--短视频矩阵系统源码开发

一、开发短视频矩阵系统的源码需要以下步骤&#xff1a; 确定系统需求&#xff1a; 根据客户的具体业务目标&#xff0c;明确系统需实现的核心功能模块&#xff0c;例如用户注册登录、视频内容上传与管理、多维度视频浏览与推荐、用户互动&#xff08;评论、点赞、分享&#xf…

Windows 下搭建 Zephyr 开发环境

1. 系统要求 操作系统&#xff1a;Windows 10/11&#xff08;64位&#xff09;磁盘空间&#xff1a;至少 8GB 可用空间&#xff08;Zephyr 及其工具链较大&#xff09;权限&#xff1a;管理员权限&#xff08;部分工具需要&#xff09; 2. 安装必要工具 winget安装依赖工具&am…

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…

安全月报 | 傲盾DDoS攻击防御2025年5月简报

引言 在2025年5月&#xff0c;全球数字化进程高歌猛进&#xff0c;各行各业深度融入数字浪潮&#xff0c;人工智能、物联网、大数据等前沿技术蓬勃发展&#xff0c;进一步夯实了数字经济的基石。然而&#xff0c;在这看似繁荣的数字生态背后&#xff0c;网络安全威胁正以惊人的…

【Spring】Spring哪些源码解决了哪些问题P1

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录 Spring是怎么处理请求的&#xff1f;Spring请求方…

坚持每日Codeforces三题挑战:Day 4 - 题目详解(2025-06-07,难度:1000, 1100, 1400)

前言&#xff1a; 此文章主要是记录每天的codeforces刷题&#xff0c;还有就是给其他打算法竞赛的人一点点点点小小的帮助&#xff08;毕竟现在实力比较菜&#xff0c;题目比较简单&#xff0c;但我还是会认真写题解&#xff09;。 之前忙学校事情&#xff0c;懈怠了一段时间…

6.7本日总结

一、英语 复习默写list10list19&#xff0c;07年第3篇阅读 二、数学 学习线代第一讲&#xff0c;写15讲课后题 三、408 学习计组第二章&#xff0c;写计组习题 四、总结 本周结束线代第一讲和计组第二章&#xff0c;之后学习计网4.4&#xff0c;学完计网4.4之后开操作系…

PGSR : 基于平面的高斯溅射高保真表面重建【全流程分析与测试!】【2025最新版!!】

【PGSR】: 基于平面的高斯溅射高保真表面重建 前言 三维表面重建是计算机视觉和计算机图形学领域的核心问题之一。随着Neural Radiance Fields (NeRF)和3D Gaussian Splatting (3DGS)技术的发展&#xff0c;从多视角RGB图像重建高质量三维表面成为了研究热点。今天我们要深入…

从认识AI开始-----AutoEncoder:生成模型的起点

前言 从15年开始&#xff0c;在深度学习的重要模型中&#xff0c;AutoEncoder&#xff08;自编码器&#xff09;可以说是打开生成模型世界的起点。它不仅是压缩与重建的工具&#xff0c;更是VAE、GAN、DIffusion等复杂生成模型的思想起源。其实AutoEncoder并不复杂&#xff0c;…

解决MySQL8.4报错ERROR 1524 (HY000): Plugin ‘mysql_native_password‘ is not loaded

最近使用了MySQL8.4 , 服务启动成功,但是就是无法登陆,并且报错: ERROR 1524 (HY000): Plugin mysql_native_password is not loaded 使用如下的命令也报错 mysql -u root -p -P 3306 问题分析: 在MySQL 8.0版本中,默认的认证插件从mysql_native_password变更为cachi…

TDengine 开发指南——无模式写入

简介 在物联网应用中&#xff0c;为了实现自动化管理、业务分析和设备监控等多种功能&#xff0c;通常需要采集大量的数据项。然而&#xff0c;由于应用逻辑的版本升级和设备自身的硬件调整等原因&#xff0c;数据采集项可能会频繁发生变化。为了应对这种挑战&#xff0c;TDen…

嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)

一、C有几种传值方式之间的区别 一、值传递&#xff08;Pass by Value&#xff09; 机制&#xff1a;创建参数的副本&#xff0c;函数内操作不影响原始数据语法&#xff1a;void func(int x)特点&#xff1a; 数据安全&#xff1a;原始数据不受影响性能开销&#xff1a;需要复…

Spark 之 AQE

个人其他链接 AQE 执行顺序https://blog.csdn.net/zhixingheyi_tian/article/details/125112793 AQE 产生 AQE 的 循环触发点 src/main/scala/org/apache/spark/sql/execution/adaptive/AdaptiveSparkPlanExec.scala override def doExecute(): RDD[InternalRow] = {withFin…

FSMC扩展外部SRAM

提示&#xff1a;文章 文章目录 前言一、背景二、2.12.2 三、3.1 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 2025年6月7日 19:34:48 今天看了FSMC扩展外部SRAM的文章&#xff0c;大概理解到stm32除了内部存储器&#xff0c;还可以扩展外部存储器。其中s…

【CSS-6】深入理解CSS复合选择器:提升样式表的精确性与效率

CSS选择器是前端开发的基石&#xff0c;而复合选择器则是其中最强大且实用的工具之一。本文将全面解析CSS复合选择器的类型、用法、优先级规则以及最佳实践&#xff0c;帮助你编写更高效、更精确的样式表。 1. 什么是复合选择器&#xff1f; 复合选择器是通过组合多个简单选择…