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の設定について

画像1


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();
           }
       }
   }
}


参考サイト


この記事が気に入ったらサポートをしてみませんか?