-
20. ItemWriter (DB)BackEnd/Spring Batch 2021. 12. 31. 18:30반응형
JdbcBatchItemWriter
JdbcCursorItemReader 설정과 마찬가지로 datasource를 지정하고, sql 속성에 실행할 쿼리를 설정합니다. JDBC의 Batch 기능을 사용하여 bulk insert/update/delete 방식으로 처리합니다. 단건 처리가 아닌 일괄처리이기 때문에 성능에 이점을 가집니다.
API
package io.springbatch.springbatchlecture; import lombok.RequiredArgsConstructor; import org.springframework.batch.core.*; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.item.database.*; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; import org.springframework.batch.item.database.support.MySqlPagingQueryProvider; import org.springframework.batch.item.json.JacksonJsonObjectMarshaller; import org.springframework.batch.item.json.JsonFileItemWriter; import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder; import org.springframework.batch.item.xml.StaxEventItemWriter; import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.oxm.xstream.XStreamMarshaller; import javax.sql.DataSource; import java.util.*; @RequiredArgsConstructor @Configuration public class JdbcBatchConfiguration { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; private final DataSource dataSource; @Bean public Job job() throws Exception { return jobBuilderFactory.get("batchJob") .incrementer(new RunIdIncrementer()) .start(step1()) .build(); } @Bean public Step step1() throws Exception { return stepBuilderFactory.get("step1") .<Customer, Customer>chunk(10) .reader(customItemReader()) .writer(customItemWriter()) .build(); } @Bean public JdbcPagingItemReader<Customer> customItemReader() { JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>(); reader.setDataSource(this.dataSource); reader.setFetchSize(10); reader.setRowMapper(new CustomerRowMapper()); MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider(); queryProvider.setSelectClause("id, firstName, lastName, birthdate"); queryProvider.setFromClause("from customer"); queryProvider.setWhereClause("where firstname like :firstname"); Map<String, Order> sortKeys = new HashMap<>(1); sortKeys.put("id", Order.ASCENDING); queryProvider.setSortKeys(sortKeys); reader.setQueryProvider(queryProvider); HashMap<String, Object> parameters = new HashMap<>(); parameters.put("firstname", "A%"); reader.setParameterValues(parameters); return reader; } @Bean public JdbcBatchItemWriter<Customer> customItemWriter() { return new JdbcBatchItemWriterBuilder<Customer>() .dataSource(dataSource) .sql("insert into customer2 values (:id, :firstName, :lastName, :birthdate)") // .beanMapped() .columnMapped() .build(); } /*@Bean public JdbcBatchItemWriter<Customer> customItemWriter() { JdbcBatchItemWriter<Customer> itemWriter = new JdbcBatchItemWriter<>(); itemWriter.setDataSource(this.dataSource); itemWriter.setSql("insert into customer2 values (:id, :firstName, :lastName, :birthdate)"); itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider()); itemWriter.afterPropertiesSet(); return itemWriter; }*/ }
JpaItemWriter
JPA Entity 기반으로 데이터를 처리하며 EntityManagerFactory를 주입받아 사용합니다. Entity를 하나씩 chunk 크기 만큼 insert 혹은 merge한 다음 flush 합니다. ItemReader나 ItemProcessor로부터 아이템을 전달 받을 때는 Entity 클래스 타입으로 받아야 합니다.
API
package io.springbatch.springbatchlecture; import lombok.RequiredArgsConstructor; import org.springframework.batch.core.*; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.database.*; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; import org.springframework.batch.item.database.builder.JpaItemWriterBuilder; import org.springframework.batch.item.database.support.MySqlPagingQueryProvider; import org.springframework.batch.item.json.JacksonJsonObjectMarshaller; import org.springframework.batch.item.json.JsonFileItemWriter; import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder; import org.springframework.batch.item.xml.StaxEventItemWriter; import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.oxm.xstream.XStreamMarshaller; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import java.util.*; @RequiredArgsConstructor @Configuration public class JpaConfiguration { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; private final DataSource dataSource; private final EntityManagerFactory entityManagerFactory; @Bean public Job job() throws Exception { return jobBuilderFactory.get("batchJob") .incrementer(new RunIdIncrementer()) .start(step1()) .build(); } @Bean public Step step1() throws Exception { return stepBuilderFactory.get("step1") .<Customer, Customer2>chunk(10) .reader(customItemReader()) .processor(customItemProcess()) .writer(customItemWriter()) .build(); } @Bean public JpaItemWriter<Customer2> customItemWriter() { return new JpaItemWriterBuilder<Customer2>() .entityManagerFactory(entityManagerFactory) .usePersist(true) .build(); } @Bean public ItemProcessor<? super Customer, ? extends Customer2> customItemProcess() { return new CustomItemProcess(); } @Bean public JdbcPagingItemReader<Customer> customItemReader() { JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>(); reader.setDataSource(this.dataSource); reader.setFetchSize(10); reader.setRowMapper(new CustomerRowMapper()); MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider(); queryProvider.setSelectClause("id, firstName, lastName, birthdate"); queryProvider.setFromClause("from customer"); queryProvider.setWhereClause("where firstname like :firstname"); Map<String, Order> sortKeys = new HashMap<>(1); sortKeys.put("id", Order.ASCENDING); queryProvider.setSortKeys(sortKeys); reader.setQueryProvider(queryProvider); HashMap<String, Object> parameters = new HashMap<>(); parameters.put("firstname", "C%"); reader.setParameterValues(parameters); return reader; } }
[참고자료]
반응형'BackEnd > Spring Batch' 카테고리의 다른 글
22. ItemProcessor (0) 2022.01.04 21. ItemWriterAdapter (0) 2021.12.31 19. ItemWriter (Json) (0) 2021.12.31 18. ItemWriter (XML) (0) 2021.12.31 17. ItemWriter (File) (0) 2021.12.31