亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MyBatis如何批量插入大量數據

發布時間:2022-01-05 17:28:39 來源:億速云 閱讀:444 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關MyBatis如何批量插入大量數據,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

問題背景:只用MyBatis中foreach進行批量插入數據,一次性插入超過一千條的時候MyBatis開始報錯。項目使用技術:SpringBoot、MyBatis

批量插入碰到的問題:

java.lang.StackOverflowError: null

該問題是由于一次性插入數據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>

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

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

mybatis中ExecutorType的使用

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

插入大量數據的解決方案,使用ExecutorType

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

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

public void insertExcelData(List<User> list) {
    //如果自動提交設置為true,將無法控制提交的條數,改為最后統一提交,可能導致內存溢出
    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) {
        //沒有提交的數據可以回滾
        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循環,但是使用ExecutorType.BACTH就相當于手動提交。這也是我們需要的效果,所以我們在循環里面判斷了,是否到了第400筆,如果到了第400筆就直接提交,然后清空緩存,防止溢出。這樣就有效的實現了批量插入,同時保證溢出問題的不出現

關于“MyBatis如何批量插入大量數據”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

屏南县| 太谷县| 泽库县| 怀仁县| 苏尼特右旗| 陵川县| 且末县| 合川市| 新田县| 元氏县| 都安| 浦北县| 饶河县| 堆龙德庆县| 威远县| 廊坊市| 和平县| 凤翔县| 侯马市| 莒南县| 噶尔县| 上杭县| 永顺县| 苍溪县| 郧西县| 枣阳市| 蛟河市| 繁峙县| 保亭| 祁阳县| 米易县| 汝阳县| 达拉特旗| 灵璧县| 临安市| 阿尔山市| 威宁| 确山县| 玉树县| 建宁县| 江油市|