DAMO开发者矩阵 MyBatis批量插入几千条数据

MyBatis批量插入几千条数据

在 MyBatis 中批量插入几千条数据时,通常有以下几种方式可以提高性能,避免一次性插入大量数据导致性能问题。常见的批量插入方法有通过 <foreach> 标签、批量执行 ExecutorType.BATCH 和自定义批量插入方法。方法 1:使用 <foreach> 标签进行批量插入MyBatis...

在 MyBatis 中批量插入几千条数据时,通常有以下几种方式可以提高性能,避免一次性插入大量数据导致性能问题。常见的批量插入方法有通过 <foreach> 标签、批量执行 ExecutorType.BATCH 和自定义批量插入方法。

方法 1:使用 <foreach> 标签进行批量插入

MyBatis 提供了 <foreach> 标签,可以用来执行批量插入操作。下面是一个批量插入的例子:

1. SQL 映射文件中的 <insert> 配置
<insert id="batchInsert" parameterType="java.util.List">
    INSERT INTO your_table (column1, column2, column3)
    VALUES 
    <foreach collection="list" item="item" index="index" separator=",">
        (#{item.column1}, #{item.column2}, #{item.column3})
    </foreach>
</insert>
  • collection="list":指向要插入的数据集合,通常是一个 List。
  • item="item":指代集合中的每一个元素。
  • separator=",":指定每一条插入记录之间用逗号分隔。
2. Mapper 接口中的方法
public interface YourMapper {
    void batchInsert(List<YourEntity> entities);
}
3. 调用 Mapper 方法进行批量插入
List<YourEntity> entities = new ArrayList<>();
// 填充实体列表
yourMapper.batchInsert(entities);
优点:
  • 简单明了,容易理解。
  • 适合数据量较小(几百条数据)。
限制:
  • 如果数据量非常大(几千条或更多),可能会导致 SQL 语句过长,超出数据库的查询长度限制。

方法 2:使用 ExecutorType.BATCH 执行批量插入

ExecutorType.BATCH 是 MyBatis 提供的批量执行功能,它能够将多条 SQL 语句打包成一个批次一起执行,能够有效提高性能。

1. 配置 SqlSessionFactory

首先,你需要配置 SqlSessionFactory,并设置 ExecutorType.BATCH

SqlSessionFactory sqlSessionFactory = ...; // 获取 SqlSessionFactory
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false); // 使用批量执行模式
2. Mapper 接口和 XML 配置
<insert id="batchInsert" parameterType="java.util.List">
    INSERT INTO your_table (column1, column2, column3)
    VALUES 
    <foreach collection="list" item="item" index="index" separator=",">
        (#{item.column1}, #{item.column2}, #{item.column3})
    </foreach>
</insert>
3. 调用批量插入方法
List<YourEntity> entities = new ArrayList<>();
// 填充实体列表
YourMapper mapper = session.getMapper(YourMapper.class);
for (int i = 0; i < entities.size(); i++) {
    mapper.batchInsert(entities.subList(i, Math.min(i + batchSize, entities.size())));
    if (i % batchSize == 0 || i == entities.size() - 1) {
        session.commit();
    }
}
session.close();
4. 调整批次大小
  • 批次大小(batchSize)根据具体情况进行调整,通常大小在 500 到 1000 之间。
  • 批次大小过大可能会导致内存占用过高,过小则可能没有充分发挥批量插入的优势。

方法 3:使用自定义批量插入逻辑

如果需要更细粒度的控制,可以自定义批量插入的逻辑。例如,使用 MyBatis 提供的 SqlSession 对象的 insert() 方法多次调用插入语句,并在合适时机调用 commit()

示例代码:
public void batchInsert(List<YourEntity> entities) {
    SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
    try {
        YourMapper mapper = session.getMapper(YourMapper.class);
        int batchSize = 500;
        for (int i = 0; i < entities.size(); i++) {
            mapper.batchInsert(Collections.singletonList(entities.get(i)));
            // 每隔 batchSize 条提交一次
            if (i % batchSize == 0 || i == entities.size() - 1) {
                session.commit();
            }
        }
    } finally {
        session.close();
    }
}

方法 4:批量插入时避免 flush()commit()

在批量插入的过程中,如果每插入一定数量的数据就调用 flush()commit(),可能会影响性能。在批量插入时,可以将这两个操作的频率降低,控制在一个合理的范围内。

其他优化建议

  1. 数据库配置:确保数据库表的索引配置合理,避免索引过多或不必要的索引干扰插入性能。
  2. 连接池配置:如果应用程序使用了数据库连接池,确保连接池的配置足够高效。
  3. 事务控制:确保事务提交时机正确,避免频繁的提交操作。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐

  • 浏览量 643
  • 收藏 0
  • 0

所有评论(0)

查看更多评论 
已为社区贡献9条内容