Pocket

こんにちは!
itouです。

今回は、Javaバッチを効率よく開発できる
Spring Batchというフレームワークをご紹介したいと思います。

Spring Batchとは?

Spring Batchとは、バッチ処理用に定義されたフレームワークです。

「ファイル/データを読み取り、チェックや加工を行い、ファイル/データを出力する。
それを、データがなくなるまで繰り返す。」というようなバッチ特有の制御等を
Javaで実装するのではなく、設定ファイルに別定義することで
効率よく開発することが可能です。

今回は、Spring Batchによる開発をイチから進めていきたいと思います。

Spring Tool Suite(以下、STS)環境設定~Hello worldまで

まず、開発環境の用意をします。
SpringBatchでの開発を楽にするSTSというIDEを導入します。
インストールから、Hello worldの表示まで実施してみましょう。

  1. STSをダウンロードします
    http://www.springsource.org/sts
    spring-tool-suite-3.3.0.RELEASE-e4.3-win32-x86_64-installer.exe
  2. STSをインストールします
    インストール中にJDKのパスを指定します。
    例: C:\Java\jdk1.7.0_25
  3. STSを日本語化します
    http://mergedoc.sourceforge.jp/#pleiades.html
    pleiades_1.4.0.zip
    解凍して、STSインストール先にfeaturesとpluginsを上書き
  4. STS.iniの最終行に「-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar」を追記します。
  5. STSを起動し、日本語化されていることを確認
  6. サンプルプロジェクトを作成します
    「ファイル」→「新規」→「その他」→「Springプロジェクト」
    テンプレートで「Simple Spring Batch Project」を選択
    任意のパッケージトップレベルドメイン名に「com.batch」を設定します。
  7. サンプルプロジェクトを実行します
    「実行の構成」で”Javaアプリケーション”を選択
    メイン・クラスに
    「org.springframework.batch.core.launch.support.CommandLineJobRunner」を指定。
    プログラムの引数に
    「classpath:/launch-context.xml job1」(job1はmodule-context.xmlに定義しているジョブ名)を指定し実行します。
  8. コンソールに「Hello world!」が表示されることを確認します。

サンプルバッチ仕様

それでは、今回サンプルとして作成するバッチ処理の仕様をご説明いたします。

  1. 開始ログを出力する
  2. 下記処理を取込用CSVファイルの処理対象がなくなるまで繰り返し実行する
    ・取込用CSVを読み込む
    ・取込用CSVの内容をチェックし、条件に該当する場合は処理をスキップする
    ・DBに書き込む
  3. 終了ログを出力する

取込用CSV

取込用CSVの内容は下記の通りとなっています。
(後ほど添付しておりますsample.zipに含まれています)

・1.csv

11111,Z
22222,B

・2.csv

33333,S
44444,R

データベース作成

サンプルを実施する為、RDBMSをインストールする必要があります。
今回はMySQLを使用しております。(他のRDBMSも使用可能です)
MySQLでログイン(今回のサンプルではユーザは「root」、パスワードは無しで接続)したら
下記のDDLを実行します。

CREATE DATABASE mydb CHARACTER SET utf8;
use mydb
CREATE TABLE master (
  id INT(10),
  rank VARCHAR(1),
  registration_date date
);

プロジェクトのインポート~実行

