Mybatis如何批量插入数据?

2年前 (2022) 程序员胖胖胖虎阿
199 0 0

    有一小段时间没有写技术博文了,今天我又来更新啦😊😊😊5月份中间有个小插曲,那就是我在单位打球意外导致脚跟腱受伤,然后住院在家修养了一个多月了,所以小伙伴们在外锻炼时还是时刻注意自身的安全哦!6月份这一个月都是居家办公的状态,庆幸自己是计算机专业的,不然可惨了!😂😂😂
    记录最近工作中遇到的问题以及解决的办法,也就是今天的主题:Mybatis批量插入数据。

✈️数据单条插入

    数据的单条插入,小伙伴应该对此并不陌生了,因为在之前的博文中已经介绍过如何进行基础的增加数据过程,这里不再累赘,如果这部分内容忘记的小伙伴可以参考此条链接:SpringBoot_实现基本增删改查(前后端分离版),中间本人已经描述清楚了!
    不过,随着项目越做越多,深度也越来越来大,基本的插入数据量还是偏小,如果我们项目需要我们一次性插入成百上千的数据呢?单条数据是不够看啦,问题引入进来,如何插入批量数据呢?

🚀数据批量插入

    单条插入的速度我们如果用飞机的速度描述,那么批量插入的速度就是火箭。为何这样子说呢?因为本人亲身经历过,在这之前没有仔细了解过批量插入,单条的速度就能满足我当前接手项目中的需求,一般的业务批量插入的情况少嘛!但是6月份需要做的事情中当前数据暂无,大量的数据只能通过我在代码层面进行模拟生成,涉及到每年每月每天每小时的数据,数据量可想而知,一条条插入到数据库中来,即便是我们加上了时间索引,速度还是想蜗牛爬似的。

    话不多说,直接上批量插入的用法:

🔔 ① Mapper接口层插入集合

    批量的意思就是多条数据一并插入于数据库之中,那么我们传入到数据库肯定就是以集合传值。批量插入数据时不能像单条数据一样插入一个对象了,如下例所示为单条模拟增加和多条模拟增加数据的区分:

    /** 单条模拟增加数据 */
    public int insertSimulationData(TunnelDetectData tunnelDetectData);

    /** 多条模拟增加数据 */
    public int insertSimulationDataList(List<TunnelDetectData> tunnelDetectDataList);

🔔 ② Mybatis层批量foreach插入

    以下将通过单条数据插入和批量插入做对比分析,代码实例如下:
(1)单条数据插入:
    单条的数据插入注意因为id是自增的,所以加入<selectKey></selectKey>等让主键id自增,数据库层面也要将主键id设置为自动新增,否则程序会报错!

<insert id="insertSimulationData" parameterType="com.yh.domain.TunnelDetectData" keyProperty="id" useGeneratedKeys="true">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
            SELECT LAST_INSERT_ID() as id
        </selectKey>
        insert into tunnel_detect_data
        <trim prefix="(" suffix=")" suffixOverrides="," >
            <if test="id != null" >
                id,
            </if>
            <if test="stakeNo != null" >
                stake_no,
            </if>
            <if test="deviceNo != null" >
                device_no,
            </if>
            <if test="deviceName != null" >
                device_name,
            </if>
            <if test="tunnelName != null" >
                tunnel_name,
            </if>
            <if test="direction != null" >
                direction,
            </if>
            <if test="commandType != null" >
                command_type,
            </if>
            <if test="currentData != null" >
                current_data,
            </if>
            <if test="createTime != null" >
                create_time,
            </if>
            <if test="acquisitionTime != null" >
                acquisition_time,
            </if>
            <if test="loadTime != null" >
                load_time,
            </if>
            <if test="remark1 != null" >
                remark1,
            </if>
            <if test="remark2 != null" >
                remark2,
            </if>
            <if test="remark3 != null" >
                remark3,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
            <if test="id != null" >
                #{id,jdbcType=BIGINT},
            </if>
            <if test="stakeNo != null" >
                #{stakeNo,jdbcType=VARCHAR},
            </if>
            <if test="deviceNo != null" >
                #{deviceNo,jdbcType=VARCHAR},
            </if>
            <if test="deviceName != null" >
                #{deviceName,jdbcType=VARCHAR},
            </if>
            <if test="tunnelName != null" >
                #{tunnelName,jdbcType=VARCHAR},
            </if>
            <if test="direction != null" >
                #{direction,jdbcType=INTEGER},
            </if>
            <if test="commandType != null" >
                #{commandType,jdbcType=VARCHAR},
            </if>
            <if test="currentData != null" >
                #{currentData,jdbcType=VARCHAR},
            </if>
            <if test="createTime != null" >
                #{createTime,jdbcType=TIMESTAMP},
            </if>
            <if test="acquisitionTime != null" >
                #{acquisitionTime,jdbcType=TIMESTAMP},
            </if>
            <if test="loadTime != null" >
                #{loadTime,jdbcType=TIMESTAMP},
            </if>
            <if test="remark1 != null" >
                #{remark1,jdbcType=VARCHAR},
            </if>
            <if test="remark2 != null" >
                #{remark2,jdbcType=VARCHAR},
            </if>
            <if test="remark3 != null" >
                #{remark3,jdbcType=VARCHAR},
            </if>
        </trim>
    </insert>

(2)多条数据批量插入:
    多条数据批量插入的写法有所不同,以集合的形式插入,需要借助<foreach></foreach>,代码实例如下所示:
注意<foreach></foreach>键值对中各个参数的写法:
    📣collection:为必填值,值为要迭代循环的集合类型,情况有多种:
    入参是List类型的时候,collection属性值为list,这里是否可换其他自定义值,我还未亲测过,好像有大佬们换过吧?😜
    入参是Map类型的时候,collection 属性值为map的key值。
    📣item:每一个元素进行迭代时的别名,可自行定义,省事就直接用“item”即可。
    📣index:索引的属性名,在集合数组情况下值为当前索引值,当迭代对象是map时,这个值是map的key。
    📣separator: 每次循环的分隔符。

<insert id="insertSimulationDataList" >
        insert into tunnel_detect_data
          (stake_no, device_no,
          device_name, tunnel_name, direction,
          command_type, current_data, create_time,
          acquisition_time, load_time, remark1,
          remark2, remark3)
        values
        <foreach collection="list" separator="," index="index" item="item">
            (#{item.stakeNo},
            #{item.deviceNo},
            #{item.deviceName},
            #{item.tunnelName},
            #{item.direction},
            #{item.commandType},
            #{item.currentData},
            #{item.createTime},
            #{item.acquisitionTime},
            #{item.loadTime},
            #{item.remark1},
            #{item.remark2},
            #{item.remark3})
        </foreach>
    </insert>

    路过的小伙伴,如果博文有帮助到你解决问题,可以点赞+收藏+关注一波呀~本人将会持续更新相关学习博文,感谢您的支持哦!!!芜湖起飞✈️✈️✈️
Mybatis如何批量插入数据?

版权声明:程序员胖胖胖虎阿 发表于 2022年9月22日 上午8:16。
转载请注明:Mybatis如何批量插入数据? | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...