百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

查询千万数据,除了分页,还有mybatis效率更高的流式查询

ccwgpt 2025-04-05 17:22 20 浏览 0 评论


基本概念

流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低内存使用。

如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好,就无法执行高效的分页查询。因此流式查询是一个数据库访问框架必须具备的功能。

流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:执行一个流式查询后,数据库访问框架就不负责关闭数据库连接了,需要应用在取完数据后自己关闭。

MyBatis 流式查询接口

MyBatis 提供了一个叫

org.apache.ibatis.cursor.Cursor 

的接口类用于流式查询,这个接口继承了 java.io.Closeablejava.lang.Iterable 接口,由此可知

1、 Cursor 是可关闭的;

2、 Cursor 是可遍历的。

除此之外,Cursor 还提供了三个方法:

1、 isOpen():用于在取数据之前判断 Cursor 对象是否是打开状态。只有当打开时 Cursor 才能取数据;

2、 isConsumed():用于判断查询结果是否全部取完。

3、 getCurrentIndex():返回已经获取了多少条数据

因为 Cursor 实现了迭代器接口,因此在实际使用当中,从 Cursor 取数据非常简单:

cursor.forEach(rowObject -> {...});

但构建 Cursor 的过程不简单

我们举个实际例子。下面是一个 Mapper 类:

@Mapper
publicinterfaceFooMapper{
   @Select("select * from foo limit #{limit}")
   Cursor scan(@Param("limit") int limit);
}

方法 scan() 是一个非常简单的查询。通过指定 Mapper 方法的返回值为 Cursor 类型,MyBatis 就知道这个查询方法一个流式查询。

然后我们再写一个 SpringMVC Controller 方法来调用 Mapper(无关的代码已经省略):

@GetMapping("foo/scan/0/{limit}")
publicvoid scanFoo0(@PathVariable("limit") int limit) throwsException{
   try(Cursor cursor = fooMapper.scan(limit)) {  // 1
       cursor.forEach(foo -> {});                      // 2
   }
}

上面的代码中,fooMapper 是 @Autowired 进来的。注释 1 处调用 scan 方法,得到 Cursor 对象并保证它能最后关闭;2 处则是从 cursor 中取数据。

上面的代码看上去没什么问题,但是执行 scanFoo0() 时会报错:

java.lang.IllegalStateException: A Cursoris already closed.

这是因为我们前面说了在取数据的过程中需要保持数据库连接,而 Mapper 方法通常在执行完后连接就关闭了,因此 Cusor 也一并关闭了。

所以,解决这个问题的思路不复杂,保持数据库连接打开即可。我们至少有三种方案可选。

方案一:SqlSessionFactory

我们可以用 SqlSessionFactory 来手工打开数据库连接,将 Controller 方法修改如下:

@GetMapping("foo/scan/1/{limit}")
publicvoid scanFoo1(@PathVariable("limit") int limit) throwsException{
   try(
       SqlSession sqlSession = sqlSessionFactory.openSession();  // 1
       Cursor cursor =
             sqlSession.getMapper(FooMapper.class).scan(limit)   // 2
   ) {
       cursor.forEach(foo -> { });
   }
}

上面的代码中,

1 处我们开启了一个 SqlSession (实际上也代表了一个数据库连接),并保证它最后能关闭;

2 处我们使用 SqlSession 来获得 Mapper 对象。这样才能保证得到的 Cursor 对象是打开状态的。

方案二:TransactionTemplate

在 Spring 中,我们可以用 TransactionTemplate 来执行一个数据库事务,这个过程中数据库连接同样是打开的。代码如下:

@GetMapping("foo/scan/2/{limit}")
publicvoid scanFoo2(@PathVariable("limit") int limit) throwsException{
   TransactionTemplate transactionTemplate =
           newTransactionTemplate(transactionManager);  // 1
   transactionTemplate.execute(status -> {               // 2
       try(Cursor cursor = fooMapper.scan(limit)) {
           cursor.forEach(foo -> { });
       } catch(IOException e) {
           e.printStackTrace();
       }
       returnnull;
   });
}

上面的代码中,

1 处我们创建了一个 TransactionTemplate 对象(此处 transactionManager 是怎么来的不用多解释,本文假设读者对 Spring 数据库事务的使用比较熟悉了)。

2 处执行数据库事务,而数据库事务的内容则是调用 Mapper 对象的流式查询。注意这里的 Mapper 对象无需通过 SqlSession 创建。

方案三:@Transactional 注解

这个本质上和方案二一样,代码如下:

@GetMapping("foo/scan/3/{limit}")
@Transactional
publicvoid scanFoo3(@PathVariable("limit") int limit) throwsException{
   try(Cursor cursor = fooMapper.scan(limit)) {
       cursor.forEach(foo -> { });
   }
}

