当前位置: 首页 > article >正文

一文读懂 PageQueryUtil:分页查询的优雅打开方式

适用人群Java 开发者想了解函数式编程在实际项目中的应用前置知识了解 Java 8 Lambda 表达式基础一、先来看一个实际场景场景同步 10000 条债券数据到接口平台传统做法Java// 一次性查询所有数据ListBondQuotaQueryBO allData bondQuotaQueryService.queryAll(queryBO);// 逐条处理for (BondQuotaQueryBO bo : allData) { syncSingleQuota(bo, tenantId);}问题❌ 10000 条数据一次性加载到内存可能 OOM内存溢出❌ 如果数据有 10 万条呢❌ 查询超时怎么办优雅做法Java// 分页查询逐页处理PageQueryUtil.queryAndProcess( pageInfo - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), rows - { for (BondQuotaQueryBO bo : rows) { syncSingleQuota(bo, tenantId); } }, 100 // 每页 100 条);好处✅ 每次只加载 100 条到内存✅ 自动处理所有分页✅ 代码简洁逻辑清晰二、PageQueryUtil 的核心设计1. 方法签名记住这个公式Javapublic static T long queryAndProcess( FunctionPageInfo, PageResultT queryFunction, // ← 怎么查 ConsumerListT pageHandler, // ← 怎么处理 int pageSize // ← 每页多少条)通俗理解参数 1你告诉它怎么查数据给个查询函数参数 2你告诉它查到数据后怎么处理给个处理函数参数 3每页查多少条返回值一共处理了多少条数据三、实战演练完整代码拆解步骤 1准备查询条件JavaBondQuotaQueryBO queryBO new BondQuotaQueryBO();queryBO.setLockStatus(2); // 已审批queryBO.setNotEndType(1); // 未终止步骤 2调用 queryAndProcessJavalong total PageQueryUtil.queryAndProcess( // 参数 1查询函数怎么查 pageInfo - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), // 参数 2处理函数怎么处理 rows - { for (BondQuotaQueryBO bo : rows) { syncSingleQuota(bo, tenantId); } }, // 参数 3每页条数 PAGE_SIZE // 100);步骤 3理解 Lambda 表达式参数 1 详解JavapageInfo - bondQuotaQueryService.queryBondQuotaQueryByPage(queryBO, pageInfo)翻译成人话给我一个分页信息pageInfo我返回一页数据给你等价于Javanew FunctionPageInfo, PageResultBondQuotaQueryBO() { Override public PageResultBondQuotaQueryBO apply(PageInfo pageInfo) { return bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo); }}关键点pageInfo 是 Lambda 的参数占位符queryBO 是从外部捕获的变量闭包这个 Lambda 现在不执行只是定义了一个规则参数 2 详解Javarows - { for (BondQuotaQueryBO bo : rows) { syncSingleQuota(bo, tenantId); }}翻译成人话给我一页数据rows我逐条处理它们等价于Javanew ConsumerListBondQuotaQueryBO() { Override public void accept(ListBondQuotaQueryBO rows) { for (BondQuotaQueryBO bo : rows) { syncSingleQuota(bo, tenantId); } }}四、PageQueryUtil 内部是如何工作的执行流程图PlainTextPageQueryUtil.queryAndProcess()│├─ 【第 1 步】创建第 1 页的分页参数│ PageInfo pageInfo new PageInfo(1, 100);│├─ 【第 2 步】调用你的查询函数│ PageResultT result queryFunction.apply(pageInfo);│ ↑│ └─ 实际执行bondQuotaQueryService.queryBondQuotaQueryByPage(queryBO, pageInfo)│├─ 【第 3 步】调用你的处理函数│ pageHandler.accept(result.getRows());│ ↑│ └─ 实际执行for (BondQuotaQueryBO bo : rows) { syncSingleQuota(bo, tenantId); }│├─ 【第 4 步】获取总条数计算总页数│ long total result.getTotal(); // 比如 1000│ int totalPages 1000 / 100 10;│├─ 【第 5 步】循环查询第 2~10 页│ for (int page 2; page 10; page) {│ PageInfo pageInfo new PageInfo(page, 100);│ PageResultT result queryFunction.apply(pageInfo); // 查询│ pageHandler.accept(result.getRows()); // 处理│ }│└─ 【第 6 步】返回总条数 return processedCount;时序图PlainText调用方 PageQueryUtil 你的查询函数 你的处理函数 │ │ │ │ │──queryAndProcess── │ │ │ │ │ │ │ │ │──apply(pageInfo)── │ │ │ │ │ │ │ │─PageResult 返回── │ │ │ │ │ │ │ │────────accept(rows) ────────────────────────── │ │ │ │ │ │ │ (循环第 2~N 页...) │ │ │ │ │ │─返回总条数───────── │ │ │ │ │ │ │五、为什么需要 pageInfo -常见疑惑pageInfo 不是在 queryAndProcess 里面定义了吗为什么 Lambda 还要写一次答案Lambda 是在定义函数不是在调用函数类比理解场景你点外卖传统方式Java// 你直接去餐厅吃ListFood allFood restaurant.getAllFood();eat(allFood);外卖方式PageQueryUtilJava// 你告诉外卖平台FoodDelivery.orderAndEat( // 参数 1怎么取餐 box - restaurant.getFoodByBox(box), // 参数 2怎么吃 foods - { for (Food food : foods) { eat(food); } }, // 参数 3每箱装多少 10);Lambda 的 box - 就像给我一个餐盒编号box我去取对应的菜外卖平台会准备第 1 个餐盒 → 调用你的取餐函数 → 送到你家 → 你开吃准备第 2 个餐盒 → 调用你的取餐函数 → 送到你家 → 你开吃...关键餐盒编号是外卖平台准备的你只需要定义收到编号后怎么做六、闭包Lambda 的超能力问题queryBO 没有作为参数传给 queryAndProcess为什么查询函数里能用答案Lambda 可以记住定义时的上下文JavaBondQuotaQueryBO queryBO new BondQuotaQueryBO(); // ← 外部变量queryBO.setLockStatus(2);PageQueryUtil.queryAndProcess( // Lambda捕获了外部的 queryBO pageInfo - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), // ↑ // └─ 外部变量被 Lambda 捕获 ...);通俗理解Lambda 就像一个 closures闭包把定义时能看到的变量都装进包里以后随时能用七、举一反三更多使用场景场景 1批量发送邮件JavaEmailQueryBO queryBO new EmailQueryBO();queryBO.setStatus(PENDING);PageQueryUtil.queryAndProcess( pageInfo - emailService.queryPendingEmails(queryBO, pageInfo), emails - { for (Email email : emails) { sendEmail(email); } }, 50);场景 2导出 ExcelJavaPageQueryUtil.queryAndProcess( pageInfo - orderService.queryOrders(queryBO, pageInfo), orders - { // 逐页写入 Excel excelWriter.write(orders); }, 1000);场景 3数据清洗JavaPageQueryUtil.queryAndProcess( pageInfo - dataService.queryDirtyData(pageInfo), dataList - { for (Data data : dataList) { cleanData(data); } }, 200);八、常见错误避坑❌ 错误 1直接调用方法没有 LambdaJava// 错误pageInfo 未定义PageQueryUtil.queryAndProcess( bondQuotaQueryService.queryBondQuotaQueryByPage (queryBO, pageInfo), ...);正确写法JavaPageQueryUtil.queryAndProcess( pageInfo - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), ...);❌ 错误 2忘记写 -Java// 错误这不是 LambdaPageQueryUtil.queryAndProcess( (PageInfo pageInfo) bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), ...);正确写法JavaPageQueryUtil.queryAndProcess( (PageInfo pageInfo) - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), ...);❌ 错误 3类型不匹配Java// 错误queryFunction 返回值类型不对PageQueryUtil.queryAndProcess( pageInfo - bondQuotaQueryService.queryCount (queryBO), // ← 返回 Integer不是 PageResult ...);正确写法JavaPageQueryUtil.queryAndProcess( pageInfo - bondQuotaQueryService. queryBondQuotaQueryByPage(queryBO, pageInfo), ...);九、核心要点总结1. 方法签名背下来JavaqueryAndProcess( FunctionPageInfo, PageResultT queryFunction, // 怎么查 ConsumerListT pageHandler, // 怎么处理 int pageSize // 每页多少条)2. Lambda 表达式Java// 查询函数接收 pageInfo返回 PageResultpageInfo - service.query(queryBO, pageInfo)// 处理函数接收 rows没有返回值rows - { for (T item : rows) { process(item); } }3. 闭包特性JavaSomeBO queryBO new SomeBO(); // 外部变量pageInfo - service.query(queryBO, pageInfo); // Lambda 捕获外部变量4. 执行流程PlainText1. 创建第 1 页 PageInfo2. 调用 queryFunction.apply(pageInfo) → 查询3. 调用 pageHandler.accept(rows) → 处理4. 循环第 2~N 页5. 返回总条数十、课后练习练习题 1补全代码Java// 需求分页查询用户每页 50 条打印每个用户的名字UserQueryBO queryBO new UserQueryBO();queryBO.setStatus(ACTIVE);PageQueryUtil.queryAndProcess( // 补全参数 1查询函数 ________________________________, // 补全参数 2处理函数 ________________________________, // 补全参数 3每页条数 ____);参考答案JavaPageQueryUtil.queryAndProcess( pageInfo - userService.queryUsers(queryBO, pageInfo), users - { for (User user : users) { System.out.println(user.getName()); } }, 50);练习题 2判断正误Java// 这段代码有什么问题PageQueryUtil.queryAndProcess( pageInfo - { userService.queryUsers(queryBO, pageInfo); }, users - System.out.println(users.size()), 100);答案查询函数缺少 return 语句应该改为JavapageInfo - { return userService.queryUsers(queryBO, pageInfo);}结语PageQueryUtil.queryAndProcess 是模板方法模式函数式编程的完美结合模板方法模式PageQueryUtil 定义流程你填充具体逻辑函数式编程用 Lambda 表达式传递行为代码简洁优雅掌握这个工具让你的分页查询代码✅ 内存友好✅ 逻辑清晰✅ 易于复用✅ 优雅简洁记住这个公式PlainTextqueryAndProcess( 怎么查Lambda, 怎么处理Lambda, 每页多少条)下次遇到分页查询试试这个优雅的打开方式吧

