我是Spring Batch的新手,并尝试在
中实现批处理作业我查看了this question on StackOverflow,但主要接受的答案主要是实现两个从数据库中读取两次的步骤:
<job id="myJob">
<step id="step1" next="step2">
<tasklet>
<chunk reader="reader" writer="typeAwriter"/>
</tasklet>
</step>
<step id="step2">
<tasklet>
<chunk reader="reader" processor="processor" writer="typeBwriter"/>
</tasklet>
</step>
</job>
除了从MySQL数据库中读取两次之外,还没有更有效的方法吗?例如,如果查询非常大并且拖累系统性能怎么办?
答案 0 :(得分:2)
您需要的是块策略而不是tasklet。 ItemReader将从您的数据库中读取块,处理器将处理您的数据,然后您可以将每个项目发送到可以写入数据库和文件的ItemWriter。这是许多可能的策略之一,我不知道您的业务逻辑的详细信息,但我认为这些信息足以让您按照自己的想法进行操作。
<?xml version="1.0" encoding="UTF-8"?>
<job id="customerJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1">
<chunk item-count="5">
<reader ref="itemReader"/>
<processor ref="itemProcessor"/>
<writer ref="itemWriter"/>
</chunk>
</step>
</job>
这是JSR-352 XML类型,对于Spring,你有相应的方法。
答案 1 :(得分:0)
我会继续回答我自己的问题。有多种方法可以做到这一点,但我发现首先将属性和对象保存到StepExecutionContext
,然后在步骤完成后将它们提升到JobExecutionContext
。它也非常详尽地记录here.
第1步:
在你的作家/读者中声明私人StepExecution
。然后,在您的读/写方法内创建步骤上下文,并将您的数据作为键/值对放入:
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("someKey", someObject);
第2步:
在步骤的bean配置中添加ExecutionContextPromotionListener
。 ExecutionContextPromotionListener
必须包含名为Keys的String[]
属性,其中包含您希望在步骤之外提升到作业范围的键,类似于LinkedIn article中的此实现:
@Bean
public ExecutionContextPromotionListener promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys( new String[] { "entityRef" } );
return listener;
}
第3步: 您还需要在执行步骤之前将StepExecution添加到Writer中:
@BeforeStep
public void saveStepExecution( StepExecution stepExecution ) {
this.stepExecution = stepExecution;
}
第4步:
这将为您的write()
方法提供对stepExecution
实例的访问权限,在该实例中,您可以访问stepContext
以保存数据。例如,你可以写
write() {
... // write logic
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("keyYouWantToPutIn", theCorrespondingDataObject);
}
最后,在下一步中,您可以检索此数据(例如直接来自Spring Batch documentation:
@BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.someObject = jobContext.get("someKey");
}
但是,这一次,请注意它是从jobContext
而不是stepContext
访问的 - 它已被提升!