如何在没有 xml 的 Java 配置中使用具有不同数据并具有两个 JdbcBatchItemWritter 的 Spring 批处理 CompositeItemWriter

Posted

技术标签:

【中文标题】如何在没有 xml 的 Java 配置中使用具有不同数据并具有两个 JdbcBatchItemWritter 的 Spring 批处理 CompositeItemWriter【英文标题】:How to use Spring batch CompositeItemWriter with different data and having two JdbcBatchItemWritter and in Java configurations without xml 【发布时间】:2019-04-26 21:03:46 【问题描述】:

以下是在作业中初始化的步骤代码。

@Bean
public Step stepOne() 
    return stepBuilderFactory.get("stepOne")
            .<EmployeeDTO, EmployeeDTO> chunk(1)
            .reader(readerOne())
            .processor(processorOne())
            .writer(compositeWriter())
            .build();

下面是用于写入数据的复合编写器。

@Bean
public CompositeItemWriter<EmployeeDTO> compositeWriter()

    return new CompositeWriter();


public class CompositeWriter extends CompositeItemWriter<EmployeeDTO> 

   @Autowired
   private DataSource dataSource;

   List<EmployeeDTO> insert;
   List<EmployeeDTO> update;

   @Override
   public void write(List<? extends EmployeeDTO> arg0) throws Exception 
       CompositeItemWriter<EmployeeDTO> compositeItemWriter = new CompositeItemWriter<>();
       compositeItemWriter.setDelegates(Arrays.asList(insertW(),updateW()));
   

   private JdbcBatchItemWriter<EmployeeDTO> insertW() throws Exception
       JdbcBatchItemWriter<EmployeeDTO> batchItemWriter = new JdbcBatchItemWriter<>();
       batchItemWriter.setDataSource(dataSource);
       batchItemWriter.setSql("");
       batchItemWriter.write(insert);
       return batchItemWriter;
   

   private JdbcBatchItemWriter<EmployeeDTO> updateW() throws Exception
       JdbcBatchItemWriter<EmployeeDTO> batchItemWriter = new JdbcBatchItemWriter<>();
       batchItemWriter.setDataSource(dataSource);
       batchItemWriter.setSql("");
       batchItemWriter.write(update);
       return batchItemWriter;
   

【问题讨论】:

【参考方案1】:

您的配置存在几个问题:

你不需要在 writer 上调用 write 方法(batchItemWriter.write(insert)batchItemWriter.write(update)),Spring Batch 会做。 没有必要继承CompositeItemWriter。您可以创建一个实例并在其中注册委托编写者。 代理编写者需要在步骤中注册为流。

您的情况如下:

1。定义委托作者

@Bean
public JdbcBatchItemWriter<EmployeeDTO> insertW() throws Exception
   JdbcBatchItemWriter<EmployeeDTO> batchItemWriter = new JdbcBatchItemWriter<>();
   batchItemWriter.setDataSource(dataSource);
   batchItemWriter.setSql("");
   return batchItemWriter;


@Bean
public JdbcBatchItemWriter<EmployeeDTO> updateW() throws Exception
   JdbcBatchItemWriter<EmployeeDTO> batchItemWriter = new JdbcBatchItemWriter<>();
   batchItemWriter.setDataSource(dataSource);
   batchItemWriter.setSql("");
   return batchItemWriter;

2。在CompositeItemWriter 中注册代表

@Bean
public CompositeItemWriter<EmployeeDTO> compositeItemWriter() 
    CompositeItemWriter<EmployeeDTO> compositeItemWriter = new CompositeItemWriter<>();
    compositeItemWriter.setDelegates(Arrays.asList(insertW(), updateW()));
    return compositeItemWriter;

3。在步骤中将代理注册为流(如果他们实现了 ItemSteam)

@Bean
public Step stepOne() 
    return stepBuilderFactory.get("stepOne")
            .<EmployeeDTO, EmployeeDTO> chunk(1)
            .reader(readerOne())
            .processor(processorOne())
            .writer(compositeItemWriter())
            .stream(insertW())
            .stream(updateW())
            .build();

希望这会有所帮助。

【讨论】:

感谢@Mahmoud Ben Hassine 的回复。您能否告诉我如何将以下列表传递给上述示例中的代表 List insert;列表 更新; 如果作者之一失败会发生什么(异常)。另一个是成功(承诺)还是我会回滚? 复合是一个写者链,如果其中一个写失败,后续的写者将不会被调用,见github.com/spring-projects/spring-batch/blob/…,事务将为复合写者回滚。 @MahmoudBenHassine - 我们已经看到,如果在第一个 writer 中出现任何异常,那么在我们的案例中 call 不会委托给第二个和第三个 writer。我们应该怎么做 ?由于 CompositeIteamWriter 确实提供了此功能,因此使用 ItemStreamWriter 但仍然没有运气 JdbcBatchItemWriter 没有实现 ItemStream,我认为不能将它用于流.. 所以这是一个不好的例子

以上是关于如何在没有 xml 的 Java 配置中使用具有不同数据并具有两个 JdbcBatchItemWritter 的 Spring 批处理 CompositeItemWriter的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中使用 SAX Parser 检查 xml 标签是不是具有属性?

如何在不使用带有java配置的spring的orm.xml中注册实体监听器?

如何使用 xml 配置文件、JAVA、Spring 安全性对 LDAP 用户进行身份验证

spring 注解是有啥作用

SpringBoot配置介绍

使用Java方式替换XML配置Spring