当前位置: 首页 > news >正文

Mybatis 是如何进行分页的?分页插件的原理是什么?

一、MyBatis 中的分页方法

MyBatis 可以通过以下几种方式来实现分页:

1. 手动分页

手动分页是指在 SQL 查询中直接使用数据库提供的分页功能。不同的数据库支持不同的分页语法。

**示例:**

- **MySQL** 中使用 `LIMIT` 和 `OFFSET`:

  ```sqlSELECT * FROM employees LIMIT 10 OFFSET 20;```

  这条查询语句会从第 21 条记录开始,返回 10 条记录。

- **Oracle** 中使用 `ROWNUM` 或者 `ROW_NUMBER()`:

  ```sqlSELECT * FROM (SELECT a.*, ROWNUM rnumFROM (SELECT * FROM employees) aWHERE ROWNUM <= 30)WHERE rnum > 20;```

在 MyBatis 中,通过 XML 配置或注解直接编写上述 SQL 语句,即可实现分页。

**在 Mapper 中的示例:**

```xml
<select id="selectEmployees" resultType="Employee">SELECT * FROM employees LIMIT #{limit} OFFSET #{offset}
</select>
```

调用时,传入 `limit` 和 `offset` 参数即可实现分页。

 2. 使用 RowBounds 进行分页

MyBatis 提供了 `RowBounds` 类来支持分页。`RowBounds` 是一个逻辑分页机制,它并不改变 SQL 语句,而是在查询结果集中进行截取。这种方式适用于数据量较小的情况,因为它会先将所有数据查询出来,然后再进行分页。

**示例:**

```java
RowBounds rowBounds = new RowBounds(offset, limit);
List<Employee> employees = sqlSession.selectList("selectEmployees", null, rowBounds);
```

虽然使用 `RowBounds` 实现了分页,但由于它是内存分页,性能较差,因此不推荐在大数据量时使用。

二、分页插件的原理

为了更高效和便捷地实现分页,MyBatis 社区开发了多种分页插件。这些插件通过拦截器(Interceptor)机制,在 SQL 执行前或执行后自动修改 SQL 语句或处理查询结果,实现数据库层面的分页。

1. 分页插件的工作原理

分页插件的工作原理主要包括以下步骤:

1. **拦截器机制**:分页插件通过 MyBatis 的拦截器机制拦截执行 SQL 的方法,例如 `Executor` 接口中的 `query` 方法。通过拦截器,插件可以在 SQL 执行之前或执行之后对 SQL 语句进行修改。

2. **自动添加分页语句**:当拦截到查询方法时,分页插件会检测传入的参数是否包含分页信息(如 `pageNum` 和 `pageSize`)。如果包含,插件会根据数据库类型自动为原始 SQL 语句添加相应的分页语句(如 `LIMIT`、`OFFSET`、`ROWNUM` 等)。

3. **执行分页 SQL**:经过插件修改的 SQL 会被执行器执行,数据库返回分页后的结果集。

4. **封装结果**:插件可以进一步封装查询结果,将其封装为分页对象,如 `Page<T>`,以便开发者方便地使用分页结果。

2. 常见的分页插件

- **PageHelper**:PageHelper 是 MyBatis 中最流行的分页插件。它通过自动拦截查询语句,添加 `LIMIT` 和 `OFFSET` 子句来实现分页,并且能够自动处理分页参数和结果集封装。

  **配置示例:**

  在 MyBatis 配置文件中引入 PageHelper 插件:

  ```xml<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="dialect" value="mysql"/></plugin></plugins>```

  **使用示例:**

PageHelper.startPage(pageNum, pageSize);List<Employee> employees = sqlSession.selectList("selectEmployees");PageInfo<Employee> pageInfo = new PageInfo<>(employees);

  在调用分页方法之前,使用 `PageHelper.startPage()` 方法设置分页参数。查询结果会自动分页,并封装到 `PageInfo` 对象中,包含总记录数、总页数、当前页等信息。

