MyBatis实现分页全过程

 更新时间:2025年08月27日 08:44:49   作者:Java自学之旅  
MyBatis分页有三种方式:手动SQL分页(性能高但需处理数据库差异)、RowBounds(简单但不推荐)、PageHelper分页插件(自动改写SQL,推荐生产环境),PageHelper适合百万级数据优化,是终极解决方案

下面我将详细讲解MyBatis实现分页的几种方式,通过通俗易懂的故事和代码示例帮助理解:

故事背景

假设我们经营一个"图书管理系统",数据库中有10万本图书。

当用户查看图书列表时,一次性加载所有数据会导致系统崩溃(就像把整个图书馆的书都堆在收银台上)。

这时就需要分页功能——每次只展示"一架子书"(如每页20本)。

一、MyBatis实现分页的三种方式

1.手动SQL分页(物理分页)

SELECT * FROM books LIMIT #{start}, #{pageSize}

原理

直接在SQL中通过LIMIT(MySQL)或ROWNUM(Oracle)控制数据范围。

代码示例

// Mapper接口
List<Book> getBooksByPage(@Param("start") int start, @Param("pageSize") int pageSize);

// 调用方式(获取第3页,每页20条)
int pageNum = 3;
int pageSize = 20;
List<Book> books = bookMapper.getBooksByPage((pageNum-1)*pageSize, pageSize);

✅ 优点

  • 性能最佳(数据库只返回所需数据)
  • 完全掌控SQL逻辑

❌ 缺点

  • 需手动计算偏移量(如(pageNum-1)*pageSize
  • 不同数据库语法不同(MySQL用LIMIT,Oracle用ROWNUM)

2.RowBounds分页(逻辑分页)

RowBounds rowBounds = new RowBounds(40, 20); // 跳过前40条,取20条
List<Book> books = sqlSession.selectList("getAllBooks", null, rowBounds);

原理
先查询所有数据到内存,再在Java层截取指定范围(像把整个图书馆的书运到仓库,再挑出20本)。

✅ 优点

  • 使用简单,无需改SQL

❌ 缺点

  • 性能灾难(数据量大时内存溢出)
  • 实际工作中禁止使用!

3.分页插件(推荐方案)

使用PageHelper插件(最主流方案):

// 只需在查询前设置分页参数
PageHelper.startPage(3, 20); // 第3页,每页20条
List<Book> books = bookMapper.selectAllBooks();

// 获取分页信息
PageInfo<Book> pageInfo = new PageInfo<>(books);
System.out.println("总页数:" + pageInfo.getPages());

原理

通过MyBatis拦截器自动改写SQL,添加LIMIT语句(像有个智能机器人帮你从书架上拿指定范围的书)。

配置步骤

  1. 添加依赖:
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.2</version>
</dependency>
  1. 配置拦截器(mybatis-config.xml):
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>

✅ 优点

  • 零侵入(不改动原SQL)
  • 自动适配不同数据库
  • 返回丰富分页信息(总页数/当前页等)

二、分页原理对比表

方式性能易用性适用场景
手动SQL分页⭐⭐⭐⭐⭐⭐简单SQL,明确数据库类型
RowBounds⭐⭐⭐⭐禁止生产使用
PageHelper⭐⭐⭐⭐⭐⭐⭐⭐⭐99%的生产场景

三、总结

绝对避免使用RowBounds逻辑分页(除非数据量极小)

简单场景可用手动SQL分页(需处理数据库差异)

PageHelper是终极解决方案

  • 自动生成分页SQL
  • 统一不同数据库行为
  • 返回完整分页元数据

百万级数据分页优化:

-- 使用索引覆盖优化
SELECT * FROM books 
WHERE id >= (SELECT id FROM books ORDER BY id LIMIT 1000000, 1)
LIMIT 20

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring注入Map集合实现策略模式详解

    Spring注入Map集合实现策略模式详解

    这篇文章主要介绍了Spring注入Map集合实现策略模式详解,Spring提供通过@Resource注解将相同类型的对象注入到Map集合,并将对象的名字作为key,对象作为value封装进入Map,需要的朋友可以参考下
    2023-11-11
  • JAVA二叉树的几种遍历(递归,非递归)实现

    JAVA二叉树的几种遍历(递归,非递归)实现

    这篇文章主要介绍了JAVA二叉树的几种遍历(递归,非递归)实现,需要的朋友可以参考下
    2020-12-12
  • Java使用 Spire.PDF for Java轻松搞定拆分PDF

    Java使用 Spire.PDF for Java轻松搞定拆分PDF

    有时我们需要对大型 PDF 文档进行精细化管理,例如,将一个多页的合同拆分成单页以便逐页审批,本文将为您介绍如何使用 Spire.PDF for Java 库来轻松实现 PDF 拆分,感兴趣的小伙伴可以了解下
    2025-12-12
  • Spring Boot优雅地处理404异常问题

    Spring Boot优雅地处理404异常问题

    这篇文章主要介绍了Spring Boot优雅地处理404异常问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • IDEA中java: 找不到符号 符号: 变量log

    IDEA中java: 找不到符号 符号: 变量log

    这篇文章主要介绍了使用@Slf4j注解时出现log变量找不到符号问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • java中Calendar与Date类型互相转换的方法

    java中Calendar与Date类型互相转换的方法

    这篇文章主要介绍了java中Calendar与Date类型互相转换的方法,Calendar与Date类型是我们日常开发中常用的两种数据类型,它们用于不同的场景,两者具有不同的方法,接下来通过实例给大家详解,需要的朋友可以参考下
    2022-09-09
  • java中JDeps命令使用

    java中JDeps命令使用

    jdeps是一个Java类依赖分析工具,用于分析Java应用程序的依赖情况,包括类、包、模块以及JDK内部API的使用,本文就来详细的介绍一下,感兴趣的可以了解一下
    2024-09-09
  • Java object类及正则表达式原理解析

    Java object类及正则表达式原理解析

    这篇文章主要介绍了Java object类及正则表达式原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 详解Maven环境的搭建与idea配置

    详解Maven环境的搭建与idea配置

    本篇文章主要介绍了详解Maven环境的搭建与idea配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 防止SpringMVC拦截器拦截js等静态资源文件的解决方法

    防止SpringMVC拦截器拦截js等静态资源文件的解决方法

    本篇文章主要介绍了防止SpringMVC拦截器拦截js等静态资源文件的解决方法,具有一定的参考价值,有兴趣的同学可以了解一下
    2017-09-09

最新评论