最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

通常的會(huì)采用分頁(yè)的方式,一批一批的同步,大體的實(shí)現(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 ++;
}

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

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

MyBatis 如何使用流式查詢:

配置mapper.xml文件:

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

自定義一個(gè)ResultHandler:

User是自定義的同步對(duì)象的實(shí)體對(duì)象,需要自己定義

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 {
            // 清除處理過(guò)的緩存數(shù)據(jù)
            this.cacheList.clear();
        }
    }

    /**
     * 處理最后一批沒(méi)有進(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è)置合適的大小。但是這這種方式會(huì)占用數(shù)據(jù)庫(kù)連接,使用中不會(huì)釋放,所以線上針對(duì)大數(shù)據(jù)量業(yè)務(wù)用到流式操作,一定要進(jìn)行并發(fā)控制。

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

相關(guān)文章

最新評(píng)論

兴安县| 彭州市| 靖安县| 湖南省| 寻甸| 蓝山县| 香港| 达孜县| 恭城| 武川县| 蒙阴县| 宜城市| 神木县| 峨边| 木里| 元江| 临汾市| 长宁区| 庆元县| 思茅市| 曲麻莱县| 卢氏县| 泗水县| 德惠市| 喀喇沁旗| 阳原县| 五家渠市| 陈巴尔虎旗| 九江县| 太原市| 富源县| 韩城市| 饶平县| 龙江县| 昭通市| 高青县| 奎屯市| 南溪县| 芮城县| 临高县| 灵石县|