将当前步骤输出传递给下一步并写入平面文件

Pass current step output to next step and write to flatfile

我需要准备两套List并将它们写入FlatFile。第一组只是简单地从 SQL 中检索,在写入 FlatFile 之前将进行一些字符串格式化。另一组数据稍微复杂一些,首先我需要从一些 table 中获取数据并插入到临时 table 中。数据将从这个临时文件 table 中获取,同样需要执行一些字符串格式化并更新临时文件。最后,将两个设置数据写入FlatFile。

进入Spring批次,我有3个步骤。

First Step
   First Reader read from DB
   First Processor string formatting
   First Writer write into file

Second Step
   BeforeRead Retrieve and Insert to Temp table
   Second Reader read from temp table 
   Second Processor string formatting and update temp table status
   Second Writer write into file

Third Step
  MUltiResourceItemReader read two files
  Write into Final File

Tasklet
  Delete both file and purge the temp table.

我现在的问题是第一步和第二步如果我不写入文件,可以将数据传递到第三步吗?

通常情况下,您不想这样做。

如果您只有几百个条目,它就可以了。例如,您可以编写一个实现 reader 和编写器接口的特殊 class。写入时,只需将数据存储在列表中,读取时,从列表中读取条目。只需将其实例化为一个 bean,并在两个步骤(1 和 2)中将其用作您的编写器。通过简单地使写入方法同步,它甚至可以在并行执行步骤 1 和 2 时工作。

但问题是,此解决方案无法根据您的输入数据量进行扩展。您读取的数据越多,您需要的内存就越多。

这是批处理的关键概念之一:无论必须处理的数据量如何,都具有恒定的内存使用率。

考虑到 Hansjoerg Wingeier 所说的,下面是 ListItemWriter 和 ListItemReader 的自定义实现,它们允许您定义 name 属性。此 属性 用作将列表存储在 JobExecutionContext.

中的键

reader :

public class CustomListItemReader<T> implements ItemReader<T>, StepExecutionListener {

    private String name;
    private List<T> list;

    @Override
    public T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

        if (list != null && !list.isEmpty()) {
            return list.remove(0);
        }
        return null;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        list = (List<T>) stepExecution.getJobExecution().getExecutionContext().get(name);
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        return null;
    }

    public void setName(String name) {  
        this.name = name;
    }
}

作者:

public class CustomListItemWriter<T> implements ItemWriter<T>, StepExecutionListener {

    private String name;
    private List<T> list = new ArrayList<T>();

    @Override
    public void write(List<? extends T> items) throws Exception {
        for (T item : items) {
            list.add(item);
        }
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {}

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        stepExecution.getJobExecution().getExecutionContext().put(name, list);
        return null;
    }

    public void setName(String name) {  
        this.name = name;
    }
}