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

Spring batch 将当前步骤输出传递到下一步骤并写入平面文件,spring-batch,Spring Batch,我需要准备两套列表并将它们写入平面文件。第一组将只是简单地从SQL中检索,在写入FlatFile之前,将执行一些字符串格式设置。另一组数据有点复杂,首先我需要从某个表中获取数据并插入到临时表中。数据将从此临时表中获取,同样需要执行一些字符串格式设置并更新临时文件。最后,两者都将数据写入平面文件 进入春季批次,我将有3个步骤 First Step First Reader read from DB First Processor string formatting First W

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

进入春季批次,我将有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.

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

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

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

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


这是批处理的关键概念之一:无论必须处理的数据量有多大,都要保持恒定的内存使用。

考虑到Hansjoerg Wingeier所说的,下面是ListItemWriter和ListItemReader的自定义实现,它允许您定义一个
名称
属性。此属性用作将列表存储在
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;
    }
}
公共类CustomListItemReader实现ItemReader、StepExecutionListener{
私有字符串名称;
私人名单;
@凌驾
public T read()引发异常、UnexpectedInputException、ParseException、NontTransientResourceException{
if(list!=null&&!list.isEmpty()){
返回列表。删除(0);
}
返回null;
}
@凌驾
预处理前的公共无效(步骤执行步骤执行){
list=(list)stepExecution.getJobExecution().getExecutionContext().get(name);
}
@凌驾
公共出口状态后步骤(步骤执行步骤执行){
返回null;
}
公共无效集合名(字符串名){
this.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;
    }
}
公共类CustomListItemWriter实现ItemWriter、StepExecutionListener{
私有字符串名称;
私有列表=新的ArrayList();
@凌驾
公共空白写入(列表)