23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
CompositeItemProcessor는 Spring Batch에서 제공하는 ItemProcessor 인터페이스를 구현하는 클래스이다.
여러 개의 ItemProcessor를 하나의 Processor로 연결하여 여러 단계의 처리를 수행할 수 있도록 한다.
Delegates: 처리를 수행할 ItemProcessor 목록이다.
TransactionAttribute: 트랜잭션 속성을 설정한다.
단계별 처리: 여러 단계로 나누어 처리를 수행하여 코드를 명확하고 이해하기 쉽게 만들 수 있다.
재사용 가능성: 각 단계별 Processor를 재사용하여 다른 Job에서도 활용할 수 있다.
유연성: 다양한 ItemProcessor를 조합하여 원하는 처리 과정을 구현할 수 있다.
설정 복잡성: 여러 개의 Processor를 설정하고 관리해야 하기 때문에 설정이 복잡해질 수 있다.
성능 저하: 여러 단계의 처리 과정을 거치므로 성능이 저하될 수 있다.
샘플 코드는 기존 06.06.MyBatisItemReaderSample을 그대로 이용한다.
package com.schooldevops.springbatch.batchsample.jobs.mybatis;
import com.schooldevops.springbatch.batchsample.jobs.models.Customer;
import org.springframework.batch.item.ItemProcessor;
/**
* 이름, 성별을 소문자로 변경하는 ItemProcessor
*/
public class LowerCaseItemProcessor implements ItemProcessor<Customer, Customer> {
@Override
public Customer process(Customer item) throws Exception {
item.setName(item.getName().toLowerCase());
item.setGender(item.getGender().toLowerCase());
return item;
}
}ItemProcessor를 구현하고, process 메소드를 구현한다.
여기서는 이름과 성별을 소문자로 변경한다.
나이에 20년을 더하기 위한 ItemProcessor를 작성한다.
package com.schooldevops.springbatch.batchsample.jobs.mybatis;
import com.schooldevops.springbatch.batchsample.jobs.models.Customer;
import org.springframework.batch.item.ItemProcessor;
/**
* 나이에 20년을 더하는 ItemProcessor
*/
public class After20YearsItemProcessor implements ItemProcessor<Customer, Customer> {
@Override
public Customer process(Customer item) throws Exception {
item.setAge(item.getAge() + 20);
return item;
}
}동일하게 ItemProcessor를 구현하고, process 메소드를 구현하였다.
단순히 나이에 20을 더했다.
@Bean
public CompositeItemProcessor<Customer, Customer> compositeItemProcessor() {
return new CompositeItemProcessorBuilder<Customer, Customer>()
.delegates(List.of(
new LowerCaseItemProcessor(),
new After20YearsItemProcessor()
))
.build();
}이제 CompositeItemProcessorBuilder를 이용하여 delegates를 통해서 ItemProcessor가 수행할 순서대로 배열을 만들어 전달했다.
package com.schooldevops.springbatch.batchsample.jobs.mybatis;
import com.schooldevops.springbatch.batchsample.jobs.models.Customer;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.batch.MyBatisPagingItemReader;
import org.mybatis.spring.batch.builder.MyBatisPagingItemReaderBuilder;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.support.CompositeItemProcessor;
import org.springframework.batch.item.support.builder.CompositeItemProcessorBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.List;
@Slf4j
@Configuration
public class MyBatisReaderJobConfig {
/**
* CHUNK 크기를 지정한다.
*/
public static final int CHUNK_SIZE = 2;
public static final String ENCODING = "UTF-8";
public static final String MYBATIS_CHUNK_JOB = "MYBATIS_CHUNK_JOB";
@Autowired
DataSource dataSource;
@Autowired
SqlSessionFactory sqlSessionFactory;
@Bean
public MyBatisPagingItemReader<Customer> myBatisItemReader() throws Exception {
return new MyBatisPagingItemReaderBuilder<Customer>()
.sqlSessionFactory(sqlSessionFactory)
.pageSize(CHUNK_SIZE)
.queryId("com.schooldevops.springbatch.batchsample.jobs.selectCustomers")
.build();
}
@Bean
public FlatFileItemWriter<Customer> customerCursorFlatFileItemWriter() {
return new FlatFileItemWriterBuilder<Customer>()
.name("customerCursorFlatFileItemWriter")
.resource(new FileSystemResource("./output/customer_new_v4.csv"))
.encoding(ENCODING)
.delimited().delimiter("\t")
.names("Name", "Age", "Gender")
.build();
}
@Bean
public CompositeItemProcessor<Customer, Customer> compositeItemProcessor() {
return new CompositeItemProcessorBuilder<Customer, Customer>()
.delegates(List.of(
new LowerCaseItemProcessor(),
new After20YearsItemProcessor()
))
.build();
}
@Bean
public Step customerJdbcCursorStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
log.info("------------------ Init customerJdbcCursorStep -----------------");
return new StepBuilder("customerJdbcCursorStep", jobRepository)
.<Customer, Customer>chunk(CHUNK_SIZE, transactionManager)
.reader(myBatisItemReader())
.processor(compositeItemProcessor())
.writer(customerCursorFlatFileItemWriter())
.build();
}
@Bean
public Job customerJdbcCursorPagingJob(Step customerJdbcCursorStep, JobRepository jobRepository) {
log.info("------------------ Init customerJdbcCursorPagingJob -----------------");
return new JobBuilder(MYBATIS_CHUNK_JOB, jobRepository)
.incrementer(new RunIdIncrementer())
.start(customerJdbcCursorStep)
.build();
}
}kido 30 m
kido2 40 m
kido3 50 m
kido4 60 m
kido5 31 f
kido6 35 f
kido7 45 m
kido8 53 f
kido9 61 m
kido10 37 m지금까지 ItemProcessor를 여러개 생성하고, 이를 순서대로 적용하는 샘플을 살펴보았다.
CompositeItemProcessor를 통해서 리스트의 순서대로 ItemProcessor이 적용된 것을 알 수 있다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.