欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解MyBatis如何在大數(shù)據(jù)量下使用流式查詢進(jìn)行數(shù)據(jù)同步

 更新時間:2023年05月30日 10:56:01   作者:知北游z  
通常的數(shù)據(jù)同步中,如果數(shù)據(jù)量比較少的話可以直接全量同步,但是如果數(shù)據(jù)量很大的話,全量同步需要大量的內(nèi)存,所以本文為大家介紹了MyBatis使用流式查詢實現(xiàn)數(shù)據(jù)同步的方法,希望對大家有所幫助

通常的數(shù)據(jù)同步中,如果數(shù)據(jù)量比較少的話可以直接全量同步,默認(rèn)情況下,完整的檢索結(jié)果集會將其存儲在內(nèi)存中。在大多數(shù)情況下,這是最有效的操作方式,并且由于 MySQL 網(wǎng)絡(luò)協(xié)議的設(shè)計,因此更易于實現(xiàn)。但是如果數(shù)據(jù)量很大的話,全量同步需要大量的內(nèi)存,如果內(nèi)存不足的話則可能會導(dǎo)致內(nèi)存溢出。

通常的會采用分頁的方式,一批一批的同步,大體的實現(xiàn)方式如下:

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

這種實現(xiàn)方式雖然可以實現(xiàn)分批同步,但是同步的數(shù)據(jù)必須先提供實現(xiàn)分頁的查詢方式,如果數(shù)據(jù)源是通過復(fù)雜的連表查詢來的,先實現(xiàn)一個分頁查詢更是會增加實現(xiàn)的復(fù)雜度。解決這個問題可以使用一種更為優(yōu)雅的解決方式,即使用流失查詢。

流式查詢,會建立長連接,利用服務(wù)端游標(biāo),每次讀取一條加載到 JVM 內(nèi)存,因此不會導(dǎo)致內(nèi)存溢出。

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> {

    /**
     * 每批處理數(shù)量
     */
    private final static int BATCH_SIZE = 1000;

    /**
     * 緩存數(shù)據(jù)
     */
    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);
        //每到達(dá)BATCH_SIZE 條數(shù)據(jù)處理一次
        if (this.cacheList.size() >= BATCH_SIZE) {
            this.handle();
        }
        total++;
    }


    /**
     * 處理緩存數(shù)據(jù)
     */
    private void handle() {
        try {
            // 具體的處理邏輯 省略
        } finally {
            // 清除處理過的緩存數(shù)據(jù)
            this.cacheList.clear();
        }
    }

    /**
     * 處理最后一批沒有進(jìn)行處理的數(shù)據(jù)
     */
    public int end() {
        this.end();
        return total;
    }
}

使用代碼示例:

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

結(jié)言

流式查詢可以避免 OOM,,數(shù)據(jù)量大可以考慮此方案,其占用內(nèi)存大小取決于批處理大小BATCH_SIZE的設(shè)置。所以BATCH_SIZE應(yīng)該根據(jù)業(yè)務(wù)情況設(shè)置合適的大小。但是這這種方式會占用數(shù)據(jù)庫連接,使用中不會釋放,所以線上針對大數(shù)據(jù)量業(yè)務(wù)用到流式操作,一定要進(jìn)行并發(fā)控制。

到此這篇關(guān)于詳解MyBatis如何在大數(shù)據(jù)量下使用流式查詢進(jìn)行數(shù)據(jù)同步的文章就介紹到這了,更多相關(guān)MyBatis流式查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java如何基于反射獲取對象屬性信息

    Java如何基于反射獲取對象屬性信息

    這篇文章主要介紹了Java如何基于反射獲取對象屬性信息,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • 基于springboot的RestTemplate、okhttp和HttpClient對比分析

    基于springboot的RestTemplate、okhttp和HttpClient對比分析

    這篇文章主要介紹了基于springboot的RestTemplate、okhttp和HttpClient對比分析,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • SpringBoot異常錯誤頁面實現(xiàn)方法介紹

    SpringBoot異常錯誤頁面實現(xiàn)方法介紹

    在項目訪問的時候我們經(jīng)常會發(fā)生錯誤或者頁面找不到,比如:資源找不到404,服務(wù)器500錯誤,默認(rèn)情況下springboot的處理機(jī)制都是去跳轉(zhuǎn)內(nèi)部的錯誤地址:/error 和與之對應(yīng)的一個錯誤頁面
    2022-09-09
  • java抓取鼠標(biāo)事件和鼠標(biāo)滾輪事件示例

    java抓取鼠標(biāo)事件和鼠標(biāo)滾輪事件示例

    這篇文章主要介紹了java抓取鼠標(biāo)事件和鼠標(biāo)滾輪事件示例,需要的朋友可以參考下
    2014-05-05
  • SpringMVC實現(xiàn)文件上傳和下載功能

    SpringMVC實現(xiàn)文件上傳和下載功能

    這篇文章主要為大家詳細(xì)介紹了SpringMVC實現(xiàn)文件上傳和下載功能 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java 在volatile內(nèi)部調(diào)用接口的方法

    Java 在volatile內(nèi)部調(diào)用接口的方法

    在Java中,volatile?關(guān)鍵字通常用于確保變量的可見性和有序性,而不是用來修飾接口或方法調(diào)用的,這篇文章主要介紹了Java 在volatile內(nèi)部調(diào)用接口的方法,需要的朋友可以參考下
    2024-07-07
  • 最新評論