Spring BatchのChunkモデルのバッチ作成

Spring Batchにおける「chunk（チャンク）」は、バッチ処理の中でデータを効率的に処理するための単位を指します。Spring Batchは、大量のデータを扱う際に、データを小さな単位（チャンク）に分割して処理することで、メモリ効率を向上させ、処理の信頼性を高める仕組みを提供しています。

### Chunkの基本的な概念
Spring Batchでは、データ処理は以下の3つのステップで行われます：

- ItemReader: データの読み取り（例: データベース、ファイル、APIなど）
- ItemProcessor: データの加工や変換
- ItemWriter: データの書き込み（例: データベース、ファイル、APIなど）

これらのコンポーネントを組み合わせることで、バッチ処理の構築が簡単になります。

Spring Batchのサンプルを以下に示します。
このサンプルでは、リスト形式のデータを入力として受け取り、加工して、コンソールに出力するだけのバッチ処理を実装します。

### プロジェクトのセットアップ
build.gradleの設定
以下の依存関係を追加します。
```java
plugins {
    id 'org.springframework.boot' version '2.6.7'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```
### サンプルバッチ処理の実装
メインクラスBatchApplicationクラスを作成します。
```java
package com.example.batch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class, args);
    }
}
```
### バッチ構成クラス
BatchConfigクラスを作成します。
```java
package com.example.batch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    public BatchConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
    }

    // ItemReader: 入力データを提供
    @Bean
    public ItemReader<String> reader() {
        return new ItemReader<>() {
            private final List<String> data = Arrays.asList("John", "Jane", "Foo", "Bar");
            private int index = 0;

            @Override
            public String read() {
                if (index < data.size()) {
                    return data.get(index++);
                } else {
                    return null; // nullを返すと処理が終了
                }
            }
        };
    }

    // ItemProcessor: データを加工
    @Bean
    public ItemProcessor<String, String> processor() {
        return item -> "Hello, " + item + "!";
    }

    // ItemWriter: 加工されたデータを出力
    @Bean
    public ItemWriter<String> writer() {
        return items -> items.forEach(System.out::println);
    }

    // Stepの定義
    @Bean
    public Step step1(ItemReader<String> reader, ItemProcessor<String, String> processor, ItemWriter<String> writer) {
        return stepBuilderFactory.get("step1")
                .<String, String>chunk(2) // チャンクサイズを2に設定
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .build();
    }

    // Jobの定義
    @Bean
    public Job job(Step step1) {
        return jobBuilderFactory.get("job")
                .start(step1)
                .build();
    }
}
```
### 実行
Gradleでプロジェクトを実行します。
```
./gradlew bootRun
```
### 実行結果
コンソールに以下のような出力が表示されます。
```
2024-12-19 23:27:52.821 DEBUG 3272 --- [           main] o.s.batch.repeat.support.RepeatTemplate  : Repeat is complete according to policy and result value.
Hello, John!
Hello, Jane!
・・・
2024-12-19 23:27:52.839 DEBUG 3272 --- [           main] o.s.batch.repeat.support.RepeatTemplate  : Repeat is complete according to policy and result value.
Hello, Foo!
Hello, Bar!
・・・
```
### 解説
1. ItemReader:

- 入力データを提供します。この例では、List<String>形式のデータを用意し、1件ずつ返します。
- read()メソッドがnullを返すと、Spring Batchは処理を終了します。
2. ItemProcessor:

- データを加工します。この例では、入力データに「Hello, 」を付加しています。
3. ItemWriter:

- 加工されたデータを出力します。この例では、コンソールに出力しています。
4. Step:

- chunk(2)でチャンクサイズを2に設定しています。つまり、2件のデータをまとめて処理します。
5. Job:

- 1つのステップ（step1）を実行するジョブを定義しています。

このサンプルの特徴
- データベースやファイルを使用しない: 入力データはリスト形式で直接提供され、出力はコンソールに表示されます。
- シンプルな構成: Spring Batchの基本的な構成（ItemReader、ItemProcessor、ItemWriter）を学ぶのに適しています。
- 拡張可能: このサンプルを基に、データベースやファイルを使用したバッチ処理に拡張できます。