【问题标题】:How to know if it is the last item in ItemProcessor of SpringBatch如何知道它是否是 Spring Batch 的 ItemProcessor 中的最后一项
【发布时间】:2021-05-25 16:27:08
【问题描述】:

我有以下 ItemProcessor,我需要知道该项目是否是阅读器发送的最后一个项目。这可能吗?

流程是:

  • ItemReader - 从数据库中读取行数(预计数百万行)
  • ItemProcessor - 对每一行执行一些验证,发送到 webservice 并使用 webservice 响应执行更多验证。
  • ItemWriter - 从验证中写入数据库错误,并更改线路状态。

另一个可能的解决方案是 ItemReader 发送 Line 大小为 NUMBER_OF_LINES_TO_CALL_WEBSERVICE 的列表,但我找不到有关如何修改 JpaPagingItemReader 的示例。


    @Override
    public List<Line> process(Line line) {
        

        lineList.add(line);

        if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {

            callWs(lineList);
            
            return lineList;    // goes to ItemWriter to write the response from ws in database 
        }
        
        if( /* TODO if last line */) {      
            
            callWs(lineList);

            return lineList;
        }
        

        return null;
    }
    
    private void callWs(List<Line> lineList){
        ...
        //Get response from webservice and add info to lines
    }

    @Override
    public void afterChunk(ChunkContext chunkContext) {

        if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {
            lineList.clear();
        }

    }
    

读者是JpaPagingItemReader:


    @Bean
    @StepScope
    public JpaPagingItemReader<Line> itemReader(@Qualifier("EntityManagerFactory") EntityManagerFactory entityManagerFactory) {


        String queryStr = "select l from Line l" ;

        return new JpaPagingItemReaderBuilder<Linha>()
                .name("lineReader")
                .entityManagerFactory(entityManagerFactory)
                .queryString(queryStr)
                .pageSize(PAGE_SIZE)
                .build();
    }

【问题讨论】:

  • 你为什么需要它?您能在不参考 Spring Batch 的情况下描述您想要实现的目标吗?您的步骤/工作的输入/输出是什么?有一种方法可以做到这一点,但这取决于这些问题的答案。
  • 我想将 100 个元素的列表中的行分组以发送到 Web 服务,当最后一项发送到处理器时,剩余的行将发送到 Web 服务。

标签: java spring spring-batch itemprocessor


【解决方案1】:

我想将包含 100 个元素的列表中的行分组以发送到 Web 服务,当最后一项发送到处理器时,剩余的行将发送到 Web 服务。

您可以使用块大小为 100 的面向块的步骤。该步骤将为您进行缓冲,并且您可以访问项目列表的过程中的第一个点位于 ItemWriteListener#beforeWrite(List items) 中。因此,您可以使用该侦听器执行 Web 服务调用,也可以在 ItemWriter 本身中执行此操作(如果这是您需要执行的唯一 write 操作)。

一旦你有了项目列表,你就可以对它做任何你想做的事情(即检查最后一个项目,过滤前 99 个项目并将它们发送到网络服务等)。

【讨论】:

  • 这不是唯一的write 操作。 ItemWriter 将在数据库中写入错误。也许最好的方法是更改​​ ItemReader 以发送 100 个元素的列表,您同意吗?但是通过这种方法,我需要帮助来修改ItemReader,也许我可以为此创建一个特定的问题。
  • 在这种情况下,您可以使用ItemWriteListener#beforeWrite 来执行您的Web 服务调用,并使用ItemWriter 来写入数据库。我认为无需修改阅读器,您应该利用步骤实现提供的项目的分块/缓冲。
  • 谢谢,我不知道ItemWriteListener。这种方法看起来不错
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2020-03-26
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
相关资源
最近更新 更多