相关文章:

一文读懂 PageQueryUtil:分页查询的优雅打开方式

适用人群&#xff1a;Java 开发者&#xff0c;想了解函数式编程在实际项目中的应用 前置知识&#xff1a;了解 Java 8 Lambda 表达式基础一、先来看一个实际场景场景&#xff1a;同步 10000 条债券数据到接口平台传统做法&#xff1a;Java// 一次性查询所有数据List<BondQuo…...

GetQzonehistory完整教程:三步轻松备份QQ空间所有历史说说

GetQzonehistory完整教程&#xff1a;三步轻松备份QQ空间所有历史说说 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否担心QQ空间中的珍贵回忆随着时间流逝而消失&#xff1f;Get…...

daily_stock_analysis多语言支持开发实战

daily_stock_analysis多语言支持开发实战 1. 引言 想象一下这样的场景&#xff1a;一位香港投资者收到了一份全英文的股票分析报告&#xff0c;虽然内容专业但阅读起来颇为吃力&#xff1b;一位内地用户看到繁体中文的分析结果&#xff0c;需要额外时间理解&#xff1b;而一位…...

开源项目的依赖管理:平衡兼容性与扩展性的艺术

开源项目的依赖管理&#xff1a;平衡兼容性与扩展性的艺术 【免费下载链接】IPED IPED Digital Forensic Tool. It is an open source software that can be used to process and analyze digital evidence, often seized at crime scenes by law enforcement or in a corporat…...

