Spring Data R2DBC | はじめに

Spring Data R2DBCは、リレーショナルデータベース向けのR2DBCドライバを使うソリューションに、Springの中核概念を適用する。行の保存と取得のための高レベル抽象化としてDatabaseClientを提供する。

この文書はSpring Data R2DBCサポートのリファレンスガイドである。R2DBCモジュールの概念と意味を説明し、Springとデータベースアクセスの基本概要を示す。

1. Springを学ぶ

Spring Dataは、IoCコンテナ、型変換システム、式言語、JMX統合、DAO例外階層など、Spring Frameworkの中核機能を利用する。

すべてのSpring APIを知っている必要はないが、Springの背景にある概念、特にInversion of Control(IoC)を理解し、利用するIoCコンテナに慣れておくことが重要である。

R2DBCサポートの中核機能は、SpringコンテナのIoCサービスを呼び出さずに直接利用できる。これはJdbcTemplateをスタンドアロンで使う場合と似ている。リポジトリサポートなどSpring Data R2DBCの全機能を使うには、ライブラリの一部をSpringで構成する必要がある。

2. R2DBCとは

R2DBCはReactive Relational Database Connectivityの略である。リレーショナルデータベースへアクセスするため、データベースドライバベンダーが実装するリアクティブAPIを定義する仕様イニシアチブである。

R2DBCが作られた理由の一つは、少ないスレッドと少ないハードウェアリソースで同時実行を扱うため、ノンブロッキングなアプリケーションスタックが必要だったことである。JDBCは完全にブロッキングなAPIであり、JDBCを再利用してもこの要件は満たせない。ThreadPoolで似た動作を実現することはできるが、制約が多い。

もう一つの理由は、多くのアプリケーションが依然としてリレーショナルデータベースにデータを保存していることである。NoSQLベンダーの中にはリアクティブクライアントを提供するものもあるが、多くのプロジェクトは単純にNoSQLへ移行できない。そのため、ノンブロッキングなリレーショナルデータベースドライバの基盤となる共通APIが必要になった。

3. リアクティブとは

リアクティブという用語は、I/Oイベントに反応するネットワークコンポーネント、マウスイベントに反応するUIコントローラ、利用可能なリソースの変化など、変更や利用可能性、完了通知に反応するプログラミングモデルを指す。ノンブロッキング処理も、処理完了やデータ利用可能時に反応するため、リアクティブといえる。

Springがリアクティブと結び付ける重要な仕組みに、ノンブロッキングなバックプレッシャーがある。同期的な命令型コードでは、呼び出しをブロックすることが自然な待機になる。ノンブロッキングコードでは、速いプロデューサーがコンシューマーを圧倒しないよう、イベントの速度を制御する必要がある。

Reactive Streamsは、バックプレッシャーを持つ非同期コンポーネント間の相互作用を定義する小さな仕様である。主な目的は、サブスクライバーがパブリッシャーのデータ生成速度を制御できるようにすることである。

4. リアクティブAPI

Reactive Streamsは相互運用性に重要だが、アプリケーションAPIとしては低レベルすぎる。アプリケーションには、非同期ロジックを構成するための、より高レベルな関数型APIが必要である。

Project Reactorは、Spring Data R2DBCが採用しているリアクティブライブラリである。0..1個の値を扱うMonoと、0..N個の値を扱うFluxを提供する。Reactorはノンブロッキングバックプレッシャーをサポートし、Springと密接に開発されている。

Spring Data R2DBCはProject Reactorに依存するが、Reactive Streams仕様を通じて他のリアクティブライブラリとも相互運用できる。リポジトリは通常、汎用Publisherを入力として受け取り、内部でReactor型へ適用し、MonoまたはFluxを返す。

5. 要件

Spring Data R2DBC 1.xのバイナリには次が必要である。

  • JDK 8.0以降
  • Spring Framework 5.3.13以降
  • R2DBC Arabba-SR10以降

6. 追加のヘルプリソース

新しいフレームワークを学ぶのは簡単ではない。困った場合は、Spring Dataタグ付きのStack Overflowなどのコミュニティリソースを利用できる。Spring DataとSpringを支援する企業による専門サポートも提供されている。

7. 開発を追う

ソースリポジトリ、ナイトリービルド、スナップショットアーティファクトについてはSpring Data R2DBCのホームページを参照する。Stack Overflowでコミュニティと交流し、Spring Data R2DBCの issue tracker で課題を作成し、SpringポータルやSpringブログ、Spring Dataチームをフォローできる。

8. プロジェクトメタデータ

9. 注目すべき新機能

Spring Data R2DBC 1.3ではQuery by Exampleが導入された。1.2ではDatabaseClientがSpring R2DBCのパッケージ化されたAPIへ移動し、エンティティコールバック、@EnableR2dbcAuditingによる監査、永続性コンストラクタの@Valueサポート、Oracle R2DBCドライバサポートが追加された。

1.1ではR2dbcEntityTemplate、クエリ派生、DatabaseClient.as(...)によるインターフェースプロジェクション、DatabaseClient.filter(...)によるExecuteFunctionStatementFilterFunctionのサポートが追加された。

1.0ではR2DBC 0.8.0.RELEASEへアップグレードされ、初期リポジトリ、トランザクション、ダイアレクト、ルーティング、スキーマ初期化、コンバータ、Kotlin拡張、名前付きパラメータのサポートが追加された。

10. 依存関係

個々のSpring Dataモジュールは開始時期が異なるため、多くのモジュールは異なるメジャー、マイナーバージョンを持つ。互換性のあるバージョンを見つける最も簡単な方法は、Spring DataリリーストレインBOMを使うことである。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-bom</artifactId>
      <version>2021.1.0</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

BOMを使うと、各Spring Data依存関係を個別バージョンなしで宣言できる。Spring BootもSpring Dataモジュールのバージョンを管理し、spring-data-releasetrain.versionプロパティで上書きできる。

11. Spring Dataリポジトリの利用

Spring Dataリポジトリ抽象化の目的は、データアクセス層の定型コードを大幅に減らすことである。中心となるインターフェースはRepositoryであり、ドメイン型とID型を保持する。CrudRepositoryは、savefindByIdfindAllcountdeleteexistsByIdなどの一般的なCRUDメソッドを追加する。

PagingAndSortingRepositoryCrudRepositoryを拡張し、ソートとページング付きアクセスのためのメソッドを追加する。

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
  Iterable<T> findAll(Sort sort);
  Page<T> findAll(Pageable pageable);
}

JpaRepositoryMongoRepositoryのような技術固有リポジトリは、これらの汎用インターフェースを拡張し、基盤となる永続化技術の機能を公開する。