Spring

Spring Boot + Spring Batchで簡単なバッチサービスを作ってみる

Springのチュートリアルページをもとに、Spring Boot + Spring Batchで簡単なバッチサービスを作ってみました。具体的には、CSVファイルを読み込み、ファイル内の文字列を加工してデータベースに格納するバッチです。今回使用するデータベース(HSQLDB)はメモリ上で利用するものなので、事前にMySQLやOracleといったクライアントを用意する必要はありません。

環境

準備

まずは作業用のディレクトリを作成し、そのディレクトリに移動します。

以下のようなディレクトリ構造になっているはずです。

続いて、build.gradleを作成します。依存性にSpring BatchとHSQLDBを指定しているのがポイントです。

build.gradle

データを作成する

インプットファイルとなるCSVファイルを作成します。first name(名), last name(姓)の順に並んでいます。

src/main/resources/sample-data.csv

テーブルを作成するためのSQLスクリプトを作成します。さきほど作成したCSVデータを格納する用のテーブルですね。

src/main/resources/schema-all.sql

ちなみにSpring Bootでは、src/main/resources直下にschema.sqldata.sqlを配備することで、起動時にDDLやDMLを自動で実行してくれます。OracleやMySQLといったデータベースプラットフォーム形式のSQL文を実行したい場合は、schema-oracle.sqldata-mysql.sqlのように指定してやればOKです。今回のschema-all.sqlのように-allをつけることでどのプラットフォームでも実行されるようになります。

ビジネスクラスを作成する

CSVファイルの1レコードに対応するクラスを作成します。

src/main/java/hello/Person.java

中間処理を作成する

ファイル内のfirst name(名), last name(姓)を大文字に加工するクラスを作成します。一連のバッチ処理の「CSVファイルを読み込む→中間処理を行う→データベースに格納する」の中の「中間処理を行う」がこのクラスの役割です。

src/main/java/hello/PersonItemProcessor.java

このクラスはSpring BatchのItemProcessorインタフェースを実装しています。この実装により、後述するバッチジョブ内のコードが簡単に書けるようになります。

バッチジョブをまとめる

このクラスで実際のバッチジョブをまとめていきます。Spring Batchにはビジネスロジックに集中するための便利なユーティリティクラスが用意されているようです。

src/main/java/hello/BatchConfiguration.java

@EnableBatchProcessingアノテーションをつけることで、ジョブをサポートする多くのBean(Springが管理するインスタンス)が使えるようになります。

コードが長いので細分化して見ていきます。まずは、「CSVファイルを読み込む」、「中間処理を行う」、「データベースに格納する」の部分です。

readerItemReaderを生成します。これは、sample-data.csvを探し出し、CSVファイル内の1行ずつをPersonオブジェクトに変換します。

processorは先ほど作成した中間処理クラスであるPersonItemProcessorのインスタンスを生成します。姓名を大文字に変換するやつですね。

writerItemWriterを生成します。@EnableBatchProcessingの機能を使って、メモリ上のデータベース内のテーブルに出力内容を書き込んでいます。

ここからはジョブの定義について見ていきます。

1つめのメソッドはジョブを定義し、2つめのメソッドはステップを定義しています。Spring Batchでは、ジョブはステップから構成されます。各ステップにはreader, processor, writerが含まれています。

ジョブ定義では、実行状態を維持するデータベースを使用するためにincrementerが必要なようです。flowで実行するステップを定義しています。

ステップ定義では、一度に書き込むデータ量を定義しています。 今回の場合、一度に最大10個のレコードを書き込みます(chunk(10))。あとは、 reader, processor, writerを定義してやればOKです。

ちなみに、<Person,Person>の箇所は、インプットとアウトプットの型を表しています。今回の場合、インプットがItemReader<Person>で、アウトプットがItemWriter<Person>にあたります。

以上で長かったコードの説明は終了です。

おまけとして、バッチ処理が完了した際に動作するリスナークラスを作成します。

src/main/java/hello/JobCompletionNotificationListener.java

アプリケーションを実行可能にする

Spring Bootを起動するクラスを作成してやればバッチサービスの出来上がりです!

src/main/java/hello/Application.java

あとは、ビルドして実行するだけです。以下のようにデータが書き込まれ、バッチ完了時のリスナーログが出力されていればOKです。

お疲れさまでしたー。

まとめ

Spring Bootで簡単なバッチサービスを作ってみた感想としては、「フレームワーク化されていて使いやすそう」でした。あと、公式のチュートリアルだけに説明がわかりやすく理解しやすかったです。実際に手を動かしてみるとより理解が深まったので、本記事やチュートリアルを参考にバッチサービスを作ってみてはいかがでしょうか。

Spring Batchも良さげですが、個人的にはCommandLineRunnerを使った方法の方がシンプルで好きです。CommandLineRunnerについては以下の記事でまとめています。

Spring Bootで簡単なコマンドラインアプリケーションを作成してみる - Reasonable Code

参考リンク

-Spring

© 2024 Reasonable Code