我目前正在编写一个 Spring 批处理,其中我正在读取大量数据,对其进行处理,然后我希望将这些数据传递给 2 个写入器。一位作家将简单地更新数据库,而第二位作家将写入一个 csv 文件。
我打算编写自己的自定义编写器,并在 customItemWriter 中注入两个 itemWriter,并在 customItemWriter 的 write 方法中调用两个项目编写器的 write 方法。这种方法正确吗?是否有任何可用的 ItemWriter 实现满足我的要求?
提前致谢
我目前正在编写一个 Spring 批处理,其中我正在读取大量数据,对其进行处理,然后我希望将这些数据传递给 2 个写入器。一位作家将简单地更新数据库,而第二位作家将写入一个 csv 文件。
我打算编写自己的自定义编写器,并在 customItemWriter 中注入两个 itemWriter,并在 customItemWriter 的 write 方法中调用两个项目编写器的 write 方法。这种方法正确吗?是否有任何可用的 ItemWriter 实现满足我的要求?
提前致谢
您可以使用 Spring 的CompositeItemWriter并将所有作者委托给它。
这是一个配置示例。
您不必像示例那样使用 xml。如果您的其余代码使用注释,您可以简单地执行以下操作。
public ItemWriter<T> writerOne(){
ItemWriter<T> writer = new ItemWriter<T>();
//your logic here
return writer;
}
public ItemWriter<T> writerTwo(){
ItemWriter<T> writer = new ItemWriter<T>();
//your logic here
return writer;
}
public CompositeItemWriter<T> compositeItemWriter(){
CompositeItemWriter writer = new CompositeItemWriter();
writer.setDelegates(Arrays.asList(writerOne(),writerTwo()));
return writer;
}
你是对的。SB 很大程度上基于委托,因此使用CompositeItemWriter是满足您需求的正确选择。
Java Config方式SpringBatch4
@Bean
public Step step1() {
return this.stepBuilderFactory.get("step1")
.<String, String>chunk(2)
.reader(itemReader())
.writer(compositeItemWriter())
.stream(fileItemWriter1())
.stream(fileItemWriter2())
.build();
}
/**
* In Spring Batch 4, the CompositeItemWriter implements ItemStream so this isn't
* necessary, but used for an example.
*/
@Bean
public CompositeItemWriter compositeItemWriter() {
List<ItemWriter> writers = new ArrayList<>(2);
writers.add(fileItemWriter1());
writers.add(fileItemWriter2());
CompositeItemWriter itemWriter = new CompositeItemWriter();
itemWriter.setDelegates(writers);
return itemWriter;
}
根据您的需要,另一种选择是扩展 Writer 类并在其中添加功能。例如,我有一个项目,我在其中扩展 HibernateItemWriter,然后覆盖 write(List items)。然后,我将正在编写的对象与 sessionFactory 一起发送到 Writer 的 doWrite 方法:doWrite(sessionFactory, filteredRecords)。
所以在上面的例子中,我可以在我的扩展类中写入 csv 文件,然后 HibernateItemWriter 将写入数据库。显然,这对于本示例可能并不理想,但对于某些场景,这是一个不错的选择。
这是一个可能的解决方案。Composite Writer 中的两个 writer。
@Bean
public JdbcBatchItemWriter<XPTO> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<XPTO>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("UPDATE xxxx")
.dataSource(dataSource)
.build();
}
@Bean
public JdbcBatchItemWriter<XPTO> writer2(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<XPTO>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("UPDATE yyyyy")
.dataSource(dataSource)
.build();
}
@Bean
public CompositeItemWriter<XPTO> compositeItemWriter(DataSource dataSource) {
CompositeItemWriter<XPTO> compositeItemWriter = new CompositeItemWriter<>();
compositeItemWriter.setDelegates(Arrays.asList( writer(dataSource), writer2(dataSource)));
return compositeItemWriter;
}
@Bean
protected Step step1(DataSource datasource) {
return this.stepBuilderFactory.get("step1").
<XPTO, XPTO>chunk(1).
reader(reader()).
processor(processor()).
writer(compositeItemWriter(datasource)).
build();
}