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

 更新时间:2023年05月30日 10:56:01   作者:知北游z  
通常的数据同步中,如果数据量比较少的话可以直接全量同步,但是如果数据量很大的话,全量同步需要大量的内存,所以本文为大家介绍了MyBatis使用流式查询实现数据同步的方法,希望对大家有所帮助

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

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

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文件:

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

自定义一个ResultHandler:

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

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;
    }
}

使用代码示例:

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

结言

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

到此这篇关于详解MyBatis如何在大数据量下使用流式查询进行数据同步的文章就介绍到这了,更多相关MyBatis流式查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java:无法访问org.springframework.boot.SpringApplication的解决方法

    java:无法访问org.springframework.boot.SpringApplication的解决方法

    这篇文章主要给大家介绍了关于java:无法访问org.springframework.boot.SpringApplication的解决方法,文中通过实例代码将解决的办法介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • java实现马踏棋盘的算法

    java实现马踏棋盘的算法

    这篇文章主要为大家详细介绍了java实现马踏棋盘的算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Spring5学习之基础知识总结

    Spring5学习之基础知识总结

    这篇文章主要介绍了Spring5学习之基础知识总结,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • JavaSE中compare、compareTo的区别

    JavaSE中compare、compareTo的区别

    本文主要介绍了JavaSE中compare、compareTo的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • quarzt定时调度任务解析

    quarzt定时调度任务解析

    这篇文章主要介绍了quarzt定时调度任务,具有一定参考价值,需要的朋友可以了解下。
    2017-12-12
  • SpringBoot跨系统单点登陆的实现方法

    SpringBoot跨系统单点登陆的实现方法

    这篇文章主要介绍了SpringBoot跨系统单点登陆的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java批量向PDF文件中添加图像水印实现细节

    Java批量向PDF文件中添加图像水印实现细节

    这篇文章主要为大家介绍了Java批量向PDF文件中添加图像水印实现细节,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • mybatis-plus 如何判断参数是否为空并作为查询条件

    mybatis-plus 如何判断参数是否为空并作为查询条件

    这篇文章主要介绍了mybatis-plus 如何判断参数是否为空并作为查询条件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Spring核心容器之BeanDefinition解析

    Spring核心容器之BeanDefinition解析

    这篇文章主要介绍了Spring核心容器之BeanDefinition解析,Spring 将管理的对象称之为 Bean,容器会先实例化 Bean,然后自动注入,实例化的过程就需要依赖 BeanDefinition,需要的朋友可以参考下
    2023-11-11
  • 使用Spring自身提供的地址匹配工具匹配URL操作

    使用Spring自身提供的地址匹配工具匹配URL操作

    这篇文章主要介绍了使用Spring自身提供的地址匹配工具匹配URL操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论