ItemPorcessor
๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๊ฑฐ๋ ํํฐ๋งํ๋ ์ญํ ์ ํ๋ฉฐ, ํ์๊ฐ ์๋๋ค. ์ด ์ญํ ์ ItemWriter
์์๋ ๊ตฌํ์ด ๊ฐ๋ฅํ์ง๋ง, ๋ถ๋ฆฌํจ์ผ๋ก์จ ๋น์ฆ๋์ค ์ฝ๋๊ฐ ์์ด๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๋ค.
public interface ItemProcessor<I, O> {
@Nullable
O process(@NonNull I var1) throws Exception;
}
I
๋ ItemReader์์ ๋ฐ์ ๋ฐ์ดํฐ ํ์
์ด๋ฉฐ, O
๋ ItemWriter์ ๋ณด๋ผ ๋ฐ์ดํฐ ํ์
์ด๋ค. ์ฆ, Reader์์ ์ฝ์ ๋ฐ์ดํฐ๊ฐ ItemProcessor์ process()
๋ฅผ ํต๊ณผํ ํ Writer์ ์ ๋ฌ๋๋ค. ๊ตฌํํด์ผํ ๋ฉ์๋๋ processํ๋์ด๋ฉฐ, Java 8๋ถํฐ๋ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋๊ฐ 1๊ฐ์ธ ๊ฒฝ์ฐ ๋๋ค์์ ์ฌ์ฉํ ์ ์๋ค.
@Bean(BEAN_PREFIX + "processor")
@StepScope
public ItemProcessor<ReadType, WriteType> processor() {
return item -> {
item.convert();
return item;
};
}
๋ถํ์ํ ์ฝ๋๊ฐ ์์ด ๊ตฌํ ์ฝ๋ ์์ด ์ ๋ค. (๋น ๋ฅด๊ฒ ๊ตฌํ ๊ฐ๋ฅ)
๊ณ ์ ๋ ํํ๊ฐ ์์ด ์ํ๋ ํํ์ ์ด๋ค ์ฒ๋ฆฌ๋ ๊ฐ๋ฅํ๋ค.
Batch Config ํด๋์ค ์์ ํฌํจ๋์ด ์์ด์ผ๋ง ํ๋ฉฐ, Batch Config ์ฝ๋ ์์ด ๋ง์์ง ์ ์๋ค.
์ฝ๋ ์์ด ๋ง์์ง๋ง ๋ณ๋ ํด๋์ค๋ก Processor๋ฅผ ๋ถ๋ฆฌํด์ ์ฌ์ฉํ๊ธฐ๋ ํ๋ค.
ํฌ๊ฒ ItemProcessor๋ ๋ค์ ์ญํ ์ ํ๋ค.
๋ณํ : Reader์์ ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ํ์
์ผ๋ก ๋ณํํ์ฌ, Writer์ ๋๊ฒจ์ค ์ ์๋ค.
// Pay -> String ํ์
๋ณํ
@Bean
public ItemProcessor<Pay, String> processor(){
return pay -> {
return pay.getTxName();
};
}
ํํฐ : Reader์์ ๋๊ฒจ์ค ๋ฐ์ดํฐ๋ฅผ Writer๋ก ๋๊ฒจ์ค ๊ฒ์ธ์ง ๊ฒฐ์ ํ ์ ์์ผ๋ฉฐ, null
์ ๋ฐํํ๋ฉด Writer์ ์ ๋ฌ๋์ง ์๋๋ค.
// amount๊ฐ 10000์ด์์ธ ๊ฐ๋ง Writer์ ๋์ด๊ฐ๋๋ก ํํฐ
@Bean
public ItemProcessor<Pay, Pay> nullProcessor(){
return pay -> {
if(pay.getAmount() < 10000){
log.info("Pay amount :{}", pay.getAmount());
return null;
}
return pay;
};
}
ItemProcessor๊ฐ null
์ ๋ฐํํ๋ฉด ํด๋น Item์ ๋ชจ๋ ์ดํ ์ฒ๋ฆฌ๊ฐ ์ค์ง๋๋ค. ์ด๋ null์ ๋ฐํํ๋๋ผ๋ ๋ค๋ฅธ Item ์ฒ๋ฆฌ๊ฐ ๊ณ์ ์ด๋ฃจ์ด์ง๋ค.
๊ตฌํ์ฒด
Spring Batch ์์๋ ์์ฃผ ์ฌ์ฉํ๋ ์ฉ๋์ Processor๋ฅผ ๋ฏธ๋ฆฌ ํด๋์ค๋ก ๋ง๋ค์ด์ ์ ๊ณตํด์ฃผ๊ณ ์๋ค.
ํ์ง๋ง ์ต๊ทผ์๋ ๋๋ถ๋ถ processor๋ฅผ ์ง์ ๊ตฌํํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ , ๋๋ค์์ผ๋ก ๋น ๋ฅด๊ฒ ๊ตฌํํ ๋๋ ๋ง๋ค. ๊ทธ๋์ ItemProcessorAdapter
์ ValidatingItemProcessor
๋ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค.
์
๋ ฅ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ฌ์ฉํ๋ ItemProcessor ๊ตฌํ์ฒด์ด๋ค. ์
๋ ฅ ์์ดํ
์ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ํํ๋ ์คํ๋ง๋ฐฐ์น Validator
๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ ํจ์ฑ ๊ฒ์ฆ์ด ์คํจํ๋ฉด, ValidationException
์ด ๋ฐ์ํ๋ค.
org.springframework.batch.item.validator.ValidatingItemProcessor
BeanValidatingItemProcessor
JSR 303์ ๋น ์ ํจ์ฑ ๊ฒ์ฆ์ ์ํ ๊ฒ์ผ๋ก, ์คํ๋ง ๋ฐฐ์น๋ ๋ฏธ๋ฆฌ ์ ์๋ ์ ํจ์ฑ ๊ฒ์ฆ ๊ธฐ๋ฅ์ ์ด๋
ธํ
์ด์
์ผ๋ก ์ ๊ณตํด์ค๋ค. ํด๋น ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ ค๋ฉด, ๋ค์ ์์กด์ฑ์ ์ถ๊ฐํด์ค์ผํ๋ค.
implementation 'org.springframework.boot:spring-boot-starter-validation'
์ด๋
ธํ
์ด์
์์ฑ
์ค๋ช
๊ฐ์ด null์ธ์ง ์๋์ง ๊ฒ์ฌ
int min : ์ต์ ํฌ๊ธฐ(default : 0)
int max : ์ต๋ํฌ๊ธฐ
๊ธธ์ด๋ ํฌ๊ธฐ๊ฐ ์ง์ ํ ๊ฐ ๋ฒ์์ ์๋์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค๊ณ ํ๋จ
String regexp = ์ ๊ทํํ์
๊ฐ์ด ์ ๊ท ํํ์์ ์ผ์นํ๋์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค๊ณ ํ๋จ
๊ฐ์ด true์ธ์ง false์ธ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
String value: ์ต๋๊ฐ ๋๋ ์ต์๊ฐ
boolean inclusive : ์ง์ ๊ฐ ํฌํจ ์ฌ๋ถ(default : true)
์ง์ ํ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์์ง ํน์ ํฌ๊ฑฐ๋ ๊ฐ์์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
์ง์ ํ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์์ง ํน์ ํฌ๊ฑฐ๋ ๊ฐ์์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
int integer : ํ์ฉ๊ฐ๋ฅํ ์ ์ ์๋ฆฟ์
int fraction : ํ์ฉ ๊ฐ๋ฅํ ์์์ ์ดํ ์๋ฆฟ์
์๋ฆฟ์๊ฐ ์ง์ ํ ํฌ๊ธฐ๋ฅผ ๋์ง ์๋์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
๋ฌธ์์ด, ๋ฐฐ์ด : null์ด ์๋๊ณ , ๊ธธ์ด๊ฐ 0์ด ์๋์ง ๊ฒ์ฌ
Collection : null์ด ์๋๊ณ , ํฌ๊ธฐ๊ฐ 0์ด ์๋์ง ๊ฒ์ฌ
null์ด ์๋๊ณ ์ต์ํ ํ๊ฐ ์ด์์ ๊ณต๋ฐฑ์ด ์๋ ๋ฌธ์๋ฅผ ํฌํจํ๋์ง ๊ฒ์ฌ
@Positive
@PositiveOrZero
์์์ธ์ง ๊ฒ์ฌ
OrZero๋ ์์ ํน์ 0์ธ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
@Negative
@NegativeOrZero
์์์ธ์ง ๊ฒ์ฌ
OrZero๋ ์์ ํน์ 0์ธ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
์ด๋ฉ์ผ ์ฃผ์๊ฐ ์ ํจํ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
ํด๋น ์๊ฐ์ด ๋ฏธ๋์ธ์ง ๊ฒ์ฌ
OrPresent๋ ํ์ฌ ๋๋ ๋ฏธ๋์๊ฐ์ธ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
ํด๋น ์๊ฐ์ด ๊ณผ๊ฑฐ์ธ์ง ๊ฒ์ฌ
OrPresent๋ ํ์ฌ ๋๋ ๊ณผ๊ฑฐ์๊ฐ์ธ์ง ๊ฒ์ฌ
null์ ์ ํจํ๋ค ํ๋จ
public class Customer {
@NotNull(message = "firstname์ ํ์๊ฐ์
๋๋ค.")
@Pattern(regexp = "[a-zA-Z]+", message = "firstname์ ์์ด์ฌ์ผํฉ๋๋ค.")
private String firstName;
@NotNull(message = "city ํ์๊ฐ์
๋๋ค.")
@Pattern(regexp = "[a-zA-Z\\. ]+")
private String city;
@NotNull(message = "state ํ์๊ฐ์
๋๋ค.")
@Size(min=2, max=2)
@Pattern(regexp = "[A-Z{2}]+")
private String state;
// ...
}
์ ์์ ์ ๊ฐ์ด ๊ณ ์ ํ ๋ฉ์ธ์ง๋ฅผ ์ง์ ํ ์ ์์ผ๋ฉฐ, ํ๋ ๊ฐ์ ๊ธธ์ด๊ฐ ์๋ชป๋๋์ง ํ์์ด ์๋ชป๋๋์ง ์๋ณํ ์ ์๋ค.
@Bean
public Step validationDelimitedFileStep() {
return this.stepBuilderFactory.get("validationDelimitedFileStep")
.<Customer, Customer>chunk(10)
.reader(validationDelimitedCustomerItemReader(null))
.processor(validationCustomerProcessor()) // processor
.writer(validationDelimitedCustomerItemWriter())
.build();
}
/**
* BeanValidationItemProcessor ์ค์
* @return
*/
@Bean
public BeanValidatingItemProcessor<Customer> validationCustomerProcessor() {
return new BeanValidatingItemProcessor<>();
}
Field error in object 'item' on field 'middleInitial': rejected value [YS]; codes [Size.item.middleInitial,Size.middleInitial,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.middleInitial,middleInitial]; arguments []; default message [middleInitial],1,1]; default message [ํฌ๊ธฐ๊ฐ 1์์ 1 ์ฌ์ด์ฌ์ผ ํฉ๋๋ค]
Field error in object 'item' on field 'middleInitial': rejected value [YS]; codes [Pattern.item.middleInitial,Pattern.middleInitial,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.middleInitial,middleInitial]; arguments []; default message [middleInitial],[Ljavax.validation.constraints.Pattern$Flag;@5c7a06ec,[a-zA-Z]]; default message [middleInitial๋ ๋ฐ๋์ ์์ด์ฌ์ผํฉ๋๋ค.]
๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ validation์ ๋ง์ง ์์ผ๋ฉด ์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ValidatingItemProcessor
๋ฐ์ดํฐ์
๋ด์์ ํ๊ฐ์ ํ๋์ ๊ฐ์ด ๊ณ ์ ํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์์ ์ ์๋ค. ๊ณ ์ ํ ๊ฐ์ ํ๋๋ฅผ ItemStream
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ, ๊ฐ ์ปค๋ฐ๊ณผ ํ๋ ๊ฐ์ ExecutionContext
์ ์ ์ฅํด ์ํ๋ฅผ ์ ์งํ ์ ์๋ค.
/**
* JobExecution ๊ฐ์ ์ํ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ItemStreamSupport ์์
*/
public class UniqueLastNameValidator extends ItemStreamSupport implements Validator<Customer> {
private Set<String> lastNames = new HashSet<>();
@Override
public void validate(Customer value) throws ValidationException {
if (lastNames.contains(value.getLastName())) {
throw new ValidationException(value.getLastName() + " lastName์ด ์ค๋ณต๋ฉ๋๋ค.");
}
this.lastNames.add(value.getLastName());
}
@Override
public void open(ExecutionContext executionContext) {
String lastNames = getExecutionContextKey("lastNames");
// lastNames๊ฐ Execution์ ์ ์ฅ๋์ด์๋์ง ํ์ธ ํ ์ ์ฅ๋์ด์๋ค๋ฉด, ์คํ
์ฒ๋ฆฌ ์ด์ ์ ํด๋น๊ฐ์ผ๋ก ์๋ณต
if (executionContext.containsKey(lastNames)) {
this.lastNames = (Set<String>) executionContext.get(lastNames);
}
}
/**
* ์ฒญํฌ ๋จ์๋ก ์ํ๋๋๋ฐ, ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ํ์ฌ ์ํ๋ฅผ ExecutionContext์ ์ ์ฅ
* @param executionContext
*/
@Override
public void update(ExecutionContext executionContext) {
Iterator<String> itr = lastNames.iterator();
Set<String> copiedLastNames = new HashSet<>();
while (itr.hasNext()) {
copiedLastNames.add(itr.next());
}
executionContext.put(getExecutionContextKey("lastNames"), copiedLastNames);
}
}
Validator๋ฅผ ๊ตฌํํ ํ Step์ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ฉด ๋๋ค.
@Bean
public Step validationDelimitedFileStep() {
return this.stepBuilderFactory.get("validationDelimitedFileStep")
.<Customer, Customer>chunk(10)
.reader(validationDelimitedCustomerItemReader(null))
.processor(customerValidatingItemProcessor()) // ํ๋ก์ธ์
.writer(validationDelimitedCustomerItemWriter())
.stream(uniqueLastNameValidator()) // stream ์ค์
.build();
}
@Bean
public ValidatingItemProcessor<Customer> customerValidatingItemProcessor() {
return new ValidatingItemProcessor<>(uniqueLastNameValidator());
}
@Bean
public UniqueLastNameValidator uniqueLastNameValidator() {
UniqueLastNameValidator uniqueLastNameValidator = new UniqueLastNameValidator();
uniqueLastNameValidator.setName("uniqueLastNameValidator");
return uniqueLastNameValidator;
}
ItemProcessorAdapter
org.springframework.batch.item.adapter.ItemProcessorAdapter
์๋น์ค๋ฅผ ItemProcessor
์ญํ ์ ํ๋๋ก ๋ง๋ค ์ ์๋ค.
@Service
public class UpperCaseNameService {
public Customer upperCase(Customer customer) {
Customer newCustomer = new Customer(customer);
newCustomer.setFirstName(newCustomer.getFirstName().toUpperCase());
newCustomer.setLastName(newCustomer.getLastName().toUpperCase());
newCustomer.setMiddleInitial(newCustomer.getMiddleInitial().toUpperCase());
return newCustomer;
}
}
๊ณ ๊ฐ์ ์ด๋ฆ์ ๋๋ฌธ์๋ก ๋ฐ๊ฟ์ฃผ๋ ์๋น์ค์ด๋ค. ์ด ์๋น์ค๋ฅผ ItemProcessorAdapter
๋ฅผ ์ฌ์ฉํ์ฌ Processor๋ก ์ฌ์ฉํ ์ ์๋ค.
@Bean
public Step validationDelimitedFileStep() {
return this.stepBuilderFactory.get("validationDelimitedFileStep")
.<Customer, Customer>chunk(10)
.reader(validationDelimitedCustomerItemReader(null))
.processor(customerItemProcessorAdapter())
.writer(validationDelimitedCustomerItemWriter())
.stream(uniqueLastNameValidator())
.build();
}
@Bean
public ItemProcessorAdapter<Customer, Customer> customerItemProcessorAdapter() {
ItemProcessorAdapter<Customer, Customer> adapter = new ItemProcessorAdapter<>();
adapter.setTargetObject(upperCaseNameService);
adapter.setTargetMethod("upperCase");
return adapter;
}
ScriptItemProcessor
Ruby, JavaScript, Groovy ๋ฑ ๋ค์ํ ์คํฌ๋ฆฝํธ ์ธ์ด๋ฅผ ์คํํ ์ ์๋ค.
org.springframework.batch.item.support.ScriptItemProcessor
// lowerCase.js
item.setFirstName(item.getFirstName().toLowerCase());
item;
@Bean
@StepScope
public ScriptItemProcessor<Customer, Customer> scriptItemProcessor(@Value("#{jobParameters['script']}") Resource script) {
ScriptItemProcessor<Customer, Customer> itemProcessor = new ScriptItemProcessor<>();
itemProcessor.setScript(script);
return itemProcessor;
}
์ํํ๊ณ ์ถ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ์ธ๋ฉํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
CompositeItemProcessor
CompositeItemProcessor
๋ ItemProcessor๊ฐ์ ์ฒด์ด๋์ ์ง์ํ๋ Processor์ด๋ค.
@Bean
public CompositeItemProcessor compositeItemProcessor(){
List<ItemProcessor> delegates = new ArrayList<>(2);
delegates.add(nullProcessor());
delegates.add(processor());
CompositeItemProcessor processor = new CompositeItemProcessor();
processor.setDelegates(delegates);
return processor;
}
@Bean
public ItemProcessor<Pay, String> processor(){
return pay -> {
return pay.getTxName();
};
}
@Bean
public ItemProcessor<Pay, Pay> nullProcessor(){
return pay -> {
if(pay.getAmount() < 10000){
log.info("Pay amount :{}", pay.getAmount());
return null;
}
return pay;
};
}
๋ค์๊ณผ ๊ฐ์ด Processor๊ฐ ์ฌ๋ฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์ฒด์ด๋ ์์
์ ํ ์ ์๋ค.
ํ์ง๋ง, ์ฌ๊ธฐ์ ์ ๋ค๋ฆญ ํ์
์ ์ฌ์ฉํ์ง ๋ชปํ๋ฉฐ, ๋ง์ฝ ์ ๋ค๋ฆญํ์
์ ์ฌ์ฉํ๊ฒ ๋๋ฉด delegates
์ ํฌํจ๋ ItemProcessor
๋ ๋ชจ๋ ๊ฐ์ ์ ๋ค๋ฆญ ํ์
์ ๊ฐ์ ธ์ผํ๋ค. ๋ง์ฝ ๊ฐ์ ์ ๋ค๋ฆญ ํ์
์ ์ฌ์ฉํ ์ ์๋ ItemProcessor๊ฐ ์ฒด์ด๋์ด๋ผ๋ฉด ์ ๋ค๋ฆญ์ ์ ์ธํ๋ ๊ฒ์ด ๋ ์์ ํ ์ฝ๋๊ฐ ๋ ์ ์๋ค.
ClassifierCompositeItemProcessor
org.springframework.batch.item.support.ClassifierCompositeItemProcessor
Classifier
๊ตฌํ์ฒด๋ก ์ฌ์ฉํ ItemProcessor๋ฅผ ์ ์ ํด classify
๋ฉ์๋๋ฅผ ์ํํด ๋ถ๋ฅ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
public interface Classifier<C, T> extends Serializable {
T classify(C classifiable);
}
๋ค์์ ์ฐํธ๋ฒํธ๋ฅผ ์ง์ ํ์๋ก ๋ถ๋ฅํ Classifier
๊ตฌํ์ฒด์ด๋ค.
@AllArgsConstructor
public class ZipCodeClassifier implements Classifier<Customer, ItemProcessor<Customer, Customer>> {
private ItemProcessor<Customer, Customer> oddProcessor;
private ItemProcessor<Customer, Customer> evenProcessor;
@Override
public ItemProcessor<Customer, Customer> classify(Customer classifiable) {
if (Integer.parseInt(classifiable.getZipCode()) % 2 == 0) {
return evenProcessor;
} else {
return oddProcessor;
}
}
}
๊ตฌํํ Classifier
๋ฅผ ClassifierCompositeItemProcessor
๋ก ๊ตฌํํ์ฌ ์ํํ ์ ์๋ค.
// ํ์, ์ง์ ํ๋ก์ธ์ ์ค์
@Bean
public Classifier classifier() {
return new ZipCodeClassifier(customerItemProcessorAdapter(), scriptItemProcessor());
}
@Bean
public ClassifierCompositeItemProcessor<Customer, Customer> classifierCompositeItemProcessor() {
ClassifierCompositeItemProcessor<Customer, Customer> itemProcessor = new ClassifierCompositeItemProcessor<>();
itemProcessor.setClassifier(classifier());
return itemProcessor;
}
ํ์์ธ ๊ฒฝ์ฐ์๋ upperCase์ถ๋ ฅ, ์ง์์ธ ๊ฒฝ์ฐ lowerCase๋ก ๋ถ๋ฅํด์ ์ถ๋ ฅํ๋๋ก ๊ตฌํํ์์ผ๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ด ์ ์์ ์ผ๋ก ์ถ๋ ฅ๋๋๊ฑธ ํ์ธํ ์ ์๋ค.
Customer(firstName=aimee, middleInitial=C, lastName=Hoover, addressNumber=7341, street=Vel Avenue, city=Mobile, state=AL, zipCode=35928, address=null, transactions=null)
Customer(firstName=JONAS, middleInitial=U, lastName=GILBERT, addressNumber=8852, street=In St., city=Saint Paul, state=MN, zipCode=57321, address=null, transactions=null)
Customer(firstName=REGAN, middleInitial=M, lastName=BAXTER, addressNumber=4851, street=Nec Av., city=Gulfport, state=MS, zipCode=33193, address=null, transactions=null)
Customer(firstName=OCTAVIUS, middleInitial=T, lastName=DAUGHERTY, addressNumber=7418, street=Cum Road, city=Houston, state=TX, zipCode=51507, address=null, transactions=null)
Customer(firstName=stuart, middleInitial=K, lastName=Mckenzie, addressNumber=5529, street=Orci Av., city=Nampa, state=ID, zipCode=18562, address=null, transactions=null)
Customer(firstName=PETRA, middleInitial=Z, lastName=LARA, addressNumber=8401, street=Et St., city=Georgia, state=GA, zipCode=70323, address=null, transactions=null)
Customer(firstName=cherokee, middleInitial=T, lastName=Laradd, addressNumber=8516, street=Mauris St., city=Seattle, state=WA, zipCode=28720, address=null, transactions=null)
Customer(firstName=athena, middleInitial=Y, lastName=Burt, addressNumber=4951, street=Mollis Rd., city=Newark, state=DE, zipCode=41034, address=null, transactions=null)
Customer(firstName=kaitlin, middleInitial=M, lastName=Macias, addressNumber=5715, street=Velit St., city=Chandler, state=AZ, zipCode=86176, address=null, transactions=null)
Customer(firstName=LEROY, middleInitial=X, lastName=CHERRY, addressNumber=7810, street=Vulputate St., city=Seattle, state=WA, zipCode=37703, address=null, transactions=null)
ItemProcessor ์ง์ ๊ตฌํํ๊ธฐ
์ปค์คํ
ํ๋ก์ธ์๋ฅผ ์์ฑํ์ฌ ์ง์ ์ฐํธ๋ฒํธ๋ ํํฐ๋งํ๊ณ ํ์ ์ฐํธ๋ฒํธ๋ง ๋จ๊ฒจ๋๋ ItemProcessor
์์ ๋ฅผ ์ดํด๋ณผ ๊ฒ์ด๋ค.
ItemProcessor
๋ **null
**์ ๋ฐํํ๋ฉด ํด๋น ์์ดํ
์ ๊ทธ ์ดํ ์ํ๋๋ ItemProcessor
๋ ItemWriter
๋ก ์ ๋ฌ๋์ง ์๊ณ , ํํฐ๋ง๋๋ค. ์ด๋ ๊ฒ ํํฐ๋ง๋ ๋ ์ฝ๋์ ์๋ฅผ JobRepository
์ ๊ด๋ฆฌํ๊ณ ์๋ค.
public class EvenFilteringItemProcessor implements ItemProcessor<Customer, Customer> {
@Override
public Customer process(Customer item) throws Exception {
return Integer.parseInt(item.getZipCode()) % 2 == 0 ? null : item;
}
}
๋ค์๊ณผ ๊ฐ์ด ItemProcessor
๋ฅผ ๊ตฌํํ์ฌ, process
๋ฉ์๋์ ์ํ๋ ๋ก์ง์ ์์ฑํด์ฃผ๋ฉด ๋๋ค.
SELECT STEP_EXECUTION_ID AS ID, STEP_NAME, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT
FROM BATCH_STEP_EXECUTION;
BATCH_STEP_EXECUTION
๋ด์ ์ฑ๊ณตํ ์, ํํฐ๋ง ๊ฑธ๋ฆฐ ์์ดํ
์๋ฅผ ํ์ธํ ์ ์๋ค.
์ฐธ๊ณ