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

25. MyBatis中的RowBounds是什么?如何实现内存分页?

是 MyBatis 提供的一种用于结果集分页的功能,主要通过内存分页的方式实现。它通过在查询时传递分页参数,限制返回的结果集的大小。RowBounds 并不依赖于数据库层的分页功能,而是通过 MyBatis 在内存中对结果集进行截取,从而实现分页。

RowBounds 的基本属性

  • offset:从结果集的第几条记录开始截取。

  • limit:截取的记录条数。

例如,offset=5limit=10RowBounds 实例表示从结果集的第 6 条记录开始,取 10 条记录。

如何在 MyBatis 中使用 RowBounds 实现内存分页?

1. 使用 RowBounds 进行内存分页

RowBounds 的使用非常简单,可以通过 SqlSessionselectList 方法来传递 RowBounds 实例,从而实现分页。

示例:

假设我们有一个数据库表 user,并希望对查询结果进行分页。

Step 1: 定义 Mapper 接口

public interface UserMapper {List<User> selectAllUsers(RowBounds rowBounds);
}

Step 2: 配置 XML 映射文件

<mapper namespace="com.example.mapper.UserMapper"><select id="selectAllUsers" resultType="User">SELECT * FROM user</select>
</mapper>

Step 3: 使用 RowBounds 实现分页查询

try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);
​// 分页参数:从第 10 条记录开始,取 10 条记录RowBounds rowBounds = new RowBounds(10, 10);
​List<User> users = mapper.selectAllUsers(rowBounds);
​users.forEach(System.out::println);
}

在这个例子中,RowBounds 实例被传递给 selectAllUsers 方法。RowBounds 将从查询结果的第 11 条记录开始,取 10 条记录进行返回。

2. RowBounds 的局限性

尽管 RowBounds 实现了分页功能,但它有一些局限性:

  • 内存分页RowBounds 是在内存中对查询结果进行分页,这意味着在数据库层面,查询仍然会返回完整的结果集。如果结果集非常大(比如包含数百万条记录),则会消耗大量的内存和处理时间,不适用于大数据量分页。

  • 性能问题:由于 RowBounds 是在内存中截取结果集,这对内存和 CPU 的消耗较大,尤其是当 offset 较大时,查询性能会显著下降。

如何实现数据库层面的分页(推荐)?

由于 RowBounds 的局限性,通常更推荐在数据库层面进行分页查询。不同的数据库支持不同的分页查询语法,以下是几种常见数据库的分页实现方式。

1. MySQL

在 MySQL 中,可以通过 LIMIT 子句实现分页:

SELECT * FROM user LIMIT #{offset}, #{limit};

MyBatis 配置:

<select id="selectUsersWithPagination" resultType="User">SELECT * FROM user LIMIT #{offset}, #{limit}
</select>

Mapper 接口:

public interface UserMapper {List<User> selectUsersWithPagination(@Param("offset") int offset, @Param("limit") int limit);
}

调用:

try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);List<User> users = mapper.selectUsersWithPagination(10, 10);users.forEach(System.out::println);
}

2. Oracle

在 Oracle 中,可以通过 ROWNUM 或者 ROW_NUMBER() 函数实现分页:

SELECT * FROM (SELECT t.*, ROWNUM r FROM (SELECT * FROM user ORDER BY id) t WHERE ROWNUM <= #{end}
) WHERE r > #{start};

MyBatis 配置:

<select id="selectUsersWithPagination" resultType="User">SELECT * FROM (SELECT t.*, ROWNUM r FROM (SELECT * FROM user ORDER BY id) t WHERE ROWNUM <= #{end}) WHERE r > #{start}
</select>

Mapper 接口:

public interface UserMapper {List<User> selectUsersWithPagination(@Param("start") int start, @Param("end") int end);
}

调用:

try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);List<User> users = mapper.selectUsersWithPagination(10, 20); // 从第11到20条users.forEach(System.out::println);
}

3. PostgreSQL

在 PostgreSQL 中,使用 LIMITOFFSET 进行分页:

SELECT * FROM user LIMIT #{limit} OFFSET #{offset};

MyBatis 配置和调用方式与 MySQL 类似

总结

  • RowBounds 的用途RowBounds 是 MyBatis 提供的一种内存分页方式,适用于小数据量的分页场景。

  • 局限性:由于 RowBounds 是在内存中截取结果集,对于大数据量分页会带来性能问题和内存消耗,通常不推荐在大数据量情况下使用。

  • 推荐的分页方式:通常推荐在数据库层面进行分页,通过 SQL 的 LIMITOFFSET 等子句直接获取分页后的结果集,这样可以有效减少数据传输和内存占用,提高分页性能。

在实际开发中,根据数据量大小和系统性能要求选择合适的分页方式。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • KAN 学习 Day4 —— MultKAN 正向传播代码解读及测试
  • 【RabbitMQ】概述
  • 骨传导耳机哪个品牌比较好?盘点五款闭眼入都不踩雷的优质骨传导耳机!
  • 大模型LLM之SpringAI:Web+AI(一)
  • UEFI学习笔记(七):UEFI_Spec_2_10 Protocols整理
  • 【滑动窗口-1004. 最大连续1的个数 III】
  • 基于Java+SpringBoot+Vue+MySQL的西安旅游管理系统网站
  • Windows--linux共享文件夹
  • SAP B1 学习笔记 - 易混淆字段名(持续更新中)
  • matlab数据批量保存为excel,文件名,行和列的名称设置
  • Redis面对数据量庞大处理方法
  • 基于SpringBoot的社团管理系统
  • Java实现邮箱发送功能详细步骤及注意事项?
  • 介绍 Apache Spark 的基本概念和在大数据分析中的应用。
  • Java设计模式—面向对象设计原则(二) --------> 里氏代换原则 LSP (完整详解,附有代码+案列)
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Laravel核心解读--Facades
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • mac修复ab及siege安装
  • Python进阶细节
  • Shell编程
  • spring学习第二天
  • zookeeper系列(七)实战分布式命名服务
  • 阿里研究院入选中国企业智库系统影响力榜
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 分布式任务队列Celery
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 小程序 setData 学问多
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 最简单的无缝轮播
  • MPAndroidChart 教程:Y轴 YAxis
  • NLPIR智能语义技术让大数据挖掘更简单
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • #Datawhale X 李宏毅苹果书 AI夏令营#3.13.2局部极小值与鞍点批量和动量
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (04)odoo视图操作
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (33)STM32——485实验笔记
  • (7) cmake 编译C++程序(二)
  • (二)springcloud实战之config配置中心
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (转)大型网站的系统架构
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .net 流——流的类型体系简单介绍
  • .Net 中Partitioner static与dynamic的性能对比
  • .netcore如何运行环境安装到Linux服务器
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka