技术Java工具类分页工具类PaginationHelper的设计与实现
夏佳怡背景
在日常开发中,我们经常需要处理分页查询的场景。比如从数据库分页查询数据,或者调用第三方API进行分页查询。这些分页查询的逻辑往往比较类似:
- 设定页码(pageIndex)和每页大小(pageSize)
- 循环查询直到没有更多数据
- 处理每一页的数据
为了避免重复编写这些模板代码,我设计了一个通用的分页工具类PaginationHelper。
核心实现
PaginationHelper的核心是一个静态方法paginateAndProcess
,它接收三个参数:
- fetchPageFunction: 分页查询函数,传入页码和每页大小,返回分页结果
- pageSize: 每页大小
- processDataFunction: 处理每页数据的函数
代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @Slf4j public class PaginationHelper {
public static <T> void paginateAndProcess( BiFunction<Integer, Integer, PageResp<T>> fetchPageFunction, int pageSize, Consumer<List<T>> processDataFunction ) { int pageIndex = 1; boolean hasMore = true; int totalProcessed = 0; while (hasMore) { PageResp<T> pageResp = fetchPageFunction.apply(pageIndex, pageSize); if (pageResp == null) { log.error("Failed to retrieve page {}, stopping pagination", pageIndex); return; } List<T> dataList = pageResp.getDataList(); if (dataList == null || dataList.isEmpty()) { log.info("Page {} data is empty, ending pagination", pageIndex); hasMore = false; break; } processDataFunction.accept(dataList); totalProcessed += dataList.size(); long total = pageResp.getTotal(); long totalPages = (total + pageSize - 1) / pageSize; if (pageIndex >= totalPages) { hasMore = false; } else { pageIndex++; } } log.info("Pagination completed. Total entries processed: {}", totalProcessed); } }
|
1 2 3 4 5 6 7 8
| @Data @NoArgsConstructor @AllArgsConstructor public class PageResp<T> implements Serializable { public static final long serialVersionUID = 1L; private List<T> dataList; private Long total; }
|
使用示例
以下是一个简单的使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| BiFunction<Integer, Integer, PageResp<User>> fetchUsers = (pageIndex, pageSize) -> { return userService.queryByPage(pageIndex, pageSize); };
Consumer<List<User>> processUsers = users -> { users.forEach(user -> { System.out.println(user.getName()); }); };
PaginationHelper.paginateAndProcess(fetchUsers, 20, processUsers);
|
特点与优势
通用性强: 通过泛型和函数式接口,可以处理任何类型的分页数据
异常处理: 内置了基本的异常处理逻辑,避免因异常导致程序中断
日志完善: 记录了关键节点的日志,方便排查问题
使用简单: 只需要提供查询函数和处理函数即可使用
解耦合: 将分页逻辑与业务逻辑解耦,提高代码复用性
总结
PaginationHelper是一个简单但实用的分页工具类,它可以帮助我们:
- 减少重复代码
- 提高代码可读性
- 统一异常处理
- 方便日志记录
在需要分页查询的场景下,都可以考虑使用这个工具类来简化开发。