你提供的 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 代码,我来一步步带你重构 😎