之前写过一篇mybatis批量插入的文章:https://cloud.tencent.com/developer/article/1868919
这次补充:
根据https://blog.csdn.net/huanghanqian/article/details/83177178所述千条以上的批量插入或者更新慎用foreach方式,ExecutorType.BATCH 的插入方式,性能显著提升
那么怎么使用这种方式?
可以参考我上面的那篇文章。
另外发现篇不错的介绍此内容的英文文章:http://pretius.com/how-to-use-mybatis-effectively-perform-batch-db-operations/
此处简单翻译如下:
MyBatis的批处理配置
代码语言:javascript复制@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配置类中的代码:
代码语言:javascript复制 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
代码语言:javascript复制 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中的用法
代码语言:javascript复制 @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原理分析