【Spring Batch】~Stepについて~

## 前回の内容
[前回の記事](https://qiita.com/yommy/items/9156e5478c62053b4ba7)ではSpring Batchの簡単な概要とJobについて説明しましたが、今回はStepについて書いていければと思います。

## Stepの役割
まずSpring Batchの基本的な流れのイメージを持つことが大事なので、前回も張った下記の図を頭でイメージしてから読み進めてください。![spring-batch-reference-model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669426/c3e3d71e-27d7-dad5-4a3c-9ad52dfcdd24.png)

Spring BatchのStepは、Jobの中で実行される一連の処理を定義する単位のことを言います。
Jobは複数のStepから構成され、それぞれのStepが特定のタスクを実行します。

Stepは主に以下の３つのフェーズに分かれます。
```
1. ItemReader: データを読み取る
2. ItemProcessor: データを処理する
3. ItemWriter: データを書き出す
 ```

 バッチ処理のJobを「クッキーを作る工場」に例えて説明します。
 工場の仕事（Job）は、原材料からクッキーをっ作ることです。この工場では、複数のステップ(Step)を経てクッキーが完成します。
 ```
⓵原材料の調達(ItemReader)
・倉庫から小麦粉、佐藤、バター、卵などのクッキーの原材料を取り出す
《DB（倉庫）からデータ（材料）を１つずつ取り出す》

⓶記事の準備(ItemProcessor)
・取り出した原材料を混ぜてクッキー生地を作る
《データの加工や変換を行う》

⓷クッキーの成形と焼成(ItemWriter)
・作った生地をクッキーの形に成形し、オーブンを焼きます。最終的にクッキーが完成します。
《加工・変換されたデータを最終的な出力先（DBやファイル）に書き出す》
 ```

 上記のようにそれぞれのフェーズで特定のタスクを実行するイメージです。
 ちなみにItemProcessorは必須ではないので、データの変換がなどが不要な場合はItemReaderとItemWriterのみを作成すればいいです。

 実際のStepの構文としては下記のようになります。
 （データの読み取りと書き出しを想定しているためItemProcessorは省略しています）

 ```Java: Stepの実装
 @Configuration
public class SampleConfig{

    @Autowired
    private DataSource dataSource;

    @Bean
    public Job sampleJob(JobRepository jobRepository,PlatformTransactionManager transactionManager) {
        return new JobBuilder("sampleJob", jobRepository)
            .start(step1(jobRepository, transactionManager))
            .next(step2(jobRepository, transactionManager))
            .build();
    }

    @Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManeger){
            return new StepBuilder("step1", jobRepository)
            .<I, O>chunk(100, transactionManeger) //chunkサイズは自由に設定してOKです
            .reader(itemReader1())
            .writer(itemWriter1())
            .build();
    }

    @Bean
    public JdbcCursorItemReader<I> itemReader1() {
        return new JdbcCursorItemReaderBuilder<I>()
            .dataSource(dataSource)
            .name("〇〇")
            .sql("SELECT - FROM - ")
            .rowMapper(new CustomRowMapper())// RowMapperを設定して結果セットをマッピング
            .build();
    }

    @Bean
    public JdbcBatchItemWriter<O> itemWriter1() {
        return new JdbcBatchItemWriterBuilder<O>()
            .dataSource(dataSource)
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<O>())
            .sql("INSERT INTO -( ~ ) VALUES( ~ )")
            .build();
    }
           

    //step2は省略
    @Bean
    public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManeger){
        //今回は何も実装していません
    }
    
 ```

 こんな感じにはなるのですか、それって何をしているの？みたいなところもあると思うのでピックアップして簡単に説明を書いておきます。

 **▶DateSource**
 Javaアプリケーションがデータベースと通信するための重要なインターフェース

 **▶JobRepository**
 実行されたジョブの状態を追跡し管理します。これには、ジョブの開始時刻、終了時刻、ステップの実行状況、エラーの処理などが含まれます

 **▶PlatformTransactionManager**
 トランザクションを開始し、データベースへの操作が正常に完了した場合にトランザクションをコミットしたり、エラーが出た際にはロールバックしトランザクション内で行われたすべての操作を取り消します

  **▶JdbcCursorItemReader<I>**
  JDBCを使用してデータベースからデータを取得するため、大量のデータを処理する場合はJdbcCursorItemReader<I>を使用するのがおすすめ

  **▶.rowMapper()**
  データベースから取得した結果セット（ResultSet）をJavaオブジェクトにマッピングしています
  
  **▶JdbcBatchItemWriter<O>**
  JDBCを使用してデータベースにデータを書き込む。これも大量のデータを処理する場合におすすめ

   **▶.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<O>())**
   JavaオブジェクトのフィールドからSQLパラメータを自動的に生成してくれます

  ## まとめ
  今回はJob,Step(ItemReader, ItemProcesor)を使用した簡単な流れを説明しましたが、Spring Batchを使用するにあたり、流れをイメージできるかはとても大事になってくるかと思います。
今回は記載しなかったItemProcessorは自分でロジックを組み立てる必要があるので、少し難しいかもしれませんが学習中の方はぜひチャレンジしてみてください！
ありがとうございました。