本記事では、SpringBatchフレームワークとOceanBaseデータベースを使用して、テーブルの作成、データの挿入、クエリなどの基本的な操作を実現するアプリケーションの構築方法を紹介します。
前提条件
- OceanBaseデータベースがインストール済みであること。
- JDK 1.8とMavenがインストール済みであること。
- IntelliJ IDEAがインストール済みであること。
説明
本ドキュメントでコードを実行するために使用したツールはIntelliJ IDEA 2021.3.2 (Community Edition)です。個人の好みに応じて、適切なツールを選択してサンプルコードを実行することもできます。
手順
説明
本記事で示す操作手順は、Windows環境に基づいています。他のOS環境やコンパイラを使用している場合は、手順が若干異なる場合があります。
- OceanBaseデータベースの接続文字列を取得します。
java-oceanbase-springbatchプロジェクトをIDEAにインポートします。java-oceanbase-springbatchプロジェクトのデータベース接続情報を修正します。java-oceanbase-springbatchプロジェクトを実行します。
ステップ1:OceanBaseデータベースの接続文字列を取得する
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続文字列を取得します。
obclient -hxx.xx.xx.xx -P2883 -uroot@sys#cluster -p**** -Aデプロイ済みのOceanBaseデータベースに基づいて、以下のURLに対応する情報を入力します。
説明
application.propertiesファイルには、このURL情報が必要です。jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=utf-8パラメータ説明:
host:OceanBaseデータベースへの接続IPアドレス。ODP接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。port:OceanBaseデータベースへの接続ポート。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。schema_name:アクセスするスキーマ名です。user_name:-uパラメータで指定し、形式はユーザー@テナント#クラスタ名またはユーザー名@SERVICE:サービス名です。ユーザー@テナント#クラスタ名の形式を使用する場合、デフォルトのテナントはsys、管理者ユーザーはrootです。データベースに直接接続する場合、クラスタ名を省略できますが、ODP接続の場合は入力する必要があります。password:アカウントのパスワードです。characterEncoding:文字エンコーディングです。
その他のURLパラメータの詳細については、データベースURLを参照してください。
ステップ2:java-oceanbase-springbatchプロジェクトをIDEAにインポートする
IntelliJ IDEAを開き、**File > Open...**オプションを選択します。

表示されたOpen File or Projectウィンドウで、対応するプロジェクトファイルを選択し、OKをクリックしてプロジェクトファイルのインポートを完了します。
IntelliJ IDEAは、プロジェクト内のさまざまなファイルの種類を自動的に認識し、Projectツールウィンドウで、プロジェクトのディレクトリ構造、ファイルリスト、モジュールリスト、依存関係などの情報を確認できます。Projectツールウィンドウは通常、IntelliJ IDEA画面の左側にあり、デフォルトでは開いています。Projectツールウィンドウが閉じている場合は、メニューバーのView > Tool Windows > Projectをクリックするか、ショートカットキーAlt + 1を使用して再表示できます。
説明
IntelliJ IDEAでプロジェクトをインポートすると、IntelliJ IDEAはプロジェクト内のpom.xmlファイルを自動的に検出し、ファイルに記述されている依存関係に基づいて必要な依存ライブラリを自動的にダウンロードし、プロジェクトに追加します。
プロジェクトの状況を確認します。