它仅仅是在原来方法上面加了个 @Transactional 注解。这个方案看上去最简洁,但请注意 Spring 框架当中注解使用的坑:只在外部调用时生效。在当前类中调用这个方法,依旧会报错。

以上是三种实现 MyBatis 流式查询的方法。

相关推荐

PPT 139 | 粉色渐变小清新春暖花开PPT模板

春暖花开,这是你制作PPT的世界粉色渐变小清新春暖花开PPT模板,共22P适用场合:工作总结/个人汇报/演讲培训等喜欢的可以赞一个更多类似PPT模板,搜【小清新】也可以,在线编辑,一键下载...

框架完整岗位竞聘报告PPT模板

需要源文件de可私!氢元素为您提供PPT模板、PNG元素免费、办公模板。工作述职汇报、计划总结、培训课件、节日庆典、营销策划、商业计划、宣传企业、产品发布、个人简历、毕业答辩、岗位竞聘、护理培训,...

PPT与视频相关的几个操作要点

都知道PPT中可以插入视频,而2010及以上版本插入后还可以对视频做各种处理,另外别忘了还可以直接将PPT导出成视频格式。插入视频方式往PPT中插入视频,除了【插入】|【视频】|【PC上的视频】这种方...

书写主题品管圈汇报PPT模板,主题框架,简约设计,品管圈必备

Hello大家好,我是帮帮。今天跟大家分享一张书写主题品管圈汇报PPT模板,主题框架,简约设计,品管圈必备。有个好消息!为了方便大家更快的掌握技巧,寻找捷径。请大家点击文章末尾的“了解更多”,在里面找...

【教学成果框架图】国家级获奖案例解析与可视化方案(实战版)

教学成果逻辑框架图的绘制精髓总结为“逻辑为骨,视觉为翼”。下面结合具体案例,手把手教你制作既专业又美观的成果框架图。一、设计理念:教育逻辑与视觉传达的融合教学成果框架图需体现三重逻辑:教育目标层(立德...

工作总结PPT模板完整框架 (30)

年中汇报PPT的超强框架来袭,职场人士的必备神器!

这套框架堪称完美,适用于各类工作汇报场景。它逻辑清晰,内容丰富,涵盖个人介绍、工作回顾、业绩成果、问题分析以及未来工作计划等常见汇报模块。PPT已包含600多页,所有元素均可自由编辑,数据图表也能轻松...

三个说话框架,提升逻辑思维,让你清晰表达

#暑期创作大赛#建立清晰的逻辑思维:三个说话框架的力量我们生活在一个充满语言交流的世界中。无论是在学校,工作场所,还是在社交场合,我们都需要有效地表达我们的观点和想法。然而,许多人都有表达上的困扰,他...

《石头记》人物原型故事之逻辑框架(一)

话说空空道人将《石头记》带往人世,又经东鲁孔梅溪醒题《风月宝鉴》,曹雪芹定名《金陵十二钗》,加之警幻仙子提醒防备新谱《红楼梦十二支曲》。蛮以为他人在闲适风月故事之于能够了然背后真实故事,怎耐一万年老怪...

如何搭建高效沟通与精彩演讲的逻辑结构

对于大多数人而言,说话有逻辑这件事难于登天。很多人在演讲、工作汇报中都会遇到诸如“我不知道你在说什么”、“你的重点是什么”、“你说话毫无逻辑”此类的评价,被认为是说话缺乏逻辑的人。那么如何成为一个说话...

「书讯」论证逻辑框架下说理写作模式研究

《论证逻辑框架下说理写作模式研究》作者:金建龙出版日期:2018年11月开本:16开出版社:经济管理出版社小编推荐提升大学生批判意识和理性说理能力是新时代背景下高等教育中通识教育和博雅教育的全新探索...

【一元脑花】青少年4D逻辑训练的基本框架

一、核心训练模块多维认知构建资源分布图谱:通过分析社会资源层级与流动规律,建立立体空间认知模型2DOC时空维度整合:将历史局势演变(纵向时间轴)与未来趋势预判(横向可能性轴)结合训练2DOC动态干预系...

提升写作逻辑,这5个框架你搭建好了吗?

每个人都有写作的愿望,也都想表达心中浩荡的情感,但多年过后,许多人依旧卡在“无话可说”“写不出结构”的怪圈里。有人慨叹:“浮云一别后,流水十年间”,梦想与现实总有一道沟壑横亘——此岸是满腹心事,彼岸...

2023年主观题法治思想知识框架图

...

学霸:2天吃透初一语文上学期核心预习知识框架图|暑假弯道超车

学霸:2天吃透初一语文上学期核心预习知识框架图|暑假弯道超车。具体如下:查看作者的个人主页获悉剩余的~...

取消回复欢迎 发表评论: