스프링 배치 가이드
- 지난 포스팅에서 튜토리얼 보고 따라해봤는데, 이번에는 개념부터 천천히 공부해보자.
- 책을 보고 공부하려 했으나, 스프링과 부트의 배치 사용 문법이 많이 달라 이동욱님의 블로그를 보고 공부했다.
https://devhooney.tistory.com/139
1. ItemWriter
public interface ItemWriter<T> {
/**
* Process the supplied data element. Will not be called with any null items
* in normal operation.
*
* @param items items to be written
* @throws Exception if there are errors. The framework will catch the
* exception and convert or rethrow it as appropriate.
*/
void write(List<? extends T> items) throws Exception;
}
- ItemWriter 인터페이스는 Items List를 받는다.
- ItemReader를 통해 각 항목을 개별적으로 읽고 이를 처리하기 위해 ItemProcessor로 전달
- 이 프로세스는 Chunk의 Item 개수 만큼 처리될 때 까지 계속 진행
- Chunk 단위만큼 처리가 완료되면 Writer에 전달되어 Writer에 명시되어 있는대로 일괄 처리
=> Reader와 Processor를 거쳐서 처리된 Item을 Chunk 단위만큼 쌓은 뒤 Writer에 전달!
2. Database Writer
- Writer는 Chunk단위의 마지막이므로 Flush 처리를 해줘야 한다.
- Writer가 받은 모든 Item이 처리된 후, Spring Batch는 현재 트랜잭션을 커밋한다.
- 데이터베이스와 관련된 Writer는 3가지
- JdbcBatchItemWriter
- HibernateItemWriter
- JpaItemWriter
3. JdbcBatchItemWriter
- ORM을 사용하지 않는 경우 Writer는 대부분 JdbcBatchItemWriter를 사용
- JDBC의 Batch 기능을 사용하여 한번에 Query를 DB로 전달하며, DB 내부에서 쿼리들이 실행된다.
- 이유는 어플리케이션과 데이터베이스 간에 데이터를 주고 받는 횟수를 최소화하여 성능을 향상시키기 위한 것.
4. JpaItemWriter
- 예제 코드
@Slf4j
@RequiredArgsConstructor
@Configuration
public class JpaItemWriterJobConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final EntityManagerFactory entityManagerFactory;
private static final int chunkSize = 10;
@Bean
public Job jpaItemWriterJob() {
return jobBuilderFactory.get("jpaItemWriterJob")
.start(jpaItemWriterStep())
.build();
}
@Bean
public Step jpaItemWriterStep() {
return stepBuilderFactory.get("jpaItemWriterStep")
.<Pay, Pay2>chunk(chunkSize)
.reader(jpaItemWriterReader())
.processor(jpaItemProcessor())
.writer(jpaItemWriter())
.build();
}
@Bean
public JpaPagingItemReader<Pay> jpaItemWriterReader() {
return new JpaPagingItemReaderBuilder<Pay>()
.name("jpaItemWriterReader")
.entityManagerFactory(entityManagerFactory)
.pageSize(chunkSize)
.queryString("SELECT p FROM Pay p")
.build();
}
@Bean
public ItemProcessor<Pay, Pay2> jpaItemProcessor() {
return pay -> new Pay2(pay.getAmount(), pay.getTxName(), pay.getTxDateTime());
}
@Bean
public JpaItemWriter<Pay2> jpaItemWriter() {
JpaItemWriter<Pay2> jpaItemWriter = new JpaItemWriter<>();
jpaItemWriter.setEntityManagerFactory(entityManagerFactory);
return jpaItemWriter;
}
}
- ItemProcessor는 Pay에서 Pay2로 전달해주기 위한 것
- JpaItemWriter는 Pay라는 엔티티를 데이터베이스에 반영
- JpaItemWriter는 Entity 클래스를 제네릭으로 받아야 한다.
=> JpaItemWriter 는 넘어온 Item을 그대로 entityManger.merge()로 테이블에 반영을 하기 때문.
- 실행하면
- 데이터가 pay2에 write됐다.
'개발 > Java&Kotlin' 카테고리의 다른 글
[Java] 생성자 대신 정적 팩토리 메소드 사용하기 (1) | 2023.01.01 |
---|---|
[Spring] 스프링 배치(Spring Batch) 가이드 따라가기 (7) (0) | 2022.12.23 |
[Spring] 스프링 배치(Spring Batch) 가이드 따라가기 (5) (0) | 2022.12.18 |
[Spring] 스프링 배치(Spring Batch) 가이드 따라가기 (4) (0) | 2022.12.14 |
[Spring] 스프링 배치(Spring Batch) 가이드 따라가기 (3) (0) | 2022.12.13 |