mybatis的批量插入

看网上知道了有大概三种方法

1.很笨的方法,一条一条地插入,面对大数据地时候效率及其低下!

insert into t_user values (?, ?, ?, ?, ?)

/**
* 第一种方案,用 for语句循环插入 10万 条数据
*/
@GetMapping("/test1")
public String test1(int count) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    for (int i = 0; i < count; i++) {
        User user = new User();
        user.setName("方案1测试" + i);
        user.setGender("男");
        user.setUsername("方案1测试");
        user.setPassword("方案1测试");
        user.setRemark("方案1测试");
        userService.saveInfo(user);
    }
    stopWatch.stop();
    System.out.println("第一种方案,用 for语句循环插入耗时:" + stopWatch.getTotalTimeMillis());
    return "操作完成";
}

优势:JDBC 中的 PreparedStatement 有预编译功能,预编译之后会缓存起来。

之后SQL执行会比较快,且 JDBC可以开启批处理,这个批处理执行非常给力。

劣势:这种方式插入大量数据时,效率非常底下,不推荐。很多时候我们的 SQL 服务器和应用服务器可能并不是同一台,所以必须要考虑网络 IO。

如果网络 IO 比较费时间的话,那么可能会拖慢 SQL 执行的速度。

2.利用mybatis的foreach来实现循环插入

insert into t_user values (?, ?, ?, ?, ?) , (?, ?, ?, ?, ?) , (?, ?, ?, ?, ?)

/**
* 第二种方案,利用mybatis的foreach来实现循环插入 10万 条数据
*/
@GetMapping("/test2")
public String test2(int count) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    List<User> list = new ArrayList<>();
    for (int i = 0; i < count; i++) {
        User user = new User();
        user.setName("方案2测试" + i);
        user.setGender("男");
        user.setUsername("方案2测试");
        user.setPassword("方案2测试");
        user.setRemark("方案2测试");
        list.add(user);
    }
    userService.saveList(list);
    stopWatch.stop();
    System.out.println("第二种方案,利用mybatis的foreach来实现循环插入耗时:" + stopWatch.getTotalTimeMillis());
    return "操作完成";
}
<insert id="saveList" parameterType="list">
    insert into t_user values
    <foreach collection="list" item="item" separator=",">
        (#{item.name}, #{item.gender}, #{item.username}, #{item.password}, #{item.remark})
    </foreach>
</insert>

优势:不用频繁访问数据库,一条sql搞定,效率比较高。

劣势:一当数据量太大时,会出现拼接的sql语句超长而执行失败,所以当数据量太大时,也不推荐。

二是 SQL 太长了,甚至可能需要分片后批量处理。

三是无法充分发挥 PreparedStatement 预编译的优势,SQL 要重新解析且无法复用

3.使用sqlSessionFactory实现批量插入

@Resource
private SqlSessionFactory sqlSessionFactory;
// 关闭session的自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
try {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    list.stream().forEach(user -> userMapper.saveInfo(user));
    // 提交数据
    sqlSession.commit();
    sqlSession.rollback();
} catch (Exception e) {
    sqlSession.rollback();
} finally {
    sqlSession.close();
}

优势:这种方式可以说是集第一种和第二种方式的优点于一身,既可以提高运行效率,又可以保证大数据量时执行成功,大数据量时推荐使用这种方式。

### MyBatis 批量插入的实现方式及示例代码 在 MyBatis批量插入数据可以通过多种方式实现,以下为常见的几种方法及其示例代码。 #### 方法 1:使用 `<foreach>` 标签进行批量插入 通过 `<foreach>` 标签可以在 SQL 映射文件中直接实现批量插入。以下是具体的实现步骤和代码示例: **Mapper 接口定义** ```java public interface BatchInsertMapper { int batchInsertProductCategory(List<ProductCategory> productCategoryList); } ``` **XML 文件配置** ```xml <insert id="batchInsertProductCategory" parameterType="java.util.List"> INSERT INTO tb_product_category(product_category_name, priority, shop_id) VALUES <foreach collection="list" item="productCategory" index="index" separator=","> (#{productCategory.productCategoryName}, #{productCategory.priority}, #{productCategory.shopId}) </foreach> </insert> ``` 上述代码中,`<foreach>` 标签用于遍历传入的列表参数,并将每个元素映射到 SQL 的 `VALUES` 部分[^3]。 #### 方法 2:使用 ExecutorType.BATCH 批量执行 通过设置 `SqlSession` 的执行器类型为 `ExecutorType.BATCH`,可以显著提高大批量数据插入的性能。以下是具体实现代码: **Java 应用层代码** ```java public long mybatisBatchInsert(int amount) { SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false); long beginTime = System.currentTimeMillis(); try { BatchInsertMapper insertMapper = session.getMapper(BatchInsertMapper.class); List<BatchData> dataList = buildDataList(amount); for (BatchData data : dataList) { insertMapper.insertData(data); } session.commit(); session.clearCache(); } catch (Exception e) { session.rollback(); } finally { session.close(); } return System.currentTimeMillis() - beginTime; } ``` 在此代码中,`ExecutorType.BATCH` 模式允许 MyBatis 在一次会话中累积多个插入操作,最终通过 `session.commit()` 提交所有更改[^2]。 #### 方法 3:自定义批量插入逻辑 如果需要更高的灵活性,可以结合 JDBC 的批量处理机制与 MyBatis 的映射功能。以下是一个简单的示例: **Mapper 接口定义** ```java public interface CustomBatchInsertMapper { void batchInsert(@Param("dataList") List<CustomData> dataList); } ``` **XML 文件配置** ```xml <insert id="batchInsert"> INSERT INTO custom_table(field1, field2) VALUES <foreach collection="dataList" item="item" separator=","> (#{item.field1}, #{item.field2}) </foreach> </insert> ``` **Java 调用代码** ```java public void customBatchInsert(List<CustomData> dataList) { SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false); try { CustomBatchInsertMapper mapper = session.getMapper(CustomBatchInsertMapper.class); mapper.batchInsert(dataList); session.commit(); } catch (Exception e) { session.rollback(); } finally { session.close(); } } ``` 以上三种方法均可根据实际需求选择使用,其中 `<foreach>` 标签适用于简单的批量插入场景,而 `ExecutorType.BATCH` 更适合大规模数据插入任务。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值