Mybatis是如何进行分页的

MyBatis 的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异:


1. 原生 SQL 分页(物理分页)​

原理:直接在 SQL 中编写数据库特定的分页语法(如 MySQL 的 LIMIT、Oracle 的 ROWNUM)。
示例

 

xml

<select id="selectUsers" resultType="User">
  SELECT * FROM users
  LIMIT #{offset}, #{pageSize}
</select>

优点

  • 性能最优,直接通过数据库物理分页,仅查询所需数据。
  • 无额外依赖,适用于简单场景。
    缺点
  • SQL 与数据库类型绑定,切换数据库需修改 SQL。
  • 需要手动计算分页参数(offset、pageSize)。

2. RowBounds 分页(逻辑分页)​

原理:通过 MyBatis 的 RowBounds 对象实现内存分页(逻辑分页)。查询时会获取全部数据,但在内存中截取指定范围。
示例

 

java

List<User> users = sqlSession.selectList("selectUsers", null, new RowBounds(offset, pageSize));

优点

  • 代码简单,无需修改 SQL。
  • 兼容所有数据库。
    缺点
  • 性能差:数据量大时会导致内存溢出或查询缓慢(需全量加载数据)。
  • 仅适用于小数据集。

3. PageHelper 插件(推荐)​

原理:通过拦截器动态修改 SQL,自动添加分页语句(物理分页)。支持多种数据库,并封装分页结果(总条数、页码等)。
使用步骤

  1. 引入依赖
     

    xml

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.3.0</version>
    </dependency>
  2. 配置拦截器​(MyBatis 配置文件中):
     

    xml

    <plugins>
      <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="helperDialect" value="mysql"/> <!-- 指定数据库类型 -->
      </plugin>
    </plugins>
  3. 代码调用
     

    java

    // 开启分页
    PageHelper.startPage(pageNum, pageSize);
    List<User> users = userMapper.selectUsers();
    // 封装分页结果
    PageInfo<User> pageInfo = new PageInfo<>(users);

优点

  • 自动适配不同数据库的分页语法(如 MySQL、Oracle、PostgreSQL)。
  • 提供 PageInfo 对象,包含总记录数、总页数、当前页等分页信息。
  • 对代码侵入性低。
    缺点
  • 需要引入第三方依赖。

4. MyBatis-Plus 分页插件

原理:MyBatis-Plus 是 MyBatis 的增强工具,内置分页插件,通过拦截器实现物理分页。
使用步骤

  1. 引入依赖
     

    xml

    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.5.3.1</version>
    </dependency>
  2. 配置分页插件
     

    java

    @Configuration
    public class MybatisPlusConfig {
      @Bean
      public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
      }
    }
  3. 代码调用
     

    java

    // 创建分页参数
    Page<User> page = new Page<>(pageNum, pageSize);
    // 执行分页查询
    Page<User> result = userMapper.selectPage(page, null);
    // 获取分页信息
    long total = result.getTotal();
    List<User> users = result.getRecords();

优点

  • 与 MyBatis-Plus 深度集成,支持更丰富的 CRUD 操作。
  • 自动处理分页逻辑,返回包含分页信息的 Page 对象。

5. 自定义分页拦截器

原理:手动实现 MyBatis 的 Interceptor 接口,动态修改 SQL 添加分页逻辑。
适用场景

  • 需要高度定制化分页逻辑(如特殊的分页规则)。
  • 避免引入第三方依赖。
    缺点
  • 开发成本高,需处理不同数据库的语法差异。

分页方案对比

方案性能数据库兼容性代码侵入性适用场景
原生 SQL 分页低(需手动适配)简单查询、固定数据库类型
RowBounds小数据集、逻辑分页
PageHelper通用场景,推荐使用
MyBatis-Plus使用 MyBatis-Plus 的项目
自定义拦截器可定制特殊需求

总结

  • 推荐方案:优先使用 ​PageHelper 或 ​MyBatis-Plus 分页插件,二者均通过物理分页实现高性能,且对代码侵入性低。
  • 性能陷阱:避免使用 RowBounds 处理大数据集,可能导致内存溢出。
  • 数据库兼容性:若项目需支持多数据库,选择 PageHelper 或 MyBatis-Plus,它们能自动适配不同数据库的分页语法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值