해결된 질문
23.03.18 10:31 작성
·
1.1K
0
안녕하세요 선생님!
JdbcBatchItemWriter 에서 발생하는 Query 가
batch query 로 나가지 않는 것 같아서 질문 드립니다!
혹시 jdbc 에서 batch query 로 보내더라도 optimizer 에 의해
단일쿼리로 변경되어서 나갈수도 있나요?!
감사합니다.
위 사진은 MySQL 의 Query Log 입니다.
제 설정은 아래와 같습니다
@Configuration
class HelloJobConfiguration(
private val jobBuilderFactory: JobBuilderFactory,
private val stepBuilderFactory: StepBuilderFactory,
private val dataSource: DataSource,
) {
@Bean
fun job(): Job {
return jobBuilderFactory.get("job")
.incrementer(RunIdIncrementer())
.start(step1())
.build()
}
@Bean
fun step1(): Step {
return stepBuilderFactory.get("step1")
.chunk<Customer, Customer>(5)
.reader(customItemReader())
.writer(customItemWriter())
.build()
}
@Bean
fun customItemReader(): ItemReader<Customer> {
return JdbcPagingItemReaderBuilder<Customer>()
.name("jdbcPagingItemReader")
.dataSource(dataSource)
.pageSize(5)
.rowMapper(BeanPropertyRowMapper(Customer::class.java))
.queryProvider(queryProvider())
.build()
}
@Bean
fun queryProvider(): PagingQueryProvider {
return SqlPagingQueryProviderFactoryBean().apply {
setDataSource(dataSource)
setSelectClause("SELECT id, firstName, lastName, birthdate")
setFromClause("FROM customer")
setSortKeys(mapOf("id" to Order.ASCENDING))
}.`object`
}
@Bean
fun customItemWriter(): ItemWriter<Customer> {
return JdbcBatchItemWriterBuilder<Customer>()
.dataSource(dataSource)
.sql("INSERT INTO customer2 values(:id, :firstName, :lastName, :birthdate);")
.beanMapped()
.build()
}
}
답변 1
1
2023. 03. 21. 17:28
네
쿼리가 콘솔에 나오더라도 내부적으로 배치 형태로 업데이트 된다 보시면 됩니다.
실제로 내부 소스를 보시면 jdbctemplate.batchupdate(query).... 와 같이 되어 있습니다.
if (usingNamedParameters) {
if(items.get(0) instanceof Map && this.itemSqlParameterSourceProvider == null) {
updateCounts = namedParameterJdbcTemplate.batchUpdate(sql, items.toArray(new Map[items.size()]));
} else {
SqlParameterSource[] batchArgs = new SqlParameterSource[items.size()];
int i = 0;
for (T item : items) {
batchArgs[i++] = itemSqlParameterSourceProvider.createSqlParameterSource(item);
}
updateCounts = namedParameterJdbcTemplate.batchUpdate(sql, batchArgs);
}
}
else {
updateCounts = namedParameterJdbcTemplate.getJdbcOperations().execute(sql, new PreparedStatementCallback<int[]>() {
@Override
public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
for (T item : items) {
itemPreparedStatementSetter.setValues(item, ps);
ps.addBatch();
}
return ps.executeBatch();
}
});
}
보시면
namedParameterJdbcTemplate.batchUpdate(sql, batchArgs)
ps.addBatch();
ps.executeBatch()
와 같이 되어 있습니다.