Step之间传递数据有两种方式:
一、
通过step_execution 或者 job_execution来在不同step中传递数据.但是如果数据量大的话,这将不是一种好的方式.因为spring batch默认会通过job repository将 setp_execution和job_execution进行持久化。 如果把要传递的数据放在setp_execution或者job_execution中进行传递,job repository会把数据持久化到数据库的日志表中,对于大量数据不适合。
二、
创建一个bean,通过bean来传递数据,假设step1中放入的数据,从step2中得到
1、创建一个bean,用于传递数据
@Component
public class Users {
private List<User> listUsers = new ArrayList<User>();
public List<User> getListUsers() {
return listUsers;
}
public void setListUsers(List<User> listUsers) {
this.listUsers = listUsers;
}
}
2、创建step1,放入数据
@Component
public class StepDemo1 implements Tasklet{
@Autowired
private Users users;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
List<User> listUsers = new ArrayList<>();
User user1 = new User(1, "zhangsan", 20);
User user2 = new User(2, "lisi", 25);
User user3 = new User(3, "wanger", 30);
listUsers.add(user1);
listUsers.add(user2);
listUsers.add(user3);
users.setListUsers(listUsers);
return RepeatStatus.FINISHED;
}
}
3、创建step2,用于取出数据
@Component
public class StepDemo2 implements Tasklet{
/*bean在容器中默认是单例的,所以step2中的users与step1中的users是同一个对象,故里面的数据也是一致的*/
@Autowired
private Users users;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
List<User> listUsers = users.getListUsers();
listUsers.forEach((x) -> {System.out.println(x);});
return RepeatStatus.FINISHED;
}
}
由于step2与step1中的users bean是共享的,所以数据是一致的。
4、在resource目录下创建application.xml,配置批量
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource-oracle" />
<property name="transactionManager" ref="transactionManager" />
</bean>
<!--用真实数据库配置代替-->
<bean id="dataSource-oracle" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.passwd}" />
<property name="driverClassName" value="${database.driver}" />
<property name="validationQuery" value="${database.validationQuery}" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource-oracle" />
</bean>
<batch:job id="jobTest">
<batch:step id="step1" next="step2">
<batch:tasklet ref="stepDemo1" />
</batch:step>
<batch:step id="step2">
<batch:tasklet ref="stepDemo2"></batch:tasklet>
</batch:step>
</batch:job>
5、创建测试程序
@EnableBatchProcessing
@SpringBootApplication
public class BatchDemoApp {
public static void main(String[] args) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
Set<Object> set = new HashSet<>();
set.add("classpath:applicationContext.xml");
SpringApplication app = new SpringApplication(BatchDemoApp.class);
app.setSources(set);
ApplicationContext ctx = app.run(args);
JobLauncher launcher = (JobLauncher) ctx.getBean("jobLauncher");
Job job = (Job) ctx.getBean("jobTest");
JobParametersBuilder builder = new JobParametersBuilder().addString("myKey", "myKey_value");
System.out.println("builder.toJobParameters() : " + builder.toJobParameters());
JobExecution jobExecution = launcher.run(job, builder.toJobParameters());
ExitStatus status = jobExecution.getExitStatus();
if (status.getExitCode().equals(ExitStatus.COMPLETED.getExitCode())) {
System.out.println("批量成功!");
}else {
System.out.println("批量失败!");
}
}
}
运行测试程序,在step2中输出如下数据,获得了step1中放入的数据。
User [id=1, name=zhangsan, age=20]
User [id=2, name=lisi, age=25]
User [id=3, name=wanger, age=30]