今回のサンプルをZIPで圧縮したファイルを添付しております。
sample.zip
下記の手順でインポートと実行ができます。

  1. Eclipseで「ファイル」メニューの中の「インポート」
  2. 「既存プロジェクトをワークスペースへ」を選択
  3. 対象のZIPファイルを指定
  4. 実行構成で「Javaアプリケーション」。下記を設定し実行。
    ・メイン・クラス
    org.springframework.batch.core.launch.support.CommandLineJobRunner
    ・プログラムの引数
    classpath:/launch-context.xml Batch1 file=/Batch1_csv/*.csv

→成功すれば、正常ログの出力とMYSQLにデータが挿入されます。

ファイル構成

ファイル構成を説明します。
スペースの都合上、ファイルパスは省略しております。

ファイル名 説明
1.csv~2.csv ランクデータファイル
MasterMapper.xml マスタテーブルのSQL定義
module-context.xml バッチの構成。処理順と対応するクラスを定義。
batch.properties JDBC情報などを定義
launch-context.xml DataSourceなどを定義
log4j.properties lob4jの設定を定義
Batch1ItemListener.java Batch1のItemListener。ItemReader,ItemProcessor,ItemWriterの前後の処理を定義
Batch1ItemProcessor.java Batch1のItemProcessor
Batch1ItemWriter.java Batch1のItemWriter
Batch1JobExecutionListener.java Batch1のJobExecutionListener。Job実行の前後の処理を定義
Batch1SkipException.java Batch1のJobSkip時の処理(ランクがA~F以外の場合)
JobRepositoryConfiguration.java JOB実行状態をHSQLDB(インメモリモード)に一時保存する為のConfiguration
MySqlConfiguration.java データをMySQLで管理する為のConfiguration
MasterDao.java マスタテーブルを扱う為のDao
MasterMapper.java マスタテーブルを扱う為のMapper
RankFileEntity.java ランクデータファイルを扱う為のEntity
RankFileEntityFieldSetMapper.java ランクデータファイルを扱う為のMapper
LogUtil.java log4jを使用する為のUtil
pom.xml ビルドに関する情報や、依存するライブラリの情報等を定義

module-context.xmlの記載方法

Spring Batchではmodule-context.xmlに
バッチの構成、処理順と対応するクラスなど
「ジョブの起動に必要な情報」を定義しています。
SpringBatchを実装する上で重要なファイルとなります。

こちらを理解できると、Spring Batchの理解もスムーズです。
ジョブフロー図を元に解説していきます。

【ジョブフロー図】

201309SpringBatch

「取込用CSVファイルを読み込んで、チェックし、DBに書き込む。それを繰り返す」
という、メインの処理は、chunkというまとまりの中に定義しております。

<chunk reader="batch1ItemReader" processor="batch1Processor"
writer="batch1Writer" commit-interval="1" skip-limit="100">

reader、processor、writeを繰り返し行い、1件単位でCOMMITしています。
それぞれの実行内容の詳細を確認しましょう。

reader

今回、readerについてはJavaで実装していません。
readerについては、”batch1ItemReader”というidで
module-context.xmlに定義されています。

<bean id="batch1ItemReader"
class="org.springframework.batch.item.file.MultiResourceItemReader"
scope="step">

とありますが、”MultiResourceItemReader”はフォーマットが同一である複数ファイルをまとめて
処理できるSpring Batchのクラスです。
さらに読み進めると・・・

<property name="resources" value="classpath:#{jobParameters['file']}" />

にて、対象のファイルをジョブ引数より取得して処理しています。

prosessor

processorは、
Batch1ItemProcessor.javaに定義されています。

@Component("batch1Processor")

と記載し、module-context.xmlと紐つけております。

writer

writerも同様に

@Component("batch1Writer")

Batch1ItemWriter.javaに定義しております。

listeners

jobタグの中にlistenersを定義することで
JOBの実施前後の処理を定義することができます。
中身は、Batch1JobExecutionListener.javaに定義しております。

<job id="Batch1" xmlns="http://www.springframework.org/schema/batch">
:
 <listeners>
  <listener ref="batch1JobExecutionListener" />
 </listeners>
</job>

listenersはjobの前後以外に、stepの前後にも定義が可能です。

skippable

スキップ時の処理を定義すすることができます。
processorにて、Batch1SkipExceptionを発生させた場合に、処理をスキップさせることができます。
スキップ時の処理は、Batch1JobExecutionListener.javaに定義しております。

<skippable-exception-classes>
<include class="com.example.batch.exception.Batch1SkipException" />
:
</skippable-exception-classes>

まとめ

SpringBatchを使用することで、バッチの基本構造をJavaでコーディングすることなく実装ができました。
まだ書籍やWebの資料が少ないのが難点ですが、シンプルにバッチを実装できるので
バッチ作成の効率化に繋がると考えます。