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

MyBatis批量插入大量數(shù)據(jù)(1w以上)

 更新時(shí)間:2022年01月05日 15:32:05   作者:xlecho  
MyBatis進(jìn)行批量插入數(shù)時(shí),一次性插入超過一千條的時(shí)候MyBatis開始報(bào)錯(cuò),本文主要介紹了MyBatis批量插入大量數(shù)據(jù)的解決方法,感興趣的可以了解一下

問題背景:只用MyBatis中foreach進(jìn)行批量插入數(shù)據(jù),一次性插入超過一千條的時(shí)候MyBatis開始報(bào)錯(cuò)。項(xiàng)目使用技術(shù):SpringBoot、MyBatis

批量插入碰到的問題:

java.lang.StackOverflowError: null

該問題是由于一次性插入數(shù)據(jù)1w條引起的,具體插入代碼如下:

userDao.batchInsert(list);

<insert id="batchInsert" parameterType="java.util.List">
? ? INSERT INTO USER
? ? <trim prefix="(" suffix=")" suffixOverrides=",">
? ? ? ? ID, AGE, NAME, EMAIL
? ? </trim>
? ? SELECT A.*
? ? FROM
? ? (<foreach collection="list" index="index" item="item" separator="UNION ALL">
? ? SELECT
? ? sys_guid(), #{user.age}, #{user.name}, #{user.email}
? ? FROM dual
</foreach>) A
</insert>

以上的插入代碼其實(shí)也是一種批量插入的方式,但是他的靈界點(diǎn)并不高,插入數(shù)據(jù)過多的時(shí)候,可能需要我們使用代碼在一次分批。當(dāng)然如果插入數(shù)據(jù)不超過5000的時(shí)候可以直接這么使用

插入1w條數(shù)據(jù),發(fā)現(xiàn)出現(xiàn)錯(cuò)誤,原因是數(shù)據(jù)量過大,棧內(nèi)存溢出了。mybatis中直接使用foreach插入數(shù)據(jù),就相當(dāng)于將所有的sql預(yù)先拼接到一起,然后一起提交。這本身就是一種批量插入的處理方案,但是達(dá)不到我們要求。主要是插入有上限。如果需要更多的數(shù)據(jù)導(dǎo)入,我們需要更換一種方式來解決這個(gè)問題,mybatis中ExecutorType的使用。

mybatis中ExecutorType的使用

Mybatis內(nèi)置的ExecutorType有3種,SIMPLE、REUSE、BATCH; 默認(rèn)的是simple,該模式下它為每個(gè)語句的執(zhí)行創(chuàng)建一個(gè)新的預(yù)處理語句,單條提交sql;而batch模式重復(fù)使用已經(jīng)預(yù)處理的語句,并且批量執(zhí)行所有更新語句,顯然batch性能將更優(yōu);但batch模式也有自己的問題,比如在Insert操作時(shí),在事務(wù)沒有提交之前,是沒有辦法獲取到自增的id,這在某型情形下是不符合業(yè)務(wù)要求的;

插入大量數(shù)據(jù)的解決方案,使用ExecutorType

為了能夠高效,并且解決上述問題,我們使用ExecutorType,并分批插入。代碼如下:

//我們使用的是springboot,sqlSessionTemplate是可以自己注入的
@Autowired
private SqlSessionTemplate sqlSessionTemplate;

public void insertExcelData(List<User> list) {
? ? //如果自動提交設(shè)置為true,將無法控制提交的條數(shù),改為最后統(tǒng)一提交,可能導(dǎo)致內(nèi)存溢出
? ? SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
? ? //不自動提交
? ? try {
? ? ? ? UserDao userDao = session.getMapper(UserDao.class);
? ? ? ? for (int i = 0; i < list.size(); i++) {
? ? ? ? ? ? userDao.insert(list.get(i));
? ? ? ? ? ? if (i % 400 == 0 || i == list.size() - 1) {
? ? ? ? ? ? ? ? //手動每400條提交一次,提交后無法回滾
? ? ? ? ? ? ? ? session.commit();
? ? ? ? ? ? ? ? //清理緩存,防止溢出
? ? ? ? ? ? ? ? session.clearCache();
? ? ? ? ? ? }
? ? ? ? }
? ? } catch (Exception e) {
? ? ? ? //沒有提交的數(shù)據(jù)可以回滾
? ? ? ? session.rollback();
? ? } finally {
? ? ? ? session.close();
? ? }
}

userDao.insert(User user);

<insert id="insert" parameterType="com.echo.UserPo">
? ? insert into USER
? ? (id
? ? <if test="age != null">
? ? ? ? ,age
? ? </if>
? ? <if test="name != null">
? ? ? ? ,name
? ? </if>
? ? <if test="email != null">
? ? ? ? ,email
? ? </if>
? ? )
? ? values (
? ? sys_guid()
? ? <if test="age != null">
? ? ? ? ,#{age}
? ? </if>
? ? <if test="name != null">
? ? ? ? ,#{name}
? ? </if>
? ? <if test="email != null">
? ? ? ? ,#{email}
? ? </if>)
</insert>