- **MyBatis-Plus 分页插件**:MyBatis-Plus 是一个 MyBatis 的增强工具,提供了强大的分页插件功能。它的分页插件也通过拦截器实现自动分页,并且支持多种数据库。

  **配置示例:**

  在 MyBatis-Plus 中引入分页插件:

@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}

  **使用示例:**

IPage<Employee> page = new Page<>(pageNum, pageSize);IPage<Employee> employeePage = employeeMapper.selectPage(page, null);

  MyBatis-Plus 的分页插件不仅简化了分页的配置,还集成了很多其他实用功能,适合需要高效开发的项目。

三、分页插件的优缺点

 1. 优点

- **自动化**:分页插件通过拦截和修改 SQL 语句,实现了自动分页,开发者无需手动编写分页 SQL。
- **高效**:插件直接在数据库层面实现分页,避免了内存分页的性能瓶颈。
- **易用性**:插件通常会封装分页结果,使得开发者可以方便地处理分页数据,如获取总记录数、总页数、当前页等信息。

2. 缺点

- **复杂性**:分页插件增加了系统的复杂性,尤其是在处理复杂查询或特定数据库时,可能需要额外的配置或调试。
- **依赖性**:使用分页插件时,系统对插件产生了依赖性,如果插件更新或不再维护,可能会影响系统的稳定性。
- **扩展性**:有时插件可能不支持某些高级或自定义的分页需求,开发者需要自己扩展或修改插件代码。

四、总结

MyBatis 通过手动分页、`RowBounds` 分页以及分页插件等多种方式实现分页。手动分页直接在 SQL 语句中使用数据库的分页功能,适用于简单的分页需求;`RowBounds` 是一种内存分页方式,适用于小数据量;而分页插件则通过拦截 SQL 语句,在数据库层面自动实现分页,是一种高效、易用的分页方案。

分页插件,如 PageHelper 和 MyBatis-Plus,利用拦截器机制,自动为 SQL 语句添加分页功能,并封装结果集,使得开发者可以更轻松地处理分页查询。这些插件在提高开发效率、优化分页性能方面发挥了重要作用,但同时也带来了系统复杂性和依赖性的问题。根据具体项目需求选择合适的分页方式,可以在性能和开发效率之间取得良好的平衡。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • java构建工具-maven的复习笔记【适用于复习或者初步了解】
  • WebView快速打开
  • 公司招聘中,多个面试官对候选人评价不一致怎么办?
  • class 3: vue.js 3 计算属性
  • Java中的注解(Annotation)
  • MySQL入门学习-MySQL的连接查询
  • switch语句和while循环
  • 算法练习题07:无重复字符的最长子串
  • 临时性解决斐讯K3 路由器端口转发限制
  • GO Date数据处理
  • CSS-定位【看这一篇就够了】
  • 食堂线上预约点餐系统小程序的设计
  • 使用 FormCreate 渲染 Element Plus 表单
  • k8s1.23 部署Prometheus-Operator集群监控
  • 贪心算法---用最少数量的箭引爆气球
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【刷算法】从上往下打印二叉树
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • css属性的继承、初识值、计算值、当前值、应用值
  • Promise初体验
  • Spring框架之我见(三)——IOC、AOP
  • sublime配置文件
  • 从输入URL到页面加载发生了什么
  • 二维平面内的碰撞检测【一】
  • 微服务核心架构梳理
  • 我感觉这是史上最牛的防sql注入方法类
  • 学习使用ExpressJS 4.0中的新Router
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​补​充​经​纬​恒​润​一​面​
  • ​决定德拉瓦州地区版图的关键历史事件
  • #HarmonyOS:软件安装window和mac预览Hello World
  • $ git push -u origin master 推送到远程库出错
  • (1)SpringCloud 整合Python
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (NSDate) 时间 (time )比较
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (笔记)M1使用hombrew安装qemu
  • (理论篇)httpmoudle和httphandler一览
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core 成都线下面基会拉开序幕
  • .net Signalr 使用笔记
  • .NET 中创建支持集合初始化器的类型
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .Net的DataSet直接与SQL2005交互
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @Transactional 竟也能解决分布式事务?
  • @Transient注解
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [ 转载 ] SharePoint 资料