我想从输入文件(CSV)预加载一些参考数据作为初始步骤之一(预加载引用)。以下步骤将读取包含需要处理的数据的主输入文件。要处理的每个记录都需要在preload-references步骤中加载lookkup数据。如何才能做到这一点?!参考数据可以与数据记录一起传递到主处理器例程吗?
答案 0 :(得分:0)
为简单起见 - 我们可以假设你需要一个有两个步骤的工作,第一步是将数据传递给第二步吗?如果是这种情况,您可以尝试:
ExecutionContext
。ExecutionContextPromotionListener
。我会用一个部分受official documentation启发的非常天真的例子来支持我的话语。
在第一步中,我们正在阅读"值:
class Step1Reader implements ItemReader<String> {
private AtomicLong counter = new AtomicLong();
@Override
public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
long cnt = counter.incrementAndGet();
return cnt > 5 ? null : String.valueOf(cnt);
}
}
然后&#34;处理&#34;他们通过在最后添加当前时间毫秒:
class Step1Processor implements ItemProcessor<String, String> {
@Override
public String process(String item) throws Exception {
return item + "~" + System.currentTimeMillis();
}
}
最后将它们输出到标准输出中并在上下文中存储一些垃圾(我将忽略多线程问题):
class Step1Writer implements ItemWriter<String> {
private StepExecution stepExecution;
@Override
public void write(List<? extends String> items) throws Exception {
items.forEach(System.out::println);
Integer hashCode = (Integer)stepExecution.getExecutionContext().get("key");
stepExecution.getExecutionContext().put("key", hashCode == null ? items.hashCode() : hashCode + items.hashCode());
}
@BeforeStep
public void saveStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
}
这应输出如下内容:
1~1505055135727
2~1505055135727
3~1505055135727
4~1505055135727
5~1505055135727
到目前为止一切顺利。下一步是&#34;促进&#34;关键:
@Bean
ExecutionContextPromotionListener executionContextPromotionListener()
{
ExecutionContextPromotionListener ret = new ExecutionContextPromotionListener();
ret.setKeys(new String[]{"key"});
return ret;
}
private Step step1() {
return stepBuilderFactory.get("step1")
.<String, String> chunk(10)
.reader(new Step1Reader())
.processor(new Step1Processor())
.writer(new Step1Writer())
.listener(promotionListener)
.build();
}
在第二个甚至更天真的步骤中,可以像这样访问该值:
class Step2Writer implements ItemWriter<String> {
private Object obj;
@Override
public void write(List<? extends String> items) throws Exception {
items.forEach(s -> System.out.println(s + "~" + obj));
}
@BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.obj = jobContext.get("key");
}
}
希望有所帮助: - )
答案 1 :(得分:0)
不推荐将大量数据存储到StepExecutionContext
中,因为此上下文被序列化为SB元数据表,如果数据太大,您将收到数据截断错误。
您可以使用特定的DAO访问此数据,而不是预加载数据,并将访问请求置于缓存下:无需减慢预加载速度,内存消耗将根据您的工作增长。
您还将获得可重启性。