MyBatis的批量更新或插入的正确姿势

之前写过一篇mybatis批量插入的文章:https://blog.csdn.net/w605283073/article/details/83064000

这次补充:

根据https://blog.csdn.net/huanghanqian/article/details/83177178所述千条以上的批量插入或者更新慎用foreach方式,ExecutorType.BATCH 的插入方式,性能显著提升

那么怎么使用这种方式?

可以参考我上面的那篇文章。

 

另外发现篇不错的介绍此内容的英文文章:http://pretius.com/how-to-use-mybatis-effectively-perform-batch-db-operations/

此处简单翻译如下:

MyBatis的批处理配置

@Bean
    @Primary
    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory());
    }

    @Bean(name=MyBatisProperties.BATCH_SQL_SESSION_TEMPLATE)
    public SqlSessionTemplate batchSqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory(), ExecutorType.BATCH);
    }

可以使用上面两种session模板俩处理不同的模型:

1、标准- 标准的或单条操作

2、批量- 批量或者成块的处理

注意:一个session模板只能有一种处理模型

默认的mybatis mapper使用默认的标准的session模板,而不用批处理的session模板。

如果我们想要一个mapper使用批处理session,我们需要将其从其他mapper中分离。

 

BatchConfiguration配置类中的代码:

    public final static String BATCH_FORECAST_MAPPER = "batchForecastMapper";

    @Autowired
    @Qualifier(MyBatisProperties.BATCH_SQL_SESSION_TEMPLATE)
    private SqlSessionTemplate batchSqlSessionTemplate;

    @Bean
    public MapperFactoryBean batchForecastMapper() {
        MapperFactoryBean mapper = new MapperFactoryBean();
        mapper.setMapperInterface(ForecastMapper.class);
        mapper.setSqlSessionTemplate(batchSqlSessionTemplate);
        return mapper;
    }

 

简单的mapper类,要加上bean的名称为BatchConfiguration.BATCH_FORECAST_MAPPER

    public interface ForecastMapper {
        void createForecast(@Param("forecast") Forecast forecast, @Param("audit") AuditData audit);

        void updateForecast(@Param("forecast") Forecast forecast, @Param("deleted") boolean deleted, @Param("audit") AuditData audit);

        @Flush
        List flush();
    }

添加了flush方法,是为了控制批量插入的大小。返回值是影响的行数。

service中的用法

    @Autowired
    @Qualifier(BatchConfiguration.BATCH_FORECAST_MAPPER)
    private ForecastMapper batchForecastMapper;

    ...
    if (!toUpdate.isEmpty()) {
        for (ForecastUpdate forecast : toUpdate) {
            batchForecastMapper.updateForecast(forecast, forecast.isDeleted(), auditData);
        }
        batchForecastMapper.flush();
    }
    for (ForecastUpdate forecast : toCreate) {
        batchForecastMapper.createForecast(forecast, auditData);
        // Oracle does not support useGeneratedKeys in batch update, but flush after each statement works.
        batchForecastMapper.flush();
    }

调用flush时会调用doFlushStatement方法把数据批量刷新到表中。另外flush方法在每个事务结束前或者select语句调用前会自动触发。

潜在的问题:

Oracle 数据库中需要每个插入语句后都要调用flush方法,来使得useGeneratedKeys生效。

 

参考文章:  Mybatis Executor原理分析

 

 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:Age of Ai 设计师:meimeiellie 返回首页

打赏作者

明明如月学长

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值