OpenRGB终极指南:一站式跨平台RGB设备控制解决方案

OpenRGB终极指南&#xff1a;一站式跨平台RGB设备控制解决方案 【免费下载链接】OpenRGB Open source RGB lighting control that doesnt depend on manufacturer software. Supports Windows, Linux, MacOS. Mirror of https://gitlab.com/CalcProgrammer1/OpenRGB. Releases …...

ChatGPT合租架构设计与实现:高可用代理服务的技术解析

ChatGPT合租架构设计与实现&#xff1a;高可用代理服务的技术解析 作为一名开发者&#xff0c;我最近在项目中频繁使用ChatGPT API&#xff0c;虽然效果惊艳&#xff0c;但账单也着实让人心疼。更头疼的是&#xff0c;官方对单个账户的请求速率和月度配额都有严格限制&#xf…...

C语言完美演绎5-6

/* 范例&#xff1a;5-6 */#include <stdio.h>void main(void){int a;a2; /* 将整数2赋予给变量a&#xff0c;变量a的类型与整数2一样*/printf("a%d\n",a);a6.83; /* 将浮点数6.83重新赋予给变量a&#xff0c;浮点数6.83可以自动转型为int并赋予给变量a …...

PyTorch 2.8镜像入门必看:RTX 4090D显存24G下8bit量化加载Llama3-70B方法

PyTorch 2.8镜像入门必看&#xff1a;RTX 4090D显存24G下8bit量化加载Llama3-70B方法 1. 环境准备与快速验证 在开始之前&#xff0c;让我们先确认你的环境已经准备就绪。这个PyTorch 2.8镜像已经针对RTX 4090D显卡进行了深度优化&#xff0c;预装了所有必要的组件。 1.1 环…...

Antd Upload组件文件上传前校验与拦截实战:从阻止默认请求到实现自定义上传逻辑