這里采用的是單條插入,直接使用for循環(huán),但是使用ExecutorType.BACTH就相當(dāng)于手動提交。這也是我們需要的效果,所以我們在循環(huán)里面判斷了,是否到了第400筆,如果到了第400筆就直接提交,然后清空緩存,防止溢出。這樣就有效的實(shí)現(xiàn)了批量插入,同時(shí)保證溢出問題的不出現(xiàn)

到此這篇關(guān)于MyBatis批量插入大量數(shù)據(jù)(1w以上)的文章就介紹到這了,更多相關(guān)MyBatis批量插入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java序列化機(jī)制詳解

    Java序列化機(jī)制詳解

    Java 序列化機(jī)制是一種將對象轉(zhuǎn)換為字節(jié)流的過程,以便在網(wǎng)絡(luò)上傳輸或保存到文件中,并能在需要時(shí)將字節(jié)流還原為對象,這一機(jī)制通過實(shí)現(xiàn) java.io.Serializable 接口來實(shí)現(xiàn),同時(shí)涉及到一些關(guān)鍵概念和注意事項(xiàng),需要的朋友可以參考下
    2023-12-12
  • 解決rocketmq-client查詢手動發(fā)送消息異常問題

    解決rocketmq-client查詢手動發(fā)送消息異常問題

    這篇文章主要介紹了解決rocketmq-client查詢手動發(fā)送消息異常問題,具有很好的參考價(jià)值,希望對大家大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java中獲取List中最后一個(gè)元素的三種方法

    Java中獲取List中最后一個(gè)元素的三種方法

    在Java編程中我們經(jīng)常需要獲取一個(gè)List集合中的最后一個(gè)元素,這篇文章主要給大家介紹了關(guān)于Java中獲取List中最后一個(gè)元素的三種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 將一個(gè)數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法

    將一個(gè)數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法

    下面小編就為大家?guī)硪黄獙⒁粋€(gè)數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-11-11
  • Java中前端傳參含有“+”“=”等特殊字符處理方式

    Java中前端傳參含有“+”“=”等特殊字符處理方式

    這篇文章主要介紹了Java中前端傳參含有“+”“=”等特殊字符處理,比如“+”如果不經(jīng)過處理,傳到Java后臺之后,就變成空格了,“=”就直接沒了,本文對這一問題給大家詳細(xì)講解,需要的朋友可以參考下
    2023-10-10
  • 基于java語言實(shí)現(xiàn)快遞系統(tǒng)

    基于java語言實(shí)現(xiàn)快遞系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于java語言實(shí)現(xiàn)快遞系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java中volatile關(guān)鍵字的作用是什么舉例詳解

    Java中volatile關(guān)鍵字的作用是什么舉例詳解

    這篇文章主要介紹了Java中volatile關(guān)鍵字的作用是什么的相關(guān)資料,volatile關(guān)鍵字在Java中用于修飾變量,提供可見性和禁止指令重排的特性,但不保證原子性,它通過內(nèi)存屏障實(shí)現(xiàn)這些特性,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • IntelliJ IDEA下載GitHub私有倉庫到本地的方法(新版)

    IntelliJ IDEA下載GitHub私有倉庫到本地的方法(新版)

    這篇文章主要介紹了IntelliJ IDEA下載GitHub私有倉庫到本地(新版),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 深度解析Spring?Filter方法示例

    深度解析Spring?Filter方法示例

    這篇文章主要為大家介紹了深度解析Spring?Filter用法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 關(guān)于mybatis一對一查詢一對多查詢遇到的問題

    關(guān)于mybatis一對一查詢一對多查詢遇到的問題

    這篇文章主要介紹了關(guān)于mybatis一對一查詢,一對多查詢遇到的錯(cuò)誤,接下來是對文章進(jìn)行操作,要求查詢?nèi)课恼?,并關(guān)聯(lián)查詢作者,文章標(biāo)簽,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05

最新評論

盈江县| 五常市| 桦南县| 西安市| 康平县| 油尖旺区| 宜阳县| 澄城县| 石楼县| 辽源市| 郴州市| 柳河县| 鹤壁市| 海盐县| 潼南县| 开江县| 马山县| 贡觉县| 梁平县| 龙南县| 沈阳市| 通江县| 张家界市| 彭阳县| 扶风县| 武城县| 齐河县| 合阳县| 辽宁省| 内乡县| 南溪县| 大关县| 常德市| 阜平县| 大足县| 玛沁县| 南雄市| 灵寿县| 邵阳县| 会东县| 东乡族自治县|