MyBatis作为Java持久层框架,本身未内置分页功能,需结合数据库特性或第三方插件实现。分页本质是“数据截取”,核心在于高效获取指定范围的数据并统计总量,主要分为物理分页与逻辑分页两种模式,需根据场景选择适配方案。
物理分页依托数据库原生分页语法实现,性能最优。例如MySQL通过LIMIT offset, pageSize实现,Oracle需嵌套子查询(如ROWNUM),PostgreSQL使用OFFSET与LIMIT组合。其优势在于直接减少数据库I/O,避免全量数据传输。以MySQL为例,分页SQL可写为:
sql
SELECT FROM user ORDER BY id LIMIT #{offset}, #{pageSize}
其中offset = (pageNum - 1) pageSize,需在Java代码中计算参数。但需注意深分页问题——当offset过大时,数据库仍需扫描前N条数据,可通过“游标分页”(记录上次最大ID)或“索引优化”提升效率。
逻辑分页通过内存截取实现,适用于小数据量场景。其流程为:先执行全量查询SELECT * FROM user,再通过Java集合的subList()方法截取分页数据。此方式代码简单但性能差,数据量大时易引发内存溢出,不推荐生产环境使用。
PageHelper插件是MyBatis生态中最主流的分页解决方案。通过拦截器机制,在SQL执行前自动注入分页语句并统计总量。使用步骤如下:
引入依赖(如pagehelper与jsqlparser);
配置拦截器(Spring Boot中可通过@Bean注入PageInterceptor);
在查询方法前调用PageHelper.startPage(pageNum, pageSize),后续执行的第一个SQL将被自动分页;
返回结果通过PageInfo封装,包含分页元数据(总记录数、总页数等)。
分页优化策略需结合业务场景:
索引优化:分页字段(如排序字段)需建立索引,避免全表扫描;
禁止返回大数据字段:分页查询应避免SELECT *,减少网络传输压力;
深分页优化:百万级数据可考虑“分段查询+ID映射表”或Elasticsearch等搜索引擎;
参数校验:前端传递的页码需验证合法性(如非负整数),防止SQL注入。
对比与选择:物理分页适用于大数据量、高并发场景;逻辑分页仅适合小数据量。PageHelper通过自动生成物理分页SQL,平衡了开发效率与性能,成为企业级应用首选。但需注意:多表关联查询时,分页逻辑可能因表关联方式失效,需手动编写分页SQL;动态SQL(如WHERE条件)需与分页参数兼容,避免语法错误。
综上,MyBatis分页需结合数据库特性、数据规模及业务需求综合设计,优先采用物理分页+PageHelper的组合方案,辅以索引优化与参数校验,实现高效稳定的分页查询。