MyBatis 在大数据量下使用流式查询进行数据同步

通常的数据同步中,如果数据量比较少的话可以直接全量同步,默认情况下,完整的检索结果集会将其存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于 MySQL 网络协议的设计,因此更易于实现。但是如果数据量很大的话,全量同步需要大量的内存,如果内存不足的话则可能会导致内存溢出。

通常的会采用分页的方式,一批一批的同步,大体的实现方式如下:

``

```java
int page = 1;
int pageNum = 1000;
while (true){
UserQueryRequest request = new UserQueryRequest();
request.setPage(page);
request.setPageSize(pageNum);
PageInfo<User> pageInfo = userMapper.getUserPage(request);
if (CollectionUtils.isEmpty(pageInfo.getList()) ){
break;
}
List<User> userList = pageInfo.getList();
// 具体的处理逻辑 省略

page ++;
}
```

这种实现方式虽然可以实现分批同步,但是同步的数据必须先提供实现分页的查询方式,如果数据源是通过复杂的连表查询来的,先实现一个分页查询更是会增加实现的复杂度。解决这个问题可以使用一种更为优雅的解决方式,即使用流失查询。

​ 流式查询,会建立长连接,利用服务端游标,每次读取一条加载到 JVM 内存,因此不会导致内存溢出。

 

## MyBatis 如何使用流式查询:

### 配置mapper.xml文件:

```xml
<select id="selectUsers" resultType="User" fetchSize="1000">
SELECT userId from t_user
</select>
```

### 自定义一个ResultHandler:

User是自定义的同步对象的实体对象,需要自己定义

```java
import lombok.extern.slf4j.Slf4j;
import model.User;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import java.util.ArrayList;
import java.util.List;

/**
* @author: jie
* @create: 2023/3/29 16:51
* @description:
*/
@Slf4j
public class SyncDataHandler implements ResultHandler<User> {

/**
* 每批处理数量
*/
private final static int BATCH_SIZE = 1000;

/**
* 缓存数据
*/
private List<User> cacheList = new ArrayList<>();

/**
* 同步熟虑
*/
private int total = 0;


@Override
public void handleResult(ResultContext<? extends User> resultContext) {
User coreInfoCyDTO = resultContext.getResultObject();
this.cacheList.add(coreInfoCyDTO);
//每到达BATCH_SIZE 条数据处理一次
if (this.cacheList.size() >= BATCH_SIZE) {
this.handle();
}
total++;
}


/**
* 处理缓存数据
*/
private void handle() {
try {
// 具体的处理逻辑 省略
} finally {
// 清除处理过的缓存数据
this.cacheList.clear();
}
}

/**
* 处理最后一批没有进行处理的数据
*/
public int end() {
this.end();
return total;
}
}
```

 

### 使用代码示例:

```java
SyncDataHandler syncDataHandler = new SyncDataHandler();
userMapper.getUserList("selectUsers", syncDataHandler);
syncDataHandler.end();
```

 

## **结言**

流式查询可以避免 OOM,,数据量大可以考虑此方案,其占用内存大小取决于批处理大小**BATCH_SIZE**的设置。所以**BATCH_SIZE**应该根据业务情况设置合适的大小。但是这这种方式会占用数据库连接,使用中不会释放,所以线上针对大数据量业务用到流式操作,一定要进行并发控制。

本文转载于网络 如有侵权请联系删除

