Mybatis集成MySQL使用游标查询处理大批量数据

本文主要是介绍Mybatis集成MySQL使用游标查询处理大批量数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

基于数据的时间范围查询,给符合条件的用户推送积分即将到期的提醒。

初期用户量小使用最普通简单的分页查询扫描数据处理数据没问题。随着用户量的上升表数据已经上千万,每天扫描处理的数量也超百万,limit分页出现了慢sql,任务执行时间也达不到预期了。

上述方案出现瓶颈后考虑放弃limit方案,使用游标的方式进行全量数据的获取,这样一来SQL执行快任务执行也快。

MySQL游标查询

useCursorFetch

使用游标查询时,,必须在jdbc url上设置连接属性参数useCursorFetch=true

FetchSize 

在设置了useCursorFetch=true后,需要在SQL中指定fetchSize,即一次获取的数据量。

如果不设置fetchSize参数,则执行时仍然是全量返回,可能会出现OOM。

Mybatis集成Cursor查询

mapper接口方法返回值声明为Cursor类型,下面是SQL和Mapper的示例。

Cursor<Long> selectExpireCouponMember(@Param("endTime") String endTime);<select id="selectExpireCouponMember" resultType="java.lang.Long" fetchSize="5000">selectdistinct member_idfrom t_dj_couponwhereend_time > end_time < #{endStartTime} and end_time < #{endTime}
</select>

 下面是基于上面的SQL做大量数据查询后写入文件的代码示例。

String fileName = DateFormatUtils.format(System.currentTimeMillis(), DateUtils.PATTERN_YYYY_MM_DD) + "_status_push_member.txt";
File file = new File(fileName);
file.createNewFile();fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {DjCouponMapper mapper = sqlSession.getMapper(DjCouponMapper.class);try (Cursor<Long> cursor = mapper.selectStartCouponMember(startDate, startDateEnd, BrandContextHolder.getBrandMdCode())) {Iterator<Long> iterator = cursor.iterator();Set<Long> couponMemberSet = new HashSet<>(pageSize.intValue());while (iterator.hasNext()) {couponMemberSet.add(iterator.next());writeNum++;if (couponMemberSet.size() >= pageSize) {bufferedWriter.write(couponMemberSet.toString());bufferedWriter.newLine();bufferedWriter.flush();writeLine++;couponMemberSet.clear();}}if (CollectionUtils.isNotEmpty(couponMemberSet)) {bufferedWriter.write(couponMemberSet.toString());bufferedWriter.newLine();bufferedWriter.flush();writeLine++;}}
}

Mybatis是如何实现基于Cursor查询的

com.mysql.cj.jdbc.result.ResultSetImpl实现类

ResultSetImpl 是mybatis中实现游标查询结果解析的类。这个实现类的next方法中调用了ResultsetRows接口的next方法。

ResultsetRows接口

ResultsetRows接口有ResultsetRowsCursor,ResultsetRowsStatic,ResultsetRowsStreaming三个实现类。

本文写的游标查询的场景,使用的是ResultsetRowsCursor这个实现类。

详细看下ResultsetRowsCursor这个实现类,主要是实现了Iterator的hasNext和next方法,这也是使用Cursor获取数据需要的两个方法。

下面是hasnext方法的逻辑,根据下次要获取的游标索引和当前本地数据集计算返回是否还有后续数据可以获取。

 下面是next方法的逻辑,先执行一下hasnext的逻辑判断,再取值

 

这篇关于Mybatis集成MySQL使用游标查询处理大批量数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/623729

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

mybatis映射器配置小结

《mybatis映射器配置小结》本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定... 目录select中字段的映射问题使用SQL语句中的别名功能使用mapUnderscoreToCame