Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理
分页。可以在 sql 内直接拼写带有物理分页的参数来完成物理分页功能,也可以使用分页插件
来完成物 理分页,比如: MySQL 数据的时候,在原有 SQL 后面拼写 limit 。
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦
截 待执行的 sql ,然后重写 sql ,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
MyBatis 进行分页的方式主要有两种:使用 RowBounds 和使用分页插件。以下是详细介绍:
使用 RowBounds
MyBatis 提供了一个简单的分页解决方案,即通过 `RowBounds` 对象来实现分页。`RowBounds` 包含两个参数:`offset`(偏移量)和 `limit`(每页显示的记录数)。在查询时,MyBatis 会根据这两个参数对查询结果进行分页处理。不过,这种方式的分页是在内存中完成的,可能会导致性能问题。
分页插件
分页插件是通过 MyBatis 提供的拦截器机制来实现分页功能的。以常见的 PageHelper 插件为例,其分页原理如下:
拦截器机制
分页插件实现了 MyBatis 的 `Interceptor` 接口,通过拦截器机制对 SQL 语句进行拦截和处理。在执行查询之前,分页插件会自动将下一次查询作为分页查询处理。
分页参数存储
调用分页插件的 `startPage` 方法时,会创建一个 `Page` 对象,将分页参数(如当前页码 `pageNum` 和每页显示条数 `pageSize`)设置到这个 `Page` 对象中。然后,这个 `Page` 对象会被存储到当前线程的 `ThreadLocal` 变量中,以确保分页参数的安全性和准确性。
SQL 语句拦截与修改
当 MyBatis 执行查询时,分页插件的拦截器会拦截到 SQL 查询语句。拦截器会获取到 `ThreadLocal` 中保存的分页参数,并根据这些参数和数据库类型(通过方言 `Dialect` 来适配),自动修改原始的 SQL 语句,添加分页相关的 SQL 片段(如 `LIMIT` 语句)来实现分页功能。
执行分页查询
修改后的分页 SQL 语句会被执行,返回分页结果。分页结果会被封装到 `Page` 对象中,包括查询到的数据列表、总记录数等信息。
查询总记录数(可选)
分页插件默认会在执行分页查询之前,先执行一个 `count` 查询来获取总记录数。这个 `count` 查询是通过修改原始 SQL 语句为 `count(*)` 查询来实现的。获取到的总记录数会被设置到 `Page` 对象中。
返回分页结果
执行完分页查询后,分页插件会将分页结果封装到 `Page` 对象中。开发者可以通过 `Page` 对象或将其转换为 `PageInfo` 对象来获取分页查询的结果,包括总记录数、总页数、当前页数据等。
分页插件的实现原理是基于 MyBatis 的插件机制,通过拦截器对 SQL 语句进行动态修改,添加分页相关的条件,从而实现分页功能。这种方式的分页是在数据库层面完成的,性能较好。