ステップ3:java-oceanbase-springbatch プロジェクトのデータベース接続情報を修正する
ステップ1:OceanBaseデータベースの接続文字列を取得する の情報に基づいて、application.properties ファイル内のデータベース接続情報を修正します。
例:
- データベースドライバーの名前:
com.mysql.cj.jdbc.Driver - OBServerノードのIPアドレスは
10.10.10.1です。 - アクセスポートは2881を使用します。
- アクセスするスキーマ名は
testです。 - テナントの接続アカウントは
root@mysql001です。mysql001はOceanBaseデータベースで作成されたMySQLモードのユーザーテナントであり、rootはテナントmysql001のユーザー名です。 - パスワードは
******です。
サンプルコードは以下のとおりです:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:oceanbase://10.10.10.1:2881/test?characterEncoding=utf-8
spring.datasource.username=root@mysql001
spring.datasource.password=******
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.batch.job.enabled=false
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
ステップ4:java-oceanbase-springbatch プロジェクトを実行する
AddDescPeopleWriterTest.javaファイルを実行します。- プロジェクト構造の src > test > java から
AddDescPeopleWriterTest.javaファイルを見つけます。 - ツールメニューバーで Run > Run... > AddDescPeopleWriterTest.testWrite を選択するか、右上の 緑色の三角形 を直接クリックして実行します。
- IDEAのコンソールでプロジェクトのログ情報と出力結果を確認します。
people_desc テーブルのデータ: PeopleDESC [name=John, age=25, desc=This is John with age 25] PeopleDESC [name=Alice, age=30, desc=This is Alice with age 30] Batch Job execution completed.- プロジェクト構造の src > test > java から
AddPeopleWriterTest.javaファイルを実行します。- プロジェクト構造の src > test > java から
AddPeopleWriterTest.javaファイルを見つけます。 - ツールメニューバーで Run > Run... > AddPeopleWriterTest.testWrite を選択するか、右上の 緑色の三角形 を直接クリックして実行します。
- IDEAのコンソールでプロジェクトのログ情報と出力結果を確認します。
people テーブルのデータ: People [name=zhangsan, age=27] People [name=lisi, age=35] Batch Job execution completed.- プロジェクト構造の src > test > java から
よくある質問
1. 接続タイムアウト
接続タイムアウトの問題が発生した場合、JDBC URLに接続タイムアウトパラメータを設定できます。
jdbc:mysql://host:port/database?connectTimeout=30000&socketTimeout=60000
2. 文字セットの問題
正しい文字エンコーディングを確保するために、JDBC URLに正しい文字セットパラメータを設定します。
jdbc:mysql://host:port/database?characterEncoding=utf8&useUnicode=true
3. SSL接続
OceanBaseデータベースとのSSL接続を有効にするには、JDBC URLに以下のパラメータを追加します。
jdbc:mysql://host:port/database?useSSL=true&requireSSL=true
4. アカウントパスワードの特殊文字
ユーザー名やパスワードに特殊文字(例:#)が含まれている場合は、URLエンコードが必要です。
String encodedPassword = URLEncoder.encode(password, "UTF-8");
注意
MySQL Connector/J 8.xを使用する場合は、アカウントのパスワードにシャープ記号(#)が含まれないようにしてください。含まれていると、接続エラーが発生する可能性があります。
プロジェクトコードについて
java-oceanbase-springbatch をクリックしてプロジェクトコードをダウンロードします。これは java-oceanbase-springbatch という名前の圧縮ファイルです。
解凍すると、java-oceanbase-springbatch という名前のフォルダが作成されます。ディレクトリ構造は以下のとおりです:
│ pom.xml
│
├─.idea
│
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─oceanbase
│ │ │ └─example
│ │ │ └─batch
│ │ │ │──BatchApplication.java
│ │ │ │
│ │ │ ├─config
│ │ │ │ └─BatchConfig.java
│ │ │ │
│ │ │ ├─model
│ │ │ │ ├─People.java
│ │ │ │ └─PeopleDESC.java
│ │ │ │
│ │ │ ├─processor
│ │ │ │ └─AddPeopleDescProcessor.java
│ │ │ │
│ │ │ └─writer
│ │ │ ├─AddDescPeopleWriter.java
│ │ │ └─AddPeopleWriter.java
│ │ │
│ │ └─resources
│ │ └─application.properties
│ │
│ └─test
│ └─java
│ └─com
│ └─oceanbase
│ └─example
│ └─batch
│ ├─config
│ │ └─BatchConfigTest.java
│ │
│ ├─processor
│ │ └─AddPeopleDescProcessorTest.java
│ │
│ └─writer
│ ├─AddDescPeopleWriterTest.java
│ └─AddPeopleWriterTest.java
│
└─target
ファイルの説明:
pom.xml:Mavenプロジェクトの設定ファイルで、プロジェクトの依存関係、プラグイン、ビルドなどの情報が含まれます。.idea:IDE(統合開発環境)で使用されるディレクトリで、プロジェクト関連の設定情報を格納します。src:プロジェクトのソースコードを格納するディレクトリです。main: 主要なソースコードとリソースファイルを格納するディレクトリ。java: Javaソースコードを格納するディレクトリ。com.oceanbase.example.batch: パッケージ名。BatchApplication.java:アプリケーションのエントリクラスで、mainメソッドが含まれます。config:設定クラスを格納するフォルダです。BatchConfig.java:アプリケーションの設定クラスで、アプリケーションのプロパティや動作を設定するために使用されます。model:データモデルクラスを格納するフォルダです。People.java:人員データのモデルクラスです。PeopleDESC.java:人員DESCデータのモデルクラスです。processor:プロセッサクラスを格納するフォルダです。AddPeopleDescProcessor.java:人員DESC情報を追加するプロセッサクラスです。writer:ライタークラスを格納するフォルダです。AddDescPeopleWriter.java:人員DESC情報を書き込むライタークラスです。AddPeopleWriter.java:人員情報を書き込むライタークラスです。resources:リソースフォルダで、アプリケーションの設定ファイルやその他の静的リソースファイルが含まれます。application.properties:アプリケーションの設定ファイルで、アプリケーションのプロパティを設定するために使用されます。test: テストコードとリソースファイルを格納するディレクトリ。BatchConfigTest.java:アプリケーション設定クラスのテストクラスです。AddPeopleDescProcessorTest.java:人員DESC情報を追加するプロセッサのテストクラスです。AddDescPeopleWriterTest.java:人員DESC情報を書き込むライターのテストクラスです。AddPeopleWriterTest.java:人員情報を書き込むライターのテストクラスです。target: コンパイル済みのClassファイル、Jarパッケージなどのファイルを格納するディレクトリ。
pom.xmlコードの紹介
説明
単にサンプルを検証したい場合は、デフォルトのコードをそのまま使用し、修正は不要です。以下の説明に従って、ご自身の要件に応じて pom.xml ファイルを変更することもできます。
pom.xml 設定ファイルの内容は以下のとおりです:
ファイル宣言ステートメント。
このファイルがXMLファイルであり、使用しているXMLバージョンが
1.0、文字エンコーディング方式がUTF-8であることを宣言します。コード:
<?xml version="1.0" encoding="UTF-8"?>POMの名前空間とPOMモデルバージョンを設定します。
xmlnsを使用して、POMの名前空間をhttp://maven.apache.org/POM/4.0.0と指定します。xmlns:xsiを使用して、XML名前空間をhttp://www.w3.org/2001/XMLSchema-instanceと指定します。xsi:schemaLocationを使用して、POMの名前空間をhttp://maven.apache.org/POM/4.0.0と指定し、POMのXSDファイルの場所をhttps://maven.apache.org/xsd/maven-4.0.0.xsdと指定します。<modelVersion>要素を使用して、このPOMファイルで使用するPOMモデルバージョンを4.0.0と指定します。
コード:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
</project>
親要素情報を設定します。
<groupId>を使用して、親要素の識別子をorg.springframework.bootと指定します。<artifactId>を使用して、親要素の依存関係をspring-boot-starter-parentと指定します。<version>を使用して、親要素のバージョン番号を2.7.11と指定します。relativePathを使用して、親要素のパスが空であることを示します。
コード:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/>
</parent>
基本情報を設定します。
<groupId>を使用して、プロジェクト識別子をcom.oceanbaseと指定します。<artifactId>を使用して、プロジェクトの依存関係をjava-oceanbase-springbootと指定します。<version>を使用して、プロジェクトのバージョン番号を0.0.1-SNAPSHOTと指定します。descriptionを使用して、プロジェクト情報をDemo project for Spring Batchと紹介します。
コード:
<groupId>com.oceanbase</groupId>
<artifactId>java-oceanbase-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java-oceanbase-springbatch</name>
<description>Demo project for Spring Batch</description>
Javaバージョンを設定します。
プロジェクトで使用するJavaバージョンを1.8と指定します。
コード:
<properties> <java.version>1.8</java.version> </properties>コア依存関係を設定します。
依存関係の所属組織を
org.springframework.boot、名前をspring-boot-starterと指定します。この依存関係により、Spring Bootがデフォルトでサポートするコンポーネント依存関係を使用でき、Web、データ処理、セキュリティ、Testなどの機能をサポートします。コード:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>依存関係の所属組織を
org.springframework.boot、名前をspring-boot-starter-jdbcと指定します。この依存関係により、Spring Bootが提供するJDBC関連機能、接続プールやデータソースの設定などを使用できます。コード:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>依存関係の所属組織を
org.springframework.boot、名前をspring-boot-starter-test、作用範囲をtestと指定します。この依存関係により、JUnit、Mockito、Hamcrestなど、Spring Bootが提供するテストフレームワークとツールを使用できます。コード:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>依存関係の所属組織を
com.oceanbase、名前をoceanbase-client、バージョン番号を2.4.12と指定します。この依存関係により、OceanBaseが提供するクライアント機能、接続、クエリ、トランザクションなどを使用できます。
**コード:**
```xml
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.12</version>
</dependency>
```
- 依存関係の所属組織を
org.springframework.boot、名前をspring-boot-starter-batchと指定します。この依存関係により、Spring Bootが提供するバッチ処理機能を使用できます。
**コード:**
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
```
依存関係の所属組織を
org.springframework.boot、名前をspring-boot-starter-data-jpaと指定します。この依存関係により、JPAを使用したデータアクセスに必要な依存関係と設定を使用できます。Spring Boot Starter Data JPAはSpring Bootのスターターです。コード:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>依存関係の所属組織を
org.apache.tomcat、名前をtomcat-jdbcと指定します。この依存関係により、Tomcatが提供するJDBC接続プール機能、接続プールの設定、接続の取得と解放、接続の管理などを使用できます。コード:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency>依存関係の所属テストフレームワークを
junit、名前をjunit、バージョン番号を4.10、作用範囲をtestと指定します。この依存関係により、JUnit単体テストの依存関係設定を追加できます。コード:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency>依存関係の所属組織を
javax.activation、名前をjavax.activation-api、バージョン番号を1.2.0と指定します。この依存関係により、Java Activation Framework(JAF)ライブラリを導入できます。コード:
<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>依存関係の所属組織を
jakarta.persistence、名前をjakarta.persistence-api、バージョン番号を2.2.3と指定します。この依存関係により、Jakarta Persistence APIの依存関係設定を追加できます。 コード:<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>2.2.3</version> </dependency>Mavenプラグインを設定します。
依存関係の所属組織を org.springframework.boot、名前を spring-boot-maven-plugin と指定します。このプラグインは、Spring Bootアプリケーションを実行可能なJARパッケージまたはWARパッケージにパッケージ化し、直接実行するために使用されます。
コード:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.propertiesファイルの紹介
application.properties ファイルは、データベース接続およびその他の関連パラメータを設定するために使用されます。データベースドライバー、接続URL、ユーザー名、パスワードなどが含まれます。また、JPA(Java Persistence API)とSpring Batchに関する設定、およびログレベルの設定も含まれています。
データベース接続の設定
spring.datasource.driverを使用して、データベースドライバーをcom.mysql.cj.jdbc.Driverと指定します。これはOceanBaseデータベースとの接続を確立するために使用されます。spring.datasource.urlを使用して、データベース接続用のURLを指定します。spring.datasource.usernameを使用して、データベース接続用のユーザー名を指定します。spring.datasource.passwordを使用して、データベース接続用のパスワードを指定します。
コード:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8 spring.datasource.username=user_name spring.datasource.password=******JPAの設定
spring.jpa.show-sqlを使用して、ログにSQLステートメントを表示するかどうかを指定します。trueに設定するとSQLステートメントが表示されます。spring.jpa.hibernate.ddl-autoを使用して、HibernateのDDL操作動作を指定します。ここではupdateに設定されており、アプリケーション起動時にデータベース構造を自動的に更新することを意味します。
コード:
spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=updateSpring Batchの設定
spring.batch.job.enabledを使用して、Spring Batchジョブを有効にするかどうかを指定します。ここではfalseに設定されており、バッチ処理ジョブの自動実行を無効にすることを意味します。コード:
spring.batch.job.enabled=false説明
Spring Batchにおいて、
spring.batch.job.enabledプロパティはバッチ処理ジョブの実行動作を制御します。spring.batch.job.enabled=true(デフォルト値):Spring Bootアプリケーション起動時に、定義されたすべてのバッチ処理ジョブを自動的に実行することを意味します。つまり、アプリケーション起動時に、Spring Batchは定義されたすべてのジョブを自動的に検出し実行します。spring.batch.job.enabled=false:バッチ処理ジョブの自動実行を無効にすることを意味します。これは通常、開発またはテスト環境で使用されるか、ジョブの実行を手動で制御したい場合に使用されます。falseに設定すると、ジョブはアプリケーション起動時に自動的に実行されません。RESTインターフェースやコマンドラインなど、他の方法で手動でジョブをトリガーできます。
spring.batch.job.enabled=falseを設定することで、アプリケーション起動時にジョブが自動的に実行されるのを回避し、バッチ処理ジョブの実行タイミングをより柔軟に制御できます。ログの設定
logging.level.org.springframeworkを使用して、SpringフレームワークのログレベルをINFOに指定します。logging.level.com.exampleを使用して、アプリケーションのカスタムコードのログレベルをDEBUGに指定します。
コード:
logging.level.org.springframework=INFO logging.level.com.example=DEBUG
BatchApplication.javaファイルの紹介
BatchApplication.java ファイルは、Spring Bootアプリケーションのエントリーファイルです。
BatchApplication.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
SpringApplicationクラス:Spring Bootアプリケーションを起動するために使用されます。SpringBootApplicationアノテーション:このクラスをSpring Bootアプリケーションのエントリーとしてマークするために使用されます。
コード:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;BatchApplicationクラスの定義。@SpringBootApplicationアノテーションを使用して、BatchApplicationクラスをSpring Bootアプリケーションのエントリーとしてマークします。BatchApplicationクラスでは、アプリケーションのエントリーポイントとして静的なmainメソッドを定義しています。このメソッド内で、SpringApplication.runメソッドを使用してSpring Bootアプリケーションを起動します。さらに、バッチ処理ジョブを実行するためのrunBatchJobという名前のメソッドも定義しています。コード:
@SpringBootApplication public class BatchApplication { public static void main(String[] args) { SpringApplication.run(BatchApplication.class, args); } public void runBatchJob() { } }
BatchConfig.javaファイルの紹介
BatchConfig.java ファイルは、バッチ処理ジョブのステップ、リーダー、プロセッサ、ライターなどのコンポーネントを設定するために使用されます。
BatchConfig.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Peopleクラス:データベースから読み取った人員情報を格納するために使用されます。PeopleDESCクラス:人員情報を変換または処理した後の説明情報を格納するために使用されます。AddPeopleDescProcessorクラス:読み取ったPeopleオブジェクトをPeopleDESCオブジェクトに変換するItemProcessorインターフェースの実装クラスです。AddDescPeopleWriterクラス:PeopleDESCオブジェクトをターゲット位置に書き込むItemWriterインターフェースの実装クラスです。Jobインターフェース:バッチ処理ジョブを表します。Stepインターフェース:ジョブ内のステップを表します。EnableBatchProcessingアノテーション:Spring Batchの設定アノテーションで、Spring Batch処理機能を有効化および設定するために使用されます。JobBuilderFactoryクラス:ジョブの作成と設定に使用されます。StepBuilderFactoryクラス:ステップの作成と設定に使用されます。RunIdIncrementerクラス:Spring Batchの実行ID(Run ID)インクリメンターで、ジョブを実行するたびに実行IDを増加させるために使用されます。ItemProcessorインターフェース:読み取ったアイテムを処理または変換するために使用されます。ItemReaderインターフェース:データソースからアイテムを読み取るために使用されます。ItemWriterインターフェース:処理または変換後のアイテムを指定されたターゲット位置に書き込むために使用されます。JdbcCursorItemReaderクラス:データベースからデータを読み取り、カーソル結果セットを返すために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。Beanアノテーション:Beanの作成と設定に使用されます。ComponentScanアノテーション:コンポーネントスキャンを行うパッケージまたはクラスを指定するために使用されます。Configurationアノテーション:クラスを設定クラスとしてマークするために使用されます。EnableAutoConfigurationアノテーション:Spring Bootの自動設定を有効にするために使用されます。SpringBootApplicationアノテーション:このクラスをSpring Bootアプリケーションのエントリポイントとしてマークするために使用されます。DataSourceインターフェース:データベースへの接続を表すために使用されます。
コード:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import com.oceanbase.example.batch.processor.AddPeopleDescProcessor; import com.oceanbase.example.batch.writer.AddDescPeopleWriter; 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.core.launch.support.RunIdIncrementer; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.database.JdbcCursorItemReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.BeanPropertyRowMapper; import javax.sql.DataSource;BatchConfigクラスの定義。これはシンプルなSpring Batchバッチ処理ジョブです。データの読み取り、処理、書き込みの方法を定義し、これらのステップを1つのジョブとしてカプセル化します。Spring Batchのアノテーションと自動設定機能を使用し、設定クラス内の各
@Beanメソッドを通じて対応するコンポーネントインスタンスを作成し、step1でこれらのコンポーネントを使用してデータの読み取り、処理、書き込みを完了します。@Configurationにより、このクラスが設定クラスであることを示します。@EnableBatchProcessingにより、Spring Batchの処理機能を有効にします。このアノテーションは、JobRepository、JobLauncherなどの必要なbeanを自動的に作成します。@SpringBootApplicationはSpring Bootアプリケーションのメインクラスアノテーションであり、Spring Bootアプリケーションの起動ポイントです。@ComponentScanにより、コンポーネントスキャンを行うパッケージを指定し、Springに対してこのパッケージとサブパッケージ内のすべてのコンポーネントをスキャンして登録するよう指示します。@EnableAutoConfigurationにより、Spring Bootアプリケーションのインフラストラクチャを自動設定します。
コード:
@Configuration @EnableBatchProcessing @SpringBootApplication @ComponentScan("com.oceanbase.example.batch.writer") @EnableAutoConfiguration public class BatchConfig { }@Autowiredアノテーションの定義。@Autowiredアノテーションを使用して、JobBuilderFactory、StepBuilderFactory、DataSourceをBatchConfigクラスのメンバ変数に注入します。JobBuilderFactoryはジョブ(Job)を作成および設定するためのファクトリクラス、StepBuilderFactoryはステップ(Step)を作成および設定するためのファクトリクラス、DataSourceはデータベース接続を取得するためのインターフェースです。コード:
@Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private DataSource dataSource;@Beanアノテーションの定義。@Beanアノテーションを使用して、バッチ処理ジョブのリーダー、プロセッサ、ライター、ステップ、ジョブを作成するためのいくつかのメソッドを定義します。peopleReaderメソッドにより、ItemReaderコンポーネントのインスタンスを作成します。このコンポーネントはJdbcCursorItemReaderを使用してデータベース内のPeopleオブジェクトデータを読み取ります。データソースdataSourceを設定し、データベース行をPeopleオブジェクトにマッピングするRowMapperを設定し、SQLクエリステートメントをSELECT * FROM peopleに設定します。addPeopleDescProcessorメソッドにより、ItemProcessorコンポーネントのインスタンスを作成します。このコンポーネントはAddPeopleDescProcessorを使用してPeopleオブジェクトを処理し、PeopleDESCオブジェクトに変換して返します。addDescPeopleWriterメソッドにより、ItemWriterコンポーネントのインスタンスを作成します。このコンポーネントはAddDescPeopleWriterを使用してPeopleDESCオブジェクトをターゲット位置に書き込みます。step1メソッドにより、Stepコンポーネントのインスタンスを作成します。このステップの名前はstep1です。stepBuilderFactory.getでステップビルダーを取得し、リーダーをItemReaderコンポーネントに、プロセッサをItemProcessorコンポーネントに、ライターをItemWriterコンポーネントに設定します。chunkサイズを10に設定し、最後にbuildを呼び出して設定済みのStepをビルドして返します。importJobメソッドにより、Jobコンポーネントのインスタンスを作成します。このジョブの名前はimportJobです。jobBuilderFactory.getでジョブビルダーを取得し、インクリメンターをRunIdIncrementerに設定します。ジョブflowの最初のステップをStepに設定し、最後にbuildを呼び出して設定済みのJobをビルドして返します。コード:
@Bean public ItemReader<People> peopleReader() { JdbcCursorItemReader<People> reader = new JdbcCursorItemReader<>(); reader.setDataSource((javax.sql.DataSource) dataSource); reader.setRowMapper(new BeanPropertyRowMapper<>(People.class)); reader.setSql("SELECT * FROM people"); return reader; } @Bean public ItemProcessor<People, PeopleDESC> addPeopleDescProcessor() { return new AddPeopleDescProcessor(); } @Bean public ItemWriter<PeopleDESC> addDescPeopleWriter() { return new AddDescPeopleWriter(); } @Bean public Step step1(ItemReader<People> reader, ItemProcessor<People, PeopleDESC> processor, ItemWriter<PeopleDESC> writer) { return stepBuilderFactory.get("step1") .<People, PeopleDESC>chunk(10) .reader(reader) .processor(processor) .writer(writer) .build(); } @Bean public Job importJob(Step step1) { return jobBuilderFactory.get("importJob") .incrementer(new RunIdIncrementer()) .flow(step1) .end() .build(); }
People.javaファイルの紹介
People.java ファイルは、人の情報を表す People クラスのデータモデルを作成します。このクラスには、name と age の2つのプライベートメンバ変数と、それぞれに対応する getter および setter メソッドが含まれています。最後に、オブジェクトの情報を出力するために toString メソッドをオーバーライドしています。ここで、name は人の名前を表し、age は人の年齢を表します。getter および setter メソッドを使用して、これらの属性の値を取得および設定できます。
このクラスの役割は、バッチ処理プログラムの入力と出力において、データの格納と伝達の方法を提供することです。バッチ処理の読み取りおよび書き込み操作では、People オブジェクトを使用してデータを格納し、setter メソッドでデータを設定し、getter メソッドでデータを取得します。
コード:
public class People {
private String name;
private int age;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
// Getters and setters
}
PeopleDESC.javaファイルの紹介
PeopleDESC.java ファイルは、人物の情報を表す PeopleDESC クラスのデータモデルを作成します。PeopleDESC クラスには name、age、desc、id の4つの属性があり、それぞれ人の名前、年齢、説明、識別子を表します。このクラスには、属性の値にアクセスおよび設定するための対応する getter と setter メソッドが含まれています。toString メソッドをオーバーライドして、名前、年齢、説明を含むクラスの文字列表現を返します。
People クラスと同様に、PeopleDESC クラスもバッチ処理プログラムの入力と出力において、データの格納と受け渡しに使用されます。
コード:
public class PeopleDESC {
private String name;
private int age;
private String desc;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "PeopleDESC [name=" + name + ", age=" + age + ", desc=" + desc + "]";
}
}
AddPeopleDescProcessor.javaファイルの紹介
AddPeopleDescProcessor.java ファイルは、ItemProcessor インターフェースを実装する AddPeopleDescProcessor というクラスを定義しており、People オブジェクトを PeopleDESC オブジェクトに変換するために使用されます。
AddPeopleDescProcessor.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Peopleクラス:データベースから読み取った人員情報を格納するために使用されます。PeopleDESCクラス:人員情報を変換または処理した後の説明情報を格納するために使用されます。ItemProcessorインターフェース:読み取ったアイテムを処理または変換するために使用されます。
コード:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import org.springframework.batch.item.ItemProcessor;AddPeopleDescProcessorクラスの定義。ItemProcessorインターフェースを実装するAddPeopleDescProcessorクラスは、PeopleオブジェクトをPeopleDESCオブジェクトに変換し、バッチ処理プロセスにおける入力データの処理ロジックを実装します。このクラスの
processメソッドでは、まずPeopleDESCオブジェクトdescを作成し、次にitemパラメータからPeopleオブジェクトの属性(nameとage)を取得してdescオブジェクトに設定します。同時に、descオブジェクトのdesc属性にも値を代入します。この代入ロジックは、Peopleオブジェクトの属性に基づいて説明情報を生成するものです。最後に、処理後のPeopleDESCオブジェクトを返します。コード:
public class AddPeopleDescProcessor implements ItemProcessor<People, PeopleDESC> { @Override public PeopleDESC process(People item) throws Exception { PeopleDESC desc = new PeopleDESC(); desc.setName(item.getName()); desc.setAge(item.getAge()); desc.setDesc("This is " + item.getName() + " with age " + item.getAge()); return desc; } }
AddDescPeopleWriter.javaファイルの紹介
AddDescPeopleWriter.java ファイルは、ItemWriter インターフェースを実装した AddDescPeopleWriter クラスを定義しており、People オブジェクトをデータベースに書き込むために使用されます。
AddDescPeopleWriter.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
PeopleDESCクラス:人員情報を変換または処理した後の説明情報を格納するために使用されます。ItemWriterインターフェース:処理または変換後のアイテムを指定されたターゲットに書き込むために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。JdbcTemplateクラス:SQLステートメントを実行するメソッドを提供します。Listインターフェース:クエリ結果の集合を操作するために使用されます。
コード:
import com.oceanbase.example.batch.model.PeopleDESC; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import java.util.List;AddDescPeopleWriterクラスの定義。@Autowiredアノテーションを使用してJdbcTemplateインスタンスを自動注入し、データ書き込み時にこのインスタンスを使用してデータベース操作を実行します。コード:
@Autowired private JdbcTemplate jdbcTemplate;writeメソッドでは、渡されたList<? extends PeopleDESC>を走査し、各PeopleDESCオブジェクトを順次取り出します。まず、既存のpeople_descテーブルを削除するためにDROP TABLE people_descSQLステートメントを実行します。次に、id、name、age、descriptionの4列を含むpeople_descテーブルを作成するために、CREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))SQLステートメントを実行します。その後、INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)SQLステートメントを使用して、各PeopleDESCオブジェクトのプロパティ値をpeople_descテーブルに挿入します。コード:
@Override public void write(List<? extends PeopleDESC> items) throws Exception { // 既存のテーブルを削除 jdbcTemplate.execute("DROP TABLE people_desc"); // テーブル作成ステートメント String createTableSql = "CREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))"; jdbcTemplate.execute(createTableSql); for (PeopleDESC item : items) { String sql = "INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)"; jdbcTemplate.update(sql, item.getId(), item.getName(), item.getAge(), item.getDesc()); } }
AddPeopleWriter.javaファイルの紹介
AddPeopleWriter.java ファイルは、ItemWriter インターフェースを実装する AddDescPeopleWriter クラスを定義しており、PeopleDESC オブジェクトをデータベースに書き込むために使用されます。
AddPeopleWriter.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Peopleクラス:データベースから読み取った人員情報を格納するために使用されます。ItemWriterインターフェース:処理または変換後のアイテムを指定されたターゲットに書き込むために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。JdbcTemplateクラス:SQLステートメントを実行するメソッドを提供します。Componentアノテーション:このクラスをSpringコンポーネントとしてマークするために使用されます。Listインターフェース:クエリ結果の集合を操作するために使用されます。
コード:
import com.oceanbase.example.batch.model.People; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.List;AddPeopleWriterクラスの定義。@Autowiredアノテーションを使用してJdbcTemplateインスタンスを自動注入し、データ書き込み時にこのインスタンスを使用してデータベース操作を実行します。コード:
@Autowired private JdbcTemplate jdbcTemplate;writeメソッドでは、渡されたList<? extends People>を走査し、各Peopleオブジェクトを順次取り出します。まず、既存のpeopleテーブルを削除するためにDROP TABLE peopleSQLステートメントを実行します。次に、nameとageの2つの列を含むpeopleテーブルを作成するためにCREATE TABLE people (name VARCHAR2(255), age INT)SQLステートメントを実行します。その後、INSERT INTO people (name, age) VALUES (?, ?)SQLステートメントを使用して、各Peopleオブジェクトのプロパティ値をpeopleテーブルに挿入します。コード:
@Override public void write(List<? extends People> items) throws Exception { // 既存のテーブルを削除 jdbcTemplate.execute("DROP TABLE people"); // テーブル作成ステートメント String createTableSql = "CREATE TABLE people (name VARCHAR2(255), age INT)"; jdbcTemplate.execute(createTableSql); for (People item : items) { String sql = "INSERT INTO people (name, age) VALUES (?, ?)"; jdbcTemplate.update(sql, item.getName(), item.getAge()); } }
BatchConfigTest.javaファイルの紹介
BatchConfigTest.java ファイルは、JUnitを使用したテストクラスであり、Spring Batchのジョブ設定をテストするために使用されます。
BatchConfigTest.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Assertクラス:テスト結果のアサーションに使用されます。Testアノテーション:テストメソッドをマークするために使用されます。RunWithアノテーション:テストランナーを指定するために使用されます。Jobインターフェース:バッチ処理ジョブを表します。JobExecutionクラス:バッチ処理ジョブの実行を表します。JobParametersクラス:バッチ処理ジョブのパラメータを表します。JobParametersBuilderクラス:バッチ処理ジョブのパラメータを構築するために使用されます。JobLauncherインターフェース:バッチ処理ジョブを起動するために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。SpringBootTestアノテーション:テストクラスをSpring Bootテストとして指定するために使用されます。SpringRunnerクラス:テストランナーをSpringRunnerとして指定するために使用されます。
コード:
import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.batch.runtime.BatchStatus; import java.util.UUID;BatchConfigTestクラスの定義。SpringBootTestアノテーションとSpringRunnerランナーを使用することで、Spring Bootの統合テストを実行できます。testJobメソッドでは、JobLauncherTestUtilsヘルパークラスを使用してバッチ処理ジョブを起動し、アサーションを使用してジョブの実行状態を検証します。@Autowiredアノテーションを使用してJobLauncherTestUtilsインスタンスを自動注入します。コード:
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;@Testアノテーションを使用して、testJobメソッドをテストメソッドとしてマークします。このメソッドでは、まずJobParametersオブジェクトを作成し、次にjobLauncherTestUtils.launchJobメソッドを使用してバッチ処理ジョブを起動し、Assert.assertEqualsメソッドを使用してジョブの実行状態がCOMPLETEDであることをアサートします。コード:
@Test public void testJob() throws Exception { JobParameters jobParameters = new JobParametersBuilder() .addString("jobParam", "paramValue") .toJobParameters(); JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters); Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); }@Autowiredアノテーションを使用してJobLauncherインスタンスを自動注入します。コード:
@Autowired private JobLauncher jobLauncher;@Autowiredアノテーションを使用してJobインスタンスを自動注入します。コード:
@Autowired private Job job;バッチ処理ジョブの起動を支援するために、
JobLauncherTestUtilsという名前の内部クラスを定義します。このクラスには、バッチ処理ジョブを起動するためのlaunchJobメソッドが定義されています。このメソッドでは、jobLauncher.runメソッドを使用してジョブを起動し、ジョブの実行結果を返します。コード:
private class JobLauncherTestUtils { public JobExecution launchJob(JobParameters jobParameters) throws Exception { return jobLauncher.run(job, jobParameters); } }
AddPeopleDescProcessorTest.javaファイルの紹介
AddPeopleDescProcessorTest.java ファイルは、JUnitを使用したテストクラスであり、Spring Batchのジョブ設定をテストするために使用されます。
AddPeopleDescProcessorTest.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Peopleクラス:データベースから読み取った人員情報を格納するために使用されます。PeopleDESCクラス:人員情報を変換または処理した後の説明情報を格納するために使用されます。Assertクラス:テスト中の期待結果と実際の結果が一致しているかどうかを検証するために使用されます。Testアノテーション:テストメソッドをマークするために使用されます。RunWithアノテーション:テストランナーを指定するために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。SpringBootTestアノテーション:テストクラスをSpring Bootテストとして指定するために使用されます。SpringRunnerクラス:テストランナーをSpringRunnerとして指定するために使用されます。
コード:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;AddPeopleDescProcessorTestクラスの定義。SpringBootTestアノテーションとSpringRunnerランナーを使用して、Spring Bootの統合テストを行います。@Autowiredアノテーションを使用して、AddPeopleDescProcessorインスタンスを自動注入します。コード:
@Autowired private AddPeopleDescProcessor processor;@Testアノテーションを使用して、testProcessメソッドをテストメソッドとしてマークします。このメソッドでは、まずPeopleオブジェクトを作成し、次にprocessor.processメソッドを使用してそのオブジェクトを処理し、結果をPeopleDESCオブジェクトに代入します。コード:
@Test public void testProcess() throws Exception { People people = new People(); people.setName("John"); people.setAge(25); PeopleDESC desc = processor.process(people); }
AddDescPeopleWriterTest.javaファイルの紹介
AddDescPeopleWriterTest.java ファイルは、JUnitを使用したテストクラスであり、AddDescPeopleWriter の書き込みロジックをテストするために使用されます。
AddDescPeopleWriterTest.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
PeopleDESCクラス:人員情報を変換または処理した後の説明情報を格納するために使用されます。Assertクラス:テスト結果をアサートするために使用されます。Testアノテーション:テストメソッドをマークするために使用されます。RunWithアノテーション:テストランナーを指定するために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。SpringBootTestアノテーション:テストクラスをSpring Bootテストとして指定するために使用されます。JdbcTemplateクラス:SQLステートメントを実行するメソッドを提供します。SpringRunnerクラス:テストランナーをSpringRunnerとして指定するために使用されます。ArrayListクラス:空のリストを作成するために使用されます。Listインターフェース:クエリ結果セットを操作するために使用されます。
コード:
import com.oceanbase.example.batch.model.PeopleDESC; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List;AddDescPeopleWriterTestクラスの定義。SpringBootTestアノテーションとSpringRunnerランナーを使用して、Spring Bootの統合テストを行います。@Autowiredを使用したインスタンスの注入。@Autowiredアノテーションを使用して、AddPeopleDescProcessorおよびJdbcTemplateインスタンスを自動注入します。コード:
@Autowired private AddDescPeopleWriter writer; @Autowired private JdbcTemplate jdbcTemplate;@Testを使用したデータの挿入と出力のテスト。@Testアノテーションを使用して、testWriteメソッドをテストメソッドとしてマークします。このメソッドでは、まず空のpeopleDescListリストを作成し、リストに2つのPeopleDESCオブジェクトを追加します。次に、writer.writeメソッドを使用して、リスト内のデータをデータベースに書き込みます。その後、jdbcTemplateを使用してクエリステートメントを実行し、people_descテーブルからデータを取得します。そして、アサーションステートメントを使用してデータの正確性を検証します。最後に、クエリ結果をコンソールに出力し、ジョブの実行完了メッセージを出力します。people_descテーブルへのデータ挿入。 まず、空のPeopleDESCオブジェクトリストpeopleDescListを作成します。次に、2つのPeopleDESCオブジェクトdesc1とdesc2を作成し、それぞれのプロパティ値を設定します。desc1とdesc2をpeopleDescListリストに追加します。その後、writerのwriteメソッドを呼び出し、peopleDescList内のオブジェクトをデータベースのpeople_descテーブルに書き込みます。次に、JdbcTemplateを使用してクエリステートメントSELECT COUNT(*) FROM people_descを実行し、people_descテーブルのレコード数を取得して変数countに代入します。最後に、Assert.assertEqualsメソッドを使用してアサーションを行い、countの値が2と等しいかどうかを検証します。コード:
List<PeopleDESC> peopleDescList = new ArrayList<>(); PeopleDESC desc1 = new PeopleDESC(); desc1.setId(1); desc1.setName("John"); desc1.setAge(25); desc1.setDesc("This is John with age 25"); peopleDescList.add(desc1); PeopleDESC desc2 = new PeopleDESC(); desc2.setId(2); desc2.setName("Alice"); desc2.setAge(30); desc2.setDesc("This is Alice with age 30"); peopleDescList.add(desc2); writer.write(peopleDescList); String selectSql = "SELECT COUNT(*) FROM people_desc"; int count = jdbcTemplate.queryForObject(selectSql, Integer.class); Assert.assertEquals(2, count);people_descテーブル内のデータの出力。 まず、JdbcTemplateを使用してクエリステートメントSELECT * FROM people_descを実行し、lambda式を使用してクエリ結果を処理します。lambda式では、rs.getInt、rs.getStringなどのメソッドを使用してクエリ結果セットのフィールド値を取得し、フィールド値を新しく作成したPeopleDESCオブジェクトに設定します。新しく作成した各PeopleDESCオブジェクトを結果リストresultDescに追加します。その後、people_desc テーブル内のデータ:という一行のメッセージを出力し、forループを使用してresultDescリスト内の各PeopleDESCオブジェクトを走査し、System.out.printlnを使用して各オブジェクトの内容を出力します。最後に、ジョブの実行完了メッセージを出力します。コード:
List<PeopleDESC> resultDesc = jdbcTemplate.query("SELECT * FROM people_desc", (rs, rowNum) -> { PeopleDESC desc = new PeopleDESC(); desc.setId(rs.getInt("id")); desc.setName(rs.getString("name")); desc.setAge(rs.getInt("age")); desc.setDesc(rs.getString("description")); return desc; }); System.out.println("people_desc テーブル内のデータ:"); for (PeopleDESC desc : resultDesc) { System.out.println(desc); } // ジョブ実行完了後のメッセージを出力 System.out.println("Batch Job execution completed.");
AddPeopleWriterTest.javaファイルの紹介
AddPeopleWriterTest.java ファイルは、JUnitを使用してテストを行うクラスであり、AddPeopleWriterTest の書き込みロジックをテストするために使用されます。
AddPeopleWriterTest.java ファイルのコードは、主に以下の部分で構成されています:
他のクラスとインターフェースのインポート。
このファイルには以下のインターフェースとクラスが含まれていることを宣言します:
Peopleクラス:データベースから読み取った人員情報を格納するために使用されます。Testアノテーション:テストメソッドをマークするために使用されます。RunWithアノテーション:テストランナーを指定するために使用されます。Autowiredアノテーション:依存性注入を行うために使用されます。SpringBootApplicationアノテーション:このクラスをSpring Bootアプリケーションのエントリポイントとしてマークするために使用されます。SpringBootTestアノテーション:テストクラスをSpring Bootテストとして指定するために使用されます。ComponentScanアノテーション:コンポーネントスキャンを行うパッケージまたはクラスを指定するために使用されます。JdbcTemplateクラス:SQLステートメントを実行するメソッドを提供します。SpringRunnerクラス:テストランナーをSpringRunnerとして指定するために使用されます。ArrayListクラス:空のリストを作成するために使用されます。Listインターフェース:クエリ結果セットを操作するために使用されます。
コード:
import com.oceanbase.example.batch.model.People; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List;AddPeopleWriterTestクラスの定義。SpringBootTestアノテーションとSpringRunnerランナーを使用してSpring Bootの統合テストを行い、@ComponentScanアノテーションを使用してスキャンするパッケージパスを指定します。@Autowiredを使用したインスタンスの注入。@Autowiredアノテーションを使用して、addPeopleWriterおよびJdbcTemplateインスタンスを自動注入します。コード:
@Autowired private AddPeopleWriter addPeopleWriter; @Autowired private JdbcTemplate jdbcTemplate;@Testを使用したデータの挿入と出力のテスト。peopleテーブルへのデータ挿入。 まず、空のPeopleオブジェクトリストpeopleListを作成します。次に、2つのPeopleオブジェクトperson1とperson2を作成し、それぞれの名前と年齢のプロパティを設定します。その後、これら2つのPeopleオブジェクトをpeopleListリストに追加します。その後、addPeopleWriterのwriteメソッドを呼び出し、peopleListをパラメータとして渡して、これらのPeopleオブジェクトをデータベースに書き込みます。コード:
List<People> peopleList = new ArrayList<>(); People person1 = new People(); person1.setName("zhangsan"); person1.setAge(27); peopleList.add(person1); People person2 = new People(); person2.setName("lisi"); person2.setAge(35); peopleList.add(person2); addPeopleWriter.write(peopleList);peopleテーブル内のデータの出力。 まず、JdbcTemplateを使用してクエリステートメントSELECT * FROM peopleを実行し、lambda式を使用してクエリ結果を処理します。lambda式では、rs.getStringとrs.getIntメソッドを使用してクエリ結果セットのフィールド値を取得し、その値を新しく作成したPeopleオブジェクトに設定します。新しく作成した各Peopleオブジェクトを結果リストresultに追加します。次に、people テーブル内のデータ:という一行のメッセージを出力します。その後、forループを使用してresultリスト内の各Peopleオブジェクトを走査し、System.out.printlnを使用して各オブジェクトの内容を出力します。最後に、バッチジョブの実行完了メッセージを出力します。コード:
List<People> result = jdbcTemplate.query("SELECT * FROM people", (rs, rowNum) -> { People person = new People(); person.setName(rs.getString("name")); person.setAge(rs.getInt("age")); return person; }); System.out.println("people テーブル内のデータ:"); for (People person : result) { System.out.println(person); } // バッチジョブ実行完了後のメッセージを出力 System.out.println("Batch Job execution completed.");
全コード表示
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.oceanbase</groupId>
<artifactId>java-oceanbase-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java-oceanbase-springbatch</name>
<description>Demo project for Spring Batch</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#configuration database
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8
spring.datasource.username=user_name
spring.datasource.password=
# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
# Spring Batch
spring.batch.job.enabled=false
#
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
package com.oceanbase.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);
}
public void runBatchJob() {
}
}
package com.oceanbase.example.batch.config;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import com.oceanbase.example.batch.processor.AddPeopleDescProcessor;
import com.oceanbase.example.batch.writer.AddDescPeopleWriter;
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.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import javax.sql.DataSource;
//import javax.activation.DataSource;
@Configuration
@EnableBatchProcessing
@SpringBootApplication
@ComponentScan("com.oceanbase.example.batch.writer")
@EnableAutoConfiguration
public class BatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;// Spring Bootの自動設定で提供されるデフォルトのdataSourceを使用する
@Bean
public ItemReader<People> peopleReader() {
JdbcCursorItemReader<People> reader = new JdbcCursorItemReader<>();
reader.setDataSource((javax.sql.DataSource) dataSource);
reader.setRowMapper(new BeanPropertyRowMapper<>(People.class));
reader.setSql("SELECT * FROM people");
return reader;
}
@Bean
public ItemProcessor<People, PeopleDESC> addPeopleDescProcessor() {
return new AddPeopleDescProcessor();
}
@Bean
public ItemWriter<PeopleDESC> addDescPeopleWriter() {
return new AddDescPeopleWriter();
}
@Bean
public Step step1(ItemReader<People> reader, ItemProcessor<People, PeopleDESC> processor,
ItemWriter<PeopleDESC> writer) {
return stepBuilderFactory.get("step1")
.<People, PeopleDESC>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
public Job importJob(Step step1) {
return jobBuilderFactory.get("importJob")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
}
package com.oceanbase.example.batch.model;
public class People {
private String name;
private int age;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
// Getters and setters
}
package com.oceanbase.example.batch.model;
public class PeopleDESC {
private String name;
private int age;
private String desc;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "PeopleDESC [name=" + name + ", age=" + age + ", desc=" + desc + "]";
}
}
package com.oceanbase.example.batch.processor;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.springframework.batch.item.ItemProcessor;
public class AddPeopleDescProcessor implements ItemProcessor<People, PeopleDESC> {
@Override
public PeopleDESC process(People item) throws Exception {
PeopleDESC desc = new PeopleDESC();
desc.setName(item.getName());
desc.setAge(item.getAge());
desc.setDesc("This is " + item.getName() + " with age " + item.getAge());
return desc;
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class AddDescPeopleWriter implements ItemWriter<PeopleDESC> {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void write(List<? extends PeopleDESC> items) throws Exception {
// 既存のテーブルを削除する場合があるため、まず削除します。
jdbcTemplate.execute("DROP TABLE people_desc");
// テーブル作成ステートメント
String createTableSql = "CREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))";
jdbcTemplate.execute(createTableSql);
for (PeopleDESC item : items) {
String sql = "INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(sql, item.getId(), item.getName(), item.getAge(), item.getDesc());
}
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.People;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class AddPeopleWriter implements ItemWriter<People> {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void write(List<? extends People> items) throws Exception {
// 既存のテーブルを削除する場合があるため、まず削除します。
jdbcTemplate.execute("DROP TABLE people");
// テーブル作成ステートメント
String createTableSql = "CREATE TABLE people (name VARCHAR2(255), age INT)";
jdbcTemplate.execute(createTableSql);
for (People item : items) {
String sql = "INSERT INTO people (name, age) VALUES (?, ?)";
jdbcTemplate.update(sql, item.getName(), item.getAge());
}
}
}
package com.oceanbase.example.batch.config;
import com.oceanbase.example.batch.writer.AddDescPeopleWriter;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import javax.batch.runtime.BatchStatus;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchConfigTest {
@Test
public void testJob() throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addString("jobParam", UUID.randomUUID().toString())
.toJobParameters();
JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);
Assert.assertEquals(BatchStatus.COMPLETED.toString(), jobExecution.getStatus().toString());
}
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
private class JobLauncherTestUtils {
public JobExecution launchJob(JobParameters jobParameters) throws Exception {
return jobLauncher.run(job, jobParameters);
}
}
}
package com.oceanbase.example.batch.processor;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AddPeopleDescProcessorTest {
@Autowired
private AddPeopleDescProcessor processor;
@Test
public void testProcess() throws Exception {
People people = new People();
// people.setName("John");
// people.setAge(25);
PeopleDESC desc = processor.process(people);
// Assert.assertEquals("John", desc.getName());
// Assert.assertEquals(25, desc.getAge());
// Assert.assertEquals("This is John with age 25", desc.getDesc());
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AddDescPeopleWriterTest {
@Autowired
private AddDescPeopleWriter writer;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testWrite() throws Exception {
// people_descテーブルにデータを挿入
List<PeopleDESC> peopleDescList = new ArrayList<>();
PeopleDESC desc1 = new PeopleDESC();
desc1.setId(1);
desc1.setName("John");
desc1.setAge(25);
desc1.setDesc("This is John with age 25");
peopleDescList.add(desc1);
PeopleDESC desc2 = new PeopleDESC();
desc2.setId(2);
desc2.setName("Alice");
desc2.setAge(30);
desc2.setDesc("This is Alice with age 30");
peopleDescList.add(desc2);
writer.write(peopleDescList);
String selectSql = "SELECT COUNT(*) FROM people_desc";
int count = jdbcTemplate.queryForObject(selectSql, Integer.class);
Assert.assertEquals(2, count);
// people_descテーブルのデータを出力
List<PeopleDESC> resultDesc = jdbcTemplate.query("SELECT * FROM people_desc", (rs, rowNum) -> {
PeopleDESC desc = new PeopleDESC();
desc.setId(rs.getInt("id"));
desc.setName(rs.getString("name"));
desc.setAge(rs.getInt("age"));
desc.setDesc(rs.getString("description"));
return desc;
});
System.out.println("people_desc テーブルのデータ:");
for (PeopleDESC desc : resultDesc) {
System.out.println(desc);
}
// バッチジョブ実行完了後のメッセージを出力
System.out.println("Batch Job execution completed.");
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.People;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBootApplication
@ComponentScan("com.oceanbase.example.batch.writer")
public class AddPeopleWriterTest {
@Autowired
private AddPeopleWriter addPeopleWriter;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testWrite() throws Exception {
// peopleテーブルにデータを挿入
List<People> peopleList = new ArrayList<>();
People person1 = new People();
person1.setName("zhangsan");
person1.setAge(27);
peopleList.add(person1);
People person2 = new People();
person2.setName("lisi");
person2.setAge(35);
peopleList.add(person2);
addPeopleWriter.write(peopleList);
// クエリして結果を出力
List<People> result = jdbcTemplate.query("SELECT * FROM people", (rs, rowNum) -> {
People person = new People();
person.setName(rs.getString("name"));
person.setAge(rs.getInt("age"));
return person;
});
System.out.println("people テーブルのデータ:");
for (People person : result) {
System.out.println(person);
}
// バッチジョブ実行完了後の情報を出力
System.out.println("Batch Job execution completed.");
}
}
関連ドキュメント
OceanBase Connector/Jの詳細については、OceanBase JDBCドライバを参照してください。
クリックしてjava-oceanbase-springbatchサンプルプロジェクトをダウンロード