【问题标题】:Multiple itemwriters in Spring batchSpring批处理中的多个项目编写器
【发布时间】:2013-09-25 18:40:17
【问题描述】:

我目前正在编写一个 Spring 批处理,我正在读取大量数据,对其进行处理,然后我希望将这些数据传递给 2 个写入器。一位作家将简单地更新数据库,而第二位作家将写入一个 csv 文件。

我打算编写自己的自定义编写器,并在 customItemWriter 中注入两个 itemWriter,并在 customItemWriter 的 write 方法中调用两个项目编写器的 write 方法。这种方法正确吗?是否有任何可用的 ItemWriter 实现满足我的要求?

提前致谢

【问题讨论】:

    标签: java spring spring-batch


    【解决方案1】:

    您可以使用 Spring 的 CompositeItemWriter 并将您的所有作者委托给它。
    这是configuration example

    【讨论】:

    【解决方案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;
          }
      

      【讨论】:

      【解决方案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 吗?当然!
        猜你喜欢
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 2019-03-16
        • 1970-01-01
        • 1970-01-01
        • 2020-09-07
        • 2020-03-31
        相关资源
        最近更新 更多