対象読者
- Springまわりの技術について深掘りしたい
- JOOQに入門したい
- 型安全なクエリビルダーを利用したい
- FlywayをSpringに導入したい
環境
- SpringBoot 3.2
- Apache Maven 3.9.5
- JOOQ 3.18.7
- Flyway 9.22.3
- Postgres 16
[備考] JOOQ & Flyawayは継承元のpomに定義されていたVersionを使用し、
MavenはSpringについているラッパーを使用する
FlaywayとJOOQについて
Flyway
Flywayはデータベースの移行を管理するオープンソースツールです。このツールの魅力は、そのシンプルさと設定よりも規約を重視するアプローチにあります。Flywayを使用することで、データベースのスキーマのバージョン管理が可能になり、スキーマの変更や移行を容易かつ確実に行うことができます。これはSQLやJavaコードで定義された移行を自動的に管理し、適用することができるため、データベーススキーマの進化をスムーズにコントロールするのに理想的です。(by chatgpt)
JOOQ
jOOQはJavaにおけるデータベースアクセスを革新するライブラリです。このツールの特徴は、タイプセーフかつオブジェクト指向的な方法でSQLクエリを構築できる点にあります。jOOQは完全なORMではなく、SQLに特化しているため、より複雑なSQLクエリが必要な場合に非常に有効です。Javaの型システムとの統合により、文法エラーのリスクを減らしつつ、パワフルなSQL操作を提供します。また、データベーススキーマに基づいてJavaのクラスを自動生成する機能もあり、これにより開発者は煩雑なコーディング作業から解放され、より効率的にデータベース操作を行うことができます。(by chatgpt)
依存関係
JOOQとFlyqwayのstarterを依存関係に追加する。
JOOQでDBアクセスオブジェクトを自動生成するためには、
jooq-metaとjooq-codegeが必要だが、starterには含まれていないので追加。
Versionを揃えるためにも継承元のspring-boot-starter-parentに含まれる
spring-boot-dependenciesの値を使用することが望ましい。
FlywayはPluginから実行する場合は、依存関係はいらない
<!-- PostgreSQL -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JOOQ -->
<!-- jooqはstarterに含まれているので、それ以外の依存関係を追加 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-meta</artifactId>
<version>${jooq.version}</version>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen</artifactId>
<version>${jooq.version}</version>
</dependency>
Plugin
Flyaway DB Migration
実行方法は下記の2通りの方法がある。
- Spring起動時に実行されるMigration
- Maven Pluginを使用したMigration
SpringによるMigrationは手軽であるが、JOOQでテーブル定義からコードを生成するのに不向きのためコマンドラインからMigarationを実行できるようにしたいのでPluginを追加する。
<build>
<plugins>
<!-- Flyway DB Migration -->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<configuration>
<!-- DB接続情報 -->
<url>jdbc:postgresql://localhost:5432/sample</url>
<user>admin</user>
<password>password</password>
<!-- baselineの設定。-->
<!-- どのバージョンからMigraitonを始めるかを定義 -->
<baselineVersion>0</baselineVersion>
<!-- baseline-version以前のバージョンのマイグレーションの実行の有無を定義 -->
<baselineOnMigrate>true</baselineOnMigrate>
<!-- PostgreSQLの場合デフォルトではPublicしか実行されないので-->
<!-- 別のスキーマを対象にしたい場合は別途ここで定義する-->
<schemas>
<schema>public</schema>
<schema>catalog</schema>
</schemas>
<!-- Migrationファイルが置かれているディレクトリを指定する-->
<locations>
<location>classpath:/db/migration</location>
</locations>
</configuration>
<!-- Driverを定義 -->
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
</dependencies>
</plugin>
実行方法
下記のコマンドで実行。ゴールは公式ドキュメントを参考にしてください
./mvnw flyway:${goals}
備考
Spring起動時に実行されるMigration
flyway-coreが依存関係に含まれている際に、
src/main/resources/db/migration
に配置されているmigarionファイルを実行する。
dbへの接続情報はapplication.yaml
に定義されている値を使用する。
<!-- DB Migration -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
spring:
datasource:
url: jdbc:postgresql://localhost:5432/sample
username: admin
password: password
flyway:
# どのバージョンからMigraitonを始めるかを定義
baseline-version: 0
# baseline-version以前のバージョンのマイグレーションの実行の有無を定義
baseline-on-migrate: true
# マイグレーションスクリプトのエンコーディング方法
encoding: UTF-8
# Flywayを有効または無効にするための設定
enabled: true
JOOQ Codegen Plugin
<build>
<plugins>
<!-- JOOQ Code gen -->
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-meta</artifactId>
<version>${jooq.version}</version>
</dependency>
</dependencies>
<configuration>
<!-- Driverと接続情報を定義-->
<jdbc>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/sample</url>
<user>admin</user>
<password>password</password>
</jdbc>
<generator>
<database>
<name>org.jooq.meta.postgres.PostgresDatabase</name>
<schemata>
<!-- 複数のスキーマがある場合に定義する -->
<schema>
<inputSchema>catalog</inputSchema>
</schema>
<schema>
<inputSchema>catalog</inputSchema>
</schema>
</schemata>
</database>
<!-- 自動生成するコードの定義 -->
<generate>
<indexes>false</indexes>
<keys>false</keys>
<daos>false</daos>
<pojos>false</pojos>
<pojosAsJavaRecordClasses>true</pojosAsJavaRecordClasses>
<javaTimeTypes>true</javaTimeTypes>
</generate>
<!-- 自動生成したコードを配置するための設定 -->
<target>
<packageName>com.example.stocknavigator</packageName>
<directory>src/generate/java</directory>
<encoding>UTF-8</encoding>
<clean>true</clean>
</target>
</generator>
</configuration>
</plugin>
</plugins>
</build>
実行方法
下記のコマンドを実行
./mvnw jooq-codegen:generate
まとめ
- FlywayはPluginからでもSpringからでも実行できる
- JOOQの自動生成はPluginを用いる
参考資料