Spring批处理中的多个项目编写器
Posted
技术标签:
【中文标题】Spring批处理中的多个项目编写器【英文标题】:Multiple itemwriters in Spring batch 【发布时间】:2013-09-25 18:40:17 【问题描述】:我目前正在编写一个 Spring 批处理,我正在读取大量数据,对其进行处理,然后我希望将这些数据传递给 2 个写入器。一位作家将简单地更新数据库,而第二位作家将写入一个 csv 文件。
我打算编写自己的自定义编写器,并在 customItemWriter 中注入两个 itemWriter,并在 customItemWriter 的 write 方法中调用两个项目编写器的 write 方法。这种方法正确吗?是否有任何可用的 ItemWriter 实现满足我的要求?
提前致谢
【问题讨论】:
【参考方案1】:您可以使用 Spring 的 CompositeItemWriter 并将您的所有作者委托给它。 这是configuration example。
【讨论】:
这个例子真的很有帮助。 嗨 Pratik - 你能分享示例代码吗?我已经筋疲力尽地无法解决这个问题。 这条线断了:-( @Andy 这是新网址:github.com/spring-projects/spring-batch/blob/master/…。我更新了答案【参考方案2】:您不一定必须像示例中那样使用 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;
【讨论】:
【参考方案3】:你是对的。 SB 很大程度上基于委托,因此使用CompositeItemWriter 是满足您需求的正确选择。
【讨论】:
你知道如何通过多线程编写器来实现这一点吗?【参考方案4】: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;
【讨论】:
这取自 spring 参考文档:docs.spring.io/spring-batch/docs/current/reference/html/…【参考方案5】:根据您的需要,另一种选择是扩展 Writer 类并在其中添加功能。例如,我有一个项目,我在其中扩展 HibernateItemWriter,然后覆盖 write(List items)。然后,我将正在写入的对象与 sessionFactory 一起发送到 Writer 的 doWrite 方法:doWrite(sessionFactory, filteredRecords)。
所以在上面的例子中,我可以在我的扩展类中写入 csv 文件,然后 HibernateItemWriter 会写入数据库。显然,这对于本示例可能并不理想,但对于某些场景,这是一个不错的选择。
【讨论】:
【参考方案6】:这是一个可能的解决方案。 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();
【讨论】:
根据 qtn,一个应该写入 DB,而另一个写入 CSV。但是您的示例仅显示更新数据库 我的例子的更新只是展示了如何更新两个不同的表。可以是数据库和 CSV 吗?当然!以上是关于Spring批处理中的多个项目编写器的主要内容,如果未能解决你的问题,请参考以下文章
如果写入元素发生异常,如何正确处理 Spring Batch 步骤编写器异常以便继续处理其他元素?
Spring Boot Spring Batch:没有 Spring 批处理元数据表的多个 DataSource
Spring MockRestServiceServer 处理多个异步请求
OpenShift 中的 Spring 批处理 JDBCPagingItemReader、ThreadPoolTaskExecutor 和多个 pod