mybatis批量插入方案

例子

mybatis批量插入,是拼成一个一次提交还是,多次提交。代码如下

<insert id="addEmpsBatch">
 INSERT INTO emp(ename,gender,email,did)
 VALUES
 <foreach collection="emps" item="emp" separator=",">
 (#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
 </foreach>
</insert>

在使用 MyBatis 进行批量插入时,拼成一个 SQL 语句一次性提交 的方式通常比 多次提交 更高效。你的代码示例正是通过 <foreach> 标签将多条插入语句拼接成一个 SQL 语句,然后一次性提交到数据库执行。这种方式减少了与数据库的交互次数,能够显著提升性能。


1. 代码分析

你的代码如下:

xml

复制

<insert id="addEmpsBatch">
    INSERT INTO emp(ename, gender, email, did)
    VALUES
    <foreach collection="emps" item="emp" separator=",">
        (#{emp.eName}, #{emp.gender}, #{emp.email}, #{emp.dept.id})
    </foreach>
</insert>

运行 HTML

  • <foreach> 标签:用于遍历集合 emps,生成多条 VALUES 子句。

  • separator=",":将每条 VALUES 子句用逗号分隔,最终拼接成一个完整的 SQL 语句。

生成的 SQL 语句示例:

sql

复制

INSERT INTO emp(ename, gender, email, did)
VALUES
('Alice', 'F', 'alice@example.com', 1),
('Bob', 'M', 'bob@example.com', 2),
('Charlie', 'M', 'charlie@example.com', 3);

2. 为什么一次性提交更高效?

  1. 减少网络开销

    • 一次性提交只需要与数据库交互一次,而多次提交需要多次交互,增加了网络延迟。

  2. 减少事务开销

    • 如果每次插入都单独提交,会导致多次事务提交,增加数据库的事务管理开销。

  3. 数据库优化

    • 数据库对批量插入有优化机制,一次性插入多条数据的性能通常比多次插入更高。


3. 注意事项

虽然一次性提交性能更高,但在某些场景下需要注意以下问题:

1. SQL 长度限制
  • 数据库对单条 SQL 语句的长度有限制(如 MySQL 的 max_allowed_packet)。

  • 如果批量插入的数据量过大,可能会导致 SQL 语句超长,执行失败。

  • 解决方案

    • 将数据分成多个批次,每批次插入一定数量的数据。

2. 事务管理
  • 如果批量插入过程中某条数据插入失败,默认情况下整个批量插入会回滚。

  • 解决方案

    • 如果需要部分成功,可以在代码中捕获异常并处理。

3. 数据库性能
  • 如果一次性插入的数据量过大,可能会导致数据库锁表或性能下降。

  • 解决方案

    • 根据数据库性能调整每批次插入的数据量。


4. 改进方案:分批次插入

为了避免 SQL 长度限制和数据库性能问题,可以将数据分批次插入。以下是改进后的代码:

Java 代码

java

复制

public void addEmpsBatch(List<Emp> emps) {
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    try {
        for (int i = 0; i < emps.size(); i++) {
            mapper.addEmp(emps.get(i));
            if (i % 1000 == 0 || i == emps.size() - 1) {
                // 每1000条提交一次
                sqlSession.commit();
                sqlSession.clearCache(); // 清空缓存,防止内存溢出
            }
        }
    } catch (Exception e) {
        sqlSession.rollback();
        throw e;
    } finally {
        sqlSession.close();
    }
}
MyBatis Mapper

xml

复制

<insert id="addEmp">
    INSERT INTO emp(ename, gender, email, did)
    VALUES (#{eName}, #{gender}, #{email}, #{dept.id})
</insert>

运行 HTML


5. 性能对比

方式优点缺点适用场景
一次性提交性能高,减少网络和事务开销SQL 长度限制,可能锁表数据量较小,性能要求高
分批次提交避免 SQL 长度限制,减少锁表风险性能略低于一次性提交数据量较大
逐条提交实现简单性能差,网络和事务开销大不推荐

6. 总结

  • 你的代码通过 <foreach> 标签实现了一次性批量插入,性能较高,适合数据量较小的场景。

  • 如果数据量较大,建议采用 分批次插入 的方式,避免 SQL 长度限制和数据库性能问题。

  • 在实际开发中,需要根据数据量和数据库性能选择合适的批量插入方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值