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

函数式接口实现分页查询

你提供的 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.xdnf.cn/news/12676.html

相关文章:

  • AI开发 | 生成式AI在企业软件中的演进形态:从嵌入式到智能体
  • nodejs:用 nodemailer 发送一封带有附件的邮件
  • 【JavaSE】集合学习笔记
  • C++ 对 C 的兼容性
  • 基于Scala实现Flink的三种基本时间窗口操作
  • 跨平台资源下载工具:res-downloader 的使用体验
  • Vue3中computed和watch的区别
  • OpenLayers 导航之运动轨迹
  • 深入剖析 RocketMQ 中的 DefaultMQPushConsumerImpl:消息推送消费的核心实现
  • Docker基础(二)
  • TTL简述
  • Unity基础-欧拉角和四元数
  • 【Elasticsearch】映射:Join 类型、Flattened 类型、多表关联设计
  • 基于springboot的藏文古籍系统
  • Nature子刊:16S宏基因组+代谢组学联动,借助MicrobiomeGS2建模揭示IBD代谢治疗新靶点
  • Java高级 | 【实验六】Springboot文件上传和下载
  • Python 中的MVC与MVP 框架与示例
  • LVGL对显示接口的要求
  • 闲庭信步使用SV搭建图像测试平台:第一课——图片的读写
  • 【商城saas和商城源码的区别】
  • 【Zephyr 系列 13】BLE Mesh 入门实战:构建基础节点通信与中继组播系统
  • 类型别名与类型自动推导
  • Redis数据持久化之RDB快照
  • 【走好求职第一步】求职OMG——见面课测验4
  • SAP学习笔记 - 开发27 - 前端Fiori开发 Routing and Navigation(路由和导航)
  • 算术图片验证码(四则运算)+selenium
  • 【大模型】大模型RAG(Retrieval-Augmented Generation)面试题合集
  • 欢乐熊大话蓝牙知识16:蓝牙是怎么找设备的?扫描与广播的“对话内幕”
  • Shell编程精髓:表达式与数组实战指南
  • DbServer链接KingBase8(人大)数据库