Antd Upload组件文件上传前校验与拦截实战&#xff1a;从阻止默认请求到实现自定义上传逻辑 在当今前端开发中&#xff0c;文件上传功能几乎是每个Web应用都绕不开的核心需求。而Ant Design作为企业级React UI库&#xff0c;其Upload组件凭借丰富的功能和优雅的API设计&#xf…...

从Noise2Noise到Noise2Void:无监督图像去噪技术的演进与实践

1. 无监督图像去噪的困境与突破 想象你手上有张老照片&#xff0c;布满了岁月留下的噪点&#xff0c;但原始底片早已遗失。传统图像去噪方法就像个需要参考答案的学生——必须同时看到"噪点版"和"干净版"的成对图像才能学会去噪。这种监督学习范式在2018年…...

Qwen3-1.7B部署案例分享:中小企业无需专业AI团队,30分钟上线语音转录SaaS服务

Qwen3-1.7B部署案例分享&#xff1a;中小企业无需专业AI团队&#xff0c;30分钟上线语音转录SaaS服务 1. 引言&#xff1a;当语音转录不再是技术难题 想象一下这个场景&#xff1a;你是一家小型律所的负责人&#xff0c;每天需要处理大量的会议录音、客户访谈和庭审记录。过去…...

如何突破AI音频处理瓶颈?开源工具让音质提升30%的秘密

如何突破AI音频处理瓶颈&#xff1f;开源工具让音质提升30%的秘密 【免费下载链接】so-vits-svc SoftVC VITS Singing Voice Conversion 项目地址: https://gitcode.com/gh_mirrors/so/so-vits-svc 在直播、音乐制作和语音交互等场景中&#xff0c;音频质量直接影响用户…...

OpenClaw+GLM-4.7-Flash:个人健康数据追踪

OpenClawGLM-4.7-Flash&#xff1a;个人健康数据追踪 1. 为什么选择这个技术组合 去年体检报告上的几项异常指标让我开始关注健康数据追踪。试过各种健康类App后&#xff0c;发现它们要么数据封闭&#xff0c;要么分析流于表面。直到偶然将OpenClaw与GLM-4.7-Flash结合使用&a…...

AI 辅助开发实战:高效完成自动化专业毕业设计的工程化路径

最近在帮学弟学妹们看自动化专业的毕业设计&#xff0c;发现大家普遍被几个问题困扰&#xff1a;时间紧、任务重&#xff0c;软硬件一结合就出各种玄学问题&#xff0c;算法调参调到怀疑人生。传统的开发方式&#xff0c;从查资料、写代码到调试&#xff0c;周期拉得很长&#…...

curl详细使用方法

curl -X POST -d "whatflag" http://171.80.2.169:19534&#x1f3af; 这道题的核心原理&#xff1a;HTTP POST 传参 后端条件判断1. 题目到底在干什么&#xff1f;题目页面写着&#xff1a;“什么也没有。”这是后端代码故意写的&#xff1a;正常访问&#xff08;G…...

Porymap:让宝可梦地图编辑效率提升300%的跨平台工具

Porymap&#xff1a;让宝可梦地图编辑效率提升300%的跨平台工具 【免费下载链接】porymap Map editor for pokeemerald, pokefirered, and pokeruby 项目地址: https://gitcode.com/gh_mirrors/po/porymap 功能概述&#xff1a;重新定义宝可梦地图创作体验 作为专为第三…...

BitNet 1-bit大语言模型CPU端高效推理实战指南

BitNet 1-bit大语言模型CPU端高效推理实战指南 【免费下载链接】BitNet 1-bit LLM 高效推理框架&#xff0c;支持 CPU 端快速运行。 项目地址: https://gitcode.com/GitHub_Trending/bitne/BitNet BitNet 1-bit大语言模型推理框架是微软官方推出的革命性低比特推理解决方…...

告别职场年龄焦虑:大龄职场人如何借网络安全赛道实现逆袭

告别职场年龄焦虑&#xff1a;大龄职场人如何借网络安全赛道实现逆袭 职场人如何借网络安全赛道实现逆袭告别职场年龄焦虑 //前言// 今天&#xff0c;我们来聊聊每个职场人都可能面对的痛点 —— 年龄焦虑。最近后台收到不少读者留言&#xff0c;有人感慨 35 岁后求职屡屡碰…...

Laravel迁移配置实战指南:从数据库结构到迁移文件的自定义策略

Laravel迁移配置实战指南&#xff1a;从数据库结构到迁移文件的自定义策略 【免费下载链接】migrations-generator Laravel Migrations Generator: Automatically generate your migrations from an existing database schema. 项目地址: https://gitcode.com/gh_mirrors/mi/…...

