@Configuration
@EnableBatchProcessing
public
class
ProductBatchConfiguration {
private
final
JobBuilderFactory jobBuilderFactory;
private
final
StepBuilderFactory stepBuilderFactory;
private
final
DataSource dataSource;
public
ProductBatchConfiguration(
JobBuilderFactory jobBuilderFactory,
StepBuilderFactory stepBuilderFactory,
DataSource dataSource)
{
this
.jobBuilderFactory = jobBuilderFactory;
this
.stepBuilderFactory = stepBuilderFactory;
this
.dataSource = dataSource;
}
@Bean
public
Job importProductJob(
JobCompletionNotificationListener listener)
{
return
jobBuilderFactory.get(
"importProductJob"
)
.incrementer(
new
RunIdIncrementer())
.listener(listener)
.flow(productStep())
.end()
.build();
}
@Bean
public
Step productStep()
{
return
stepBuilderFactory.get(
"productStep"
)
.<Product, Product>chunk(
10
)
.reader(productItemReader())
.processor(productItemProcessor())
.writer(productItemWriter())
.faultTolerant()
.skipLimit(
20
)
.skip(CsvFormatException.
class
)
.listener(
new
ProductSkipListener())
.build();
}
@Bean
public
FlatFileItemReader<Product> productItemReader()
{
return
new
FlatFileItemReaderBuilder<Product>()
.name(
"productItemReader"
)
.resource(
new
ClassPathResource(
"Products.csv"
))
.delimited()
.delimiter(
","
)
.names(
new
String[] {
"productId"
,
"name"
,
"category"
,
"quantity"
,
"price"
})
.linesToSkip(
1
)
.fieldSetMapper(
new
BeanWrapperFieldSetMapper<Product>() {
{
setTargetType(Product.
class
);
}
})
.build();
}
@Bean
public
ItemProcessor<Product, Product>
productItemProcessor()
{
return
new
ItemProcessor<Product, Product>() {
@Override
public
Product process(Product product)
throws
Exception
{
if
(product.getQuantity() ==
0
) {
return
null
;
}
product.setPrice(
product.getPrice()
*
1.02
);
return
product;
}
};
}
@Bean
public
JdbcBatchItemWriter<Product> productItemWriter()
{
return
new
JdbcBatchItemWriterBuilder<Product>()
.itemSqlParameterSourceProvider(
new
BeanPropertyItemSqlParameterSourceProvider<>())
.sql(
"INSERT INTO Product (productId, name, "
"category, quantity, price) VALUES "
"(:productId, :name, :category, :quantity, "
":price)"
)
.dataSource(dataSource)
.build();
}
}