将当前步骤输出传递给下一步并写入flatfile

时间:2015-10-30 01:19:16

标签: spring-batch

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

进入Spring Batch,我将有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.

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

2 个答案:

答案 0 :(得分:2)

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

中的键

读者:

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;
    }
}

答案 1 :(得分:0)

通常,你不想这样做。

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

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

这是批处理的关键概念之一:无论需要处理多少数据,都可以使用恒定的内存。