相关文章

  • 总结了Python 各种常用语句~

    背景平时用时知道有相应的设置及相应的原理,具体设置时又不好查找,现特此整理出来供大家收藏代码可左右滑动查看Anacondapiplist #或者 condalist #其中,piplist只能查看库,而condalist则可以查看库以及库的版本 pipinstallscipy pipinstallscipy--upgrade #或者 condainstallscipy condaupdatescipy #更新所有库 condaupdate--all #更新conda自身 condaupdateconda #更新anaconda自身 condaupdateanaconda 复制jupyter#显示所有列 pd.set_option('display.max_columns',None) #显示所有行 pd.set_option('display.max_rows',None) #设置value的显示长度为100,默认为50 pd.set_option('max_colwidth',100) #内嵌画图 %matp

  • IJCAI 2021 医药AI必读论文推荐

    论文名称AMA-GCN:AdaptiveMulti-layerAggregationGraphConvolutionalNetworkforDiseasePrediction表型对于医疗影像诊断会有负面影响,多图融合方法的参数随着表型的增加而变大,从而影响模型的效果。为了应对上述挑战,作者提出了一种新的相似性感知自适应校正多层聚合称GCN结构(AMA-GCN),编码器根据表型数据的空间分布,自动选择适当的表型,并利用文本的相似性和边缘的感知机制计算节点之间的权重。编码器可以自动使用对环境有积极影响的策略构造表型图种群,并进一步融合多模式信息。此外,还提出了聚合机制,设计新颖的图多层卷积网络结构,可以在抑制的同时获得深层结构信息过度平滑,并在相同类型的节点之间增加相似性。论文名称LearningUnknownfromCorrelations:GraphNeuralNetworkforInter-novel-proteinInteractionPredict现有PPI的预测在新的数据集上的表现并不好。蛋白质之间的相关性,例如,蛋白质A与B有相互作用,B与C有相互作用,那么A与C是相关的。基

  • 拿什么记录下这魔幻又真实的一年

    楔子当这一年还剩下最后不到一个星期,我们试图将阳光、洪水、暴乱、疫情、蝗灾、山火、贫困拼接成一幅游牧的画卷。虽然这些碎片并不能构成一幅完整的地图。2020可能更像是星盘,每个角度和相位倒影着每一个事件每一个格局,我们身处其中的上升点和下降点,被宿命牵扯,在意这场占卜的输赢。在牺牲与期待中,企图看见共同的过去与未来。正文清晨醒来,热爱的传奇人物离世的消息,给本就曲折的年初摘了头彩。除此之外,山火蝗灾洪水等等灾害一起活跃,我们被动地接受这一切的挑战和变革。在试图抹去我们痕迹的世界里,没有了等级,没有了贵贱,没有先来后到尊卑长幼,我们却也在顽强地抵抗。总会想着怎么记录下这终将被载入史册的一年,网易博客、腾讯微博陆续关停,很多记忆也确实被消了磁。电话给了挚友,像是急忙想给消息做个确认,开头的第一句:我:老大走了。他没有说话,电话里头只有传来的呼吸声,许久的沉默后:他:嗯。提到嗓子里的话被咽了回来,我知道这也是他敬仰多年的人。我:我想找个地儿好好记录下今年的事情,很多年后也能看到多年前这的冲突对抗和盼望。他:你记得我的个人博客吗?我:我记得。他:那你听我说。他沉思了许久,像是整理着他的思绪:他:

  • 基于rest风格对Neo4j进行调用访问之———httpClient

    1.什么是rest风格不知道戳这里2.什么是Neo4j简单来说是一个图形数据库,是一种NOSQL型的。具体摸我3.httpclient访问参考官网链接摸我。 代码如下:packageneo4j.action; importcom.alibaba.fastjson.JSON; importcom.alibaba.fastjson.JSONObject; importneo4j.config.RestTemplateConfiguration; importorg.apache.commons.codec.binary.Base64; importorg.apache.commons.httpclient.HttpClient; importorg.apache.http.auth.AuthScope; importorg.apache.http.auth.UsernamePasswordCredentials; importorg.apache.http.client.CredentialsProvider; importorg.apache.http.client.method

  • 不就是用Python做个动态图吗?看招

    大家好,今天我们要讲的是如何使用Pyecharts制作动态排名变化图?制作这样的一个动态图使用到的是Pyecharts中的TimeLine(时间线轮播图),代码实现起来其实稍有难度,但我希望能通过讲解这样一张动态图的制作过程,来让各位读者可以使用Pyecharts将任何一种图动起来,我们开始吧!首先我们需要思考一下这样一种动态图的生成逻辑,不就是把每天的数据制作成一张条形图然后轮动吗,OK那我们的数据要整理成啥样呢?一个dataframe,每列是一个国家近20天的数据,还有一个存储20天时间的list?搞定数据之后我们去Pyecharts官方示例网站找到一个类似的图http://gallery.pyecharts.org/#/Timeline/timeline_bar_with_graphic复制官网示例代码和效果都给你了,我们要做的就是将这段代码改成我们需要的形式,现在我们将这段代码复制到Notebook中,并修改将图显示在notebook中 接下来我们观察这段代码与图,首先要改的是,把他每次两组变量改为一组变量,然后删掉和修改一些不需要的文字? 上图左边是修改前的代码,右边是代码修

  • C++核心准则F.50:不愿意使用函数时使用lambda表达式

    F.50:Usealambdawhenafunctionwon'tdo(tocapturelocalvariables,ortowritealocalfunction)F.50:在不愿意使用函数时使用lambda表达式(例如读取局部变量,访问局部函数)Reason(原因)Functionscan'tcapturelocalvariablesorbedefinedatlocalscope;ifyouneedthosethings,preferalambdawherepossible,andahandwrittenfunctionobjectwherenot.Ontheotherhand,lambdasandfunctionobjectsdon'toverload;ifyouneedtooverload,preferafunction(theworkaroundstomakelambdasoverloadareornate).Ifeitherwillwork,preferwritingafunction;usethesimplesttoolnecessary.

  • 编程小白 | 每日一练(192)

    “要成为绝世高手,并非一朝一夕,除非是天生武学奇才。但是这种人…万中无一”——包租婆这道理放在编程上也一并受用。在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从编程小白进阶到高手,需要经历的是日积月累的学习,那么如何学习呢?当然是每天都练习一道题目!!一、每日一练例192:本题要求实现一个计算xn(n≥1)的函数。函数接口定义:doublecalc_pow(doublex,intn);函数calc_pow应返回x的n次幂的值。建议用递归实现。题目保证结果在双精度范围内。输入样例:23输出样例:8代码演示: 结果演示:二、总结与思考我们常说“学而不思则罔”,和学习编程知识一样,我们只有在学习的同时加以总结与思考,才能对编程有更系统和深入地了解,学到的知识才真正能为自己所用。 转发朋友圈,点下“好看”就是对小编的最大帮助!

  • 直接插入排序到希尔排序做的那些改进

    主要推送关于对算法的思考以及应用的消息。坚信学会如何思考一个算法比单纯地掌握100个知识点重要100倍。本着严谨和准确的态度,目标是撰写实用和启发性的文章,欢迎您的关注,让我们一起进步吧。01—你会学到什么?彻底弄明白常用的排序算法的基本思想,算法的时间和空间复杂度,以及如何选择这些排序算法,确定要解决的问题的最佳排序算法,已经总结了冒泡排序和其改进后的快速排序算法,直接选择排序和堆排序算法,下面总结直接插入排序到希尔排序做的改进,后面再继续总结归并排序和基数排序。02—讨论的问题是什么?各种排序算法的基本思想;讨论各种排序算法的时间、空间复杂度;以及算法的稳定性;算法是如何改进的,比如冒泡排序如何改进成了目前最常用的快速排序的,直接选择排序到堆排序的改进,接下来要讨论直接插入排序到希尔排序做的优化。 03—相关的概念和理论内部排序若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。外部排序若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。就地排序若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间为O(1),称为就地排序。

  • 腾讯云云数据库Redis公共参数调用方式

    公共参数是用于标识用户和接口签名的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,但每次请求均需要携带这些参数,才能正常发起请求。 公共参数的具体内容会因您使用的签名方法版本不同而有所差异。 使用签名方法v3的公共参数签名方法v3(有时也称作TC3-HMAC-SHA256)相比签名方法v1(有些文档可能会简称签名方法),更安全,支持更大的请求包,支持POSTJSON格式,性能有一定提升,推荐使用该签名方法计算签名。完整介绍详见签名方法v3。 注意:接口文档中的示例由于目的是展示接口参数用法,简化起见,使用的是签名方法v1GET请求,如果依旧想使用签名方法v1请参考下文章节。 使用签名方法v3时,公共参数需要统一放到HTTPHeader请求头部中,如下表所示: 参数名称 类型 必选 描述 Action String 是 HTTP请求头:X-TC-Action。操作的接口名称。取值参考接口文档中输入参数公共参数Action的说明。例如云服务器的查询实例列表接口,取值为DescribeInstances。 Region String - HTTP请求头:X-

  • 使用.NET Core快速开发一个较正规的命令行应用程序

    程序员的世界,命令行工具一直是“体验非常友好”的工具,也能自动化完成很多事情,同时还能结合shell来进行某项任务的批处理(脚本)。在.NETCore中,命令行应用程序是基础,但是如何实现像“cat”这种功能呢?今天就为大家介绍一个packages来优雅的实现一个命令行应用程序。一般命令行程序包含什么?使用方式帮助信息子命令参数选项帮助信息帮助信息如上,介绍了命令的作用和参数、选项作用。这个是必不可少的。子命令一个应用程序打包了多个功能,这时候就可以使用子命令,比如dotnetefmigrations,这时候migrations就是子命令,可以看做本来可以拆分成多个可执行程序的东西,用一个可执行程序来打包完成,子命令可以再次具有自己的帮助、参数和选项。参数参数在形式上有点类似子命令,比如cathello.txt这边的hello.txt就是一个参数,参数一般是命令中必须存在的内容。比如cat命令,没有输入路径则没法执行任何任务。选项选项是指可选项,用来扩展命令。比如删除时是否需要输出被删除的文件?是否删除文件夹?是否递归删除?等等。如何用.NETCore快速开发一个命令行程序?Comma

  • MYsql 初识

    1.在新的mysqlzip文件中没有data数据包:需要我们再cmd中执行下面一行指令:   mysqld--initialize-insecure--user=mysql 2.数据库的链接操作:   1.showdatabase:显示数据库(即显示文件夹)   2.use文件夹的名字(对想要操作文件夹进行操作权限设置)   3.showtables显示文件夹中的文件   4.select*(操作所有文件)/(选择要操作的行每一个之间用逗号进行分割)from文件名3.进行用户的查看: 1showdatabases; 2.usemysql 3.showtables; 4.selecltuser,hostfromuser;复制 ViewCode 4进行用户的创建: createuser用户名@ip地址权限identifiedby用户密码复制 5对文件夹的操作:   1.创建文件夹:createdatabase文件夹名字   2.显示所有文件夹showdatabases;   3.删除文件夹:dropdatabase文件夹的名字 6.对文件的操作:   1.创建文件:createt

  • Java学习

    JAVA学习                 图片来源是黑马程序员   笔记: 1.关键字全部小写,关键字就是被java语言赋予了特殊含义的单词 2.空常量是不能直接输出的 本文来自博客园,作者:天勤也,转载请注明原文链接:https://www.cnblogs.com/XB-gzx/p/16060351.html

  • 测试

    北木商城购物流程一、注册及登录1、新会员注册:用户可以点击首页顶端或首页登录注册“免费注册”进入注册页面后选择使用邮箱地址或者手机号码注册,然后输入密码、确认密码及验证码,勾选我已阅读并同意《北木诚服务协议》,按照提示完成注册。2、会员登陆:用户可以点击首页顶端或首页右上栏“登录”进入登录页面后,登陆账号、密码进行登陆。3、忘记密码:对于忘记密码的会员,我们提供了找回密码的功能,请在找回密码的页面中输入您的用户名、注册时电子邮箱或已验证的手机号,系统将帮助您找回密码。二、查找商品1、您可以通过在首页输入关键字的方法来搜索您想要购买的商品。2、您还可以通过分类导航栏来找到您想要购买的商品分类,根据分类找到您的商品。三、放入购物车1、挑选商品后,在商品详细页面点击“购买”按钮,将商品放入购物车中。2、在购物车中,系统默认每件商品的订购数量为一件,如果您想购买多件商品,可修改购买数量。3、在购物车中,您可以将商品加入收藏夹,或是选择删除。4、在购物车中,您可以直接查看到商品的名称、价格、优惠活动。温馨提示:1、商品价格会不定期调整,最终价格以您提交订单后订单中的价格为准。2、优惠政策、配送时

  • Object.keys使用整理

    一、语法 Object.keys(obj) 参数:要返回其枚举自身属性的对象 返回值:一个表示给定对象的所有可枚举属性的字符串数组 复制     二、处理对象,返回可枚举的属性数组 letperson={ name:"张三", age:25, address:"深圳", getName:function(){} } Object.keys(person)//["name","age","address","getName"] 复制     三、处理数组,返回索引值数组 letarr=[1,2,3,4,5,6] Object.keys(arr)//["0","1","2","3","4","5"] 复制     四、处理字符串,返回索引值数组 letstr="saasd字符串" Object.keys(str)//["0","1","2","3","4","5","6","7"] 复制     五、常用技巧 letperson={ name:"张三", age:25, address:"深圳", getName:function(){} } Object.

  • 爬虫基础-登陆抽屉

    登陆抽屉,并点赞所有新闻   importrequests frombs4importBeautifulSoup #先访问抽屉新热榜,获取cookie(未授权) ret=requests.get( url='https://dig.chouti.com/all/hot/recent/1', headers={ 'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/67.0.3396.99Safari/537.36' } ) r1_cookie_dict=ret.cookies.get_dict() #伪造浏览器登陆,并且发送用户名和密码认证+cookie(未认证) response_login=requests.post( url='https://dig.chouti.com/login', data={ 'phone':'8613121758648', 'password':'woshiniba', 'oneMonth':1 }, hea

  • 分享泛微公司OA系统用于二次开发的sql脚本

     本单位用的oa系统就是泛微公司的oa协同办公平台,下面是我对他进行二次开发统计用到的写数据库脚本,只做开发参考使用,对于该系统的二次开发技术交流可以加我q:2050372586 【仪表盘】格式sql编写规则: ?只支持select语句并且,Select的结果必须为四列一行,且没列值为数值,其中 ?第一个值为最小值 ?第二个值为最大值 ?第三个值为安全值 ?第四个值为当前值 例如 Select0,400,300,count(id)fromhrmresource 【其他图形】格式sql编写规则(饼状、柱状、折线等等) 只支持select语句并且,select的结果必须为两列N(N>=1)行,且第二列必须为数值,其中 第一列值为显示项目(分类)名称 第二列值为对应项目(分类)的值 例如 员工数机构 sql: selecttop10(selectsubcompanynamefromhrmsubcompanywhereid=subCompanyId1),count(id)AscidsfromhrmresourcegroupbysubCompanyId1orderb

  • PHP-SplDoublyLinkedList

    <?php /** *@packageadoublylinkedlisttest *@authorzhaoyingnan<zhaoyn@bbtree.com> *@copyright *@version *@since **/ /*SplDoublyLinkedList *方法 SplDoublyLinkedListimplementsIterator,ArrayAccess,Countable { public__construct(void) publicvoidadd(mixed$index,mixed$newval)在指定的索引位置插入值 publicmixedbottom(void)查看开始位置的节点 publicmixedtop(void)查看结束位置的节点 publicintcount(void)返回所有的元素的数量 publicvoidrewind(void)倒回迭代器的开始 publicmixedcurrent(void)返回当前节点的信息 publicmixedkey(void)返回当前节点的索引 publicvoidsetIteratorMod

  • php setcooike()失败的原因之一,希望能帮到你

      在学习php的道路上,又双叒遇到了奇奇怪怪、意想不到的问题,emmm...其实找到最后,我遇到的问题其实不出在php上,但因为是php的方法没有生效,我们找病症肯定是从它着手的。   首先。看帖子和php的文档,都说在setcookie之前不能有输出。PHP手册   还试着使用ob_start()、ob_end_flush()输出缓冲,但也没有收到想要的效果。如果你的问题也不在这里,往下看:   有帖子说是utf-8编码格式bom作的妖 PHP中utf-8之bom引发的问题 另一位朋友给出的解决办法   那么我使用的是VSCode,右下角有一键转换   非常爽,嘿嘿...然并卵,问题也不在这里,继续: cookie设置(前端和后台)   里边提到了一句话解决了困扰我一天的问题。 XMLHttpRequest发送请求时需要设置withCredentials属性为true,来允许浏览器在自己的域设置cookie值。 如果withCredentials没有设置为true,就会出现ResponseHeaders有Set-Cookie,但是浏览器却没有存储cookie的情况  那么我在使

  • spring+mybatis

    spring+mybatis总结

  • 如何通过鹿哥提车快速理解mvc设计模式

    如何快速理解mvc设计模式 什么是mvc mvc是干什么的 第一点还是我们还是要走官方的步骤去官网或者百度一下mvc是什么(这里我就直接帮你们复制下来了) 一.什么是mvc MVC全名是ModelViewController,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。 MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。 比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。 模型-视图-控制器(MVC)是XeroxPARC在二十世纪八十年代为编程语言Smalltalk-80发明的一种软件设计模式,已被广泛使用。 后来被推荐为O

  • db2 表压缩

    #表压缩db2"ALTERTABLECUSTOMERCOMPRESSYESADAPTIVE"#立即启用压缩db2"reorgtableCUSTOMER" db2"reorgtableCUSTOMERresetdictionary"这个参数干嘛用的建立压缩字典   如果你认为文章有用,欢迎打赏!   自然语言处理爱好者,欢迎交流。QQ:7214218

相关推荐

推荐阅读