ComfyUI工作流概念启发:可视化编排春联生成提示词

ComfyUI工作流概念启发&#xff1a;可视化编排春联生成提示词 春节快到了&#xff0c;想用AI写一副别出心裁的春联&#xff0c;却发现生成的要么太普通&#xff0c;要么对不上联&#xff0c;要么文采不够&#xff1f;别急&#xff0c;今天我们不聊复杂的模型部署&#xff0c;而…...

PyTorch 2.8镜像惊艳效果展示:FlashAttention-2加速下文生视频生成实拍

PyTorch 2.8镜像惊艳效果展示&#xff1a;FlashAttention-2加速下文生视频生成实拍 1. 开篇&#xff1a;专业级视频生成环境 当我们需要处理视频生成这类计算密集型任务时&#xff0c;一个优化到位的深度学习环境能带来质的飞跃。今天要展示的PyTorch 2.8镜像&#xff0c;就是…...

如何用Chinese-STD-GB-T-7714-related-csl解决学术论文参考文献格式难题

如何用Chinese-STD-GB-T-7714-related-csl解决学术论文参考文献格式难题 【免费下载链接】Chinese-STD-GB-T-7714-related-csl GB/T 7714相关的csl以及Zotero使用技巧及教程。 项目地址: https://gitcode.com/gh_mirrors/chi/Chinese-STD-GB-T-7714-related-csl Chinese…...

从0到1掌握KubeRay:架构解析与实战

从0到1掌握KubeRay&#xff1a;架构解析与实战 【免费下载链接】kuberay A toolkit to run Ray applications on Kubernetes 项目地址: https://gitcode.com/GitHub_Trending/ku/kuberay KubeRay作为在Kubernetes上运行Ray应用的核心工具包&#xff0c;解决了分布式计算…...

Type-C有线网卡转接方案:RTL8153B与AX88179芯片如何实现手机千兆稳定联网与百瓦快充

1. 为什么需要Type-C有线网卡转接方案 现在很多手机、平板和Switch游戏机都取消了传统的RJ45网口&#xff0c;只保留Type-C接口。虽然WiFi很方便&#xff0c;但在需要稳定高速网络的时候&#xff0c;有线连接依然是更好的选择。比如我在玩在线游戏时&#xff0c;经常遇到WiFi延…...

Springboot旅游民宿订购平台vue3

目录技术栈选择系统模块划分接口设计规范前端工程结构开发里程碑部署方案性能优化措施项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈选择 后端采用Spring Boot框架&#xff0c;提供RESTful API接口&#xff0c;处理业务…...

Trae 远程开发使用密钥时SSH权限被拒绝

如果同环境下 VSCode、PyCharm 都能正常 SSH 连接&#xff0c;唯独 Trae 报公钥认证失败。可以参考以下的解决方案&#xff1a; &#xff08;SSH 权限被拒绝&#xff1a;Public key authentication failed, please check your SSH keys&#xff09;步骤 1&#xff1a;把.ppk 密…...

Teriteri后端开发指南:如何用SpringBoot构建完整的视频网站平台

Teriteri后端开发指南&#xff1a;如何用SpringBoot构建完整的视频网站平台 【免费下载链接】teriteri-backend 一个基于 springboot mybatis-plus 搭建的视频网站平台后端 项目地址: https://gitcode.com/gh_mirrors/te/teriteri-backend Teriteri是一个基于SpringBoo…...

基于MyBatis-Plus的MySQL Geometry数据WKT转换实战

1. 为什么需要处理MySQL Geometry数据&#xff1f; 在地理信息系统&#xff08;GIS&#xff09;和位置服务应用中&#xff0c;我们经常需要处理各种空间数据。MySQL作为广泛使用的关系型数据库&#xff0c;从5.7版本开始就内置了对空间数据的支持&#xff0c;提供了Geometry数据…...

颠覆式效率工具:MarkdownEditing 让 Markdown 写作效率倍增的秘密武器

颠覆式效率工具&#xff1a;MarkdownEditing 让 Markdown 写作效率倍增的秘密武器 【免费下载链接】MarkdownEditing Powerful Markdown package for Sublime Text with better syntax understanding and good color schemes. 项目地址: https://gitcode.com/gh_mirrors/ma/M…...

市场时序解析引擎如何重塑智能投资决策:实现超额收益的金融大模型创新方法

市场时序解析引擎如何重塑智能投资决策&#xff1a;实现超额收益的金融大模型创新方法 【免费下载链接】Kronos Kronos: A Foundation Model for the Language of Financial Markets 项目地址: https://gitcode.com/GitHub_Trending/kronos14/Kronos 智能投资决策正面临…...