Spring Batch
1つのJobで複数のStepを実行する方法
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public class AppConfig {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public Job job(@Qualifier("step1") Step step1, @Qualifier("step2") Step step2) {
return jobs.get("myJob").start(step1).next(step2).build();
}
@Bean
protected Step step1(ItemReader<Person> reader,
ItemProcessor<Person, Person> processor,
ItemWriter<Person> writer) {
return steps.get("step1")
.<Person, Person> chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
protected Step step2(Tasklet tasklet) {
return steps.get("step2")
.tasklet(tasklet)
.build();
}
}
Spring Batchの実行に必要なテーブル
postgresqlの場合は下記のDDLでテーブルを作っておく必要がある。
ThreadPoolTaskExecutorの設定について
Tasklet間でデータを受け渡す場合
Taskletにセッターを定義し、Jobの設定で変数を受け渡しておくことでTaskletからTaskletへパラメータの受け渡しが可能。
public class FileDeletingTasklet implements Tasklet, InitializingBean {
private Resource directory;
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
File dir = directory.getFile();
Assert.state(dir.isDirectory());
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
boolean deleted = files[i].delete();
if (!deleted) {
throw new UnexpectedJobExecutionException("Could not delete file " +
files[i].getPath());
}
}
return RepeatStatus.FINISHED;
}
public void setDirectoryResource(Resource directory) {
this.directory = directory;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(directory, "directory must be set");
}
}
■Java Configuration
@Bean
public Job taskletJob() {
return this.jobBuilderFactory.get("taskletJob")
.start(deleteFilesInDir())
.build();
}
@Bean
public Step deleteFilesInDir() {
return this.stepBuilderFactory.get("deleteFilesInDir")
.tasklet(fileDeletingTasklet())
.build();
}
@Bean
public FileDeletingTasklet fileDeletingTasklet() {
FileDeletingTasklet tasklet = new FileDeletingTasklet();
tasklet.setDirectoryResource(new FileSystemResource("target/test-outputs/test-dir"));
return tasklet;
}
ExecutorTypeとは
ExecutorTypeの指定方法
@Service
public class BatchService {
private final SqlSession sqlSession;
public BatchService(@Autowired SqlSessionFactory sqlSessionFactory) {
this.sqlSession = new SqlSessionTemplate(sqlSessionFactory, ExecutorType.BATCH);
}
@Transactional
public void insertBatch() {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int count = 0;
int size = users.size();
for (var user : users) {
count++;
userMapper.insert(user);
// 1000件ごとと最後にフラッシュ
if (count % 1000 == 0 || count == size) {
sqlSession.flushStatements();
}
}
}
}
参考サイト
この記事が気に入ったらサポートをしてみませんか?