MySQL分批插入/更新數(shù)據(jù)方式
MySQL分批插入/更新數(shù)據(jù)
在我們的日常開(kāi)發(fā)中,經(jīng)常會(huì)使用到批量insert/update的語(yǔ)句來(lái)實(shí)現(xiàn)相關(guān)的業(yè)務(wù)功能。而如果數(shù)據(jù)量比較大的話,會(huì)導(dǎo)致sql語(yǔ)句更新失敗、拋出異常的情況出現(xiàn)。
這個(gè)時(shí)候我們可以批量執(zhí)行sql語(yǔ)句,一批一批的執(zhí)行。
比如說(shuō)現(xiàn)在有一個(gè)需要批量修改商品的方法
我們可以這么改造:
public void batchUpdateById(List<Product> productList) {
if (CollectionUtils.isEmpty(productList)) {
return;
}
if (productList.size() > CommonUtils.BATCH_NUMBER) {
int sizeNum = productList.size();
int startNum = 0;
int endNum = CommonUtils.BATCH_NUMBER - 1;
while (startNum < endNum) {
productMapper.batchUpdateById(productList.subList(startNum, endNum));
startNum += CommonUtils.BATCH_NUMBER - 1;
endNum += CommonUtils.BATCH_NUMBER - 1;
if (endNum > sizeNum - 1) {
endNum = sizeNum;
}
}
} else {
productMapper.batchUpdateById(productList);
}
}上面BATCH_NUMBER的值是50,意味著當(dāng)修改商品的數(shù)量大于50的時(shí)候,會(huì)以50個(gè)數(shù)據(jù)為一批,分批的執(zhí)行;而如果修改商品的數(shù)量不大于50的時(shí)候,就直接一次執(zhí)行就夠了。
上面是我們自己手寫的分批代碼,而如果每個(gè)方法都這么寫,也未免太過(guò)于繁瑣了。
這個(gè)時(shí)候我們就可以使用guava庫(kù)中關(guān)于集合的partition分組方法來(lái)進(jìn)行簡(jiǎn)化:
@Override
public void batchUpdateById(List<GoodsSkuBO> list) {
if (CollectionUtils.isEmpty(list)) {
return;
}
List<MerchantGoodsSkuDO> merchantGoodsSkuDOS = GoodsAnotherSkuConvertor.INSTANCE.goodsSkuBO2MerchantDOList(list);
List<List<MerchantGoodsSkuDO>> groupMerchantGoodsSkuDOS = Lists.partition(merchantGoodsSkuDOS, CommonUtils.BATCH_NUMBER);
groupMerchantGoodsSkuDOS.forEach(goodsSkuMasterMapper::batchUpdateById);
}由上可以看到,代碼簡(jiǎn)化了很多
(上面的goodsSkuBO2MerchantDOList方法只是將BO轉(zhuǎn)成DO,和分組邏輯沒(méi)有關(guān)系)。
而對(duì)于批量查詢的方法,我們也可以使用partition方法進(jìn)行分組查詢,防止in條件拼接太多的數(shù)據(jù)導(dǎo)致sql報(bào)錯(cuò)的情況出現(xiàn):
@Override
public List<GoodsSkuBO> listBySpuIdsSimple(List<Long> spuIds) {
if (CollectionUtils.isEmpty(spuIds)) {
return Collections.emptyList();
}
//去重
spuIds = spuIds.stream().distinct().collect(Collectors.toList());
List<List<Long>> groupSpuIds = Lists.partition(spuIds, CommonUtils.BATCH_NUMBER);
List<MerchantGoodsSkuDO> spuIdList = groupSpuIds.stream().map(goodsSkuMasterMapper::listBySpuIds).flatMap(Collection::stream)
.collect(Collectors.toList());
return GoodsAnotherSkuConvertor.INSTANCE.merchantGoodsSkuDO2GoodsSkuBOList(spuIdList);
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
為什么代碼規(guī)范要求SQL語(yǔ)句不要過(guò)多的join
SQL中的join可以根據(jù)某些條件把指定的表給結(jié)合起來(lái)并將數(shù)據(jù)返回給客戶端,那么在項(xiàng)目開(kāi)發(fā)中如果需要使用join語(yǔ)句,如何優(yōu)化提升性能?本文就來(lái)詳細(xì)的介紹一下2021-06-06
win2003服務(wù)器下配置 MySQL 群集(Cluster)的方法
MySQL 群集是 MySQL 適合于分布式計(jì)算環(huán)境的高可用、高冗余版本。它采用了 NDB Cluster 存儲(chǔ)引擎,允許在 1 個(gè)群集中運(yùn)行多個(gè) MySQL 服務(wù)器。2010-12-12
mysql 悲觀鎖與樂(lè)觀鎖的理解及應(yīng)用分析
這篇文章主要介紹了mysql 悲觀鎖與樂(lè)觀鎖的理解及應(yīng)用,結(jié)合實(shí)例形式分析了MySQL數(shù)據(jù)庫(kù)悲觀鎖與樂(lè)觀鎖相關(guān)概念、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-02-02
MySql優(yōu)化之InnoDB,4GB內(nèi)存,多查詢的my.ini中文配置方案詳解
本文是一個(gè)針對(duì) 4G 內(nèi)存系統(tǒng)(主要運(yùn)行只有 InnoDB 表的 MySQL 并使用幾個(gè)連接數(shù)執(zhí)行復(fù)雜的查詢)的MySQL配置文件方案2018-03-03
MySQL數(shù)據(jù)庫(kù)中CAST與CONVERT函數(shù)實(shí)現(xiàn)類型轉(zhuǎn)換的講解
今天小編就為大家分享一篇關(guān)于MySQL數(shù)據(jù)庫(kù)中CAST與CONVERT函數(shù)實(shí)現(xiàn)類型轉(zhuǎn)換的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
MySQL事務(wù)處理與應(yīng)用簡(jiǎn)析
事務(wù)處理在各種管理系統(tǒng)中都有著廣泛的應(yīng)用,比如人員管理系統(tǒng),很多同步數(shù)據(jù)庫(kù)操作大都需要用到事務(wù)處理。這篇文章主要介紹了MySQL事務(wù)處理,需要的朋友可以參考下2014-06-06

