入門

作業環境をブートストラップ設定する簡単な方法は、Pleiades All in One (JDK, STS, Lombok 付属) Spring Tools (英語) または Spring Initializr から Spring ベースのプロジェクトを作成することです。

まず、実行中のデータベースサーバーをセットアップする必要があります。R2DBC アクセス用にデータベースを構成する方法については、ベンダーのドキュメントを参照してください。

要件

Spring Data R2DBC には Spring Framework 6.2.0 以降が必要です。

データベースに関して言えば、Spring Data R2DBC には、ベンダー固有のフレーバーではなく一般的な SQL 機能を抽象化するドライバーが必要です。Spring Data R2DBC には、次のデータベースの直接サポートが含まれています。

別のデータベースを使用すると、アプリケーションは起動しません。このような場合の対処方法については、ダイアレクトのセクションに詳しく記載されています。

Hello World

STS で Spring プロジェクトを作成するには:

  1. ファイル→新規→ Spring テンプレートプロジェクト→シンプル Spring ユーティリティプロジェクトに移動し、プロンプトが表示されたらはいを押します。次に、プロジェクトとパッケージ名(org.spring.r2dbc.example など)を入力します。

  2. 以下を pom.xml ファイルの dependencies 要素に追加します。

  3. 以下を pom.xml ファイルの dependencies 要素に追加します。

    <dependencies>
    
      <!-- other dependency elements omitted -->
    
      <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-r2dbc</artifactId>
        <version>3.4.0</version>
      </dependency>
    
      <!-- a R2DBC driver -->
      <dependency>
        <groupId>io.r2dbc</groupId>
        <artifactId>r2dbc-h2</artifactId>
        <version>x.y.z</version>
      </dependency>
    
    </dependencies>
  4. pom.xml の Spring のバージョンを次のように変更します

    <spring.version>6.2.0</spring.version>
  5. Maven の Spring マイルストーンリポジトリの次の場所を、<dependencies/> 要素と同じレベルになるように pom.xml に追加します。

    <repositories>
      <repository>
        <id>spring-milestone</id>
        <name>Spring Maven MILESTONE Repository</name>
        <url>https://repo.spring.io/milestone</url>
      </repository>
    </repositories>

リポジトリも参照できます (英語)

ロギングレベルを DEBUG に設定して、追加情報を表示することもできます。これを行うには、application.properties ファイルを編集して次のコンテンツを作成します。

logging.level.org.springframework.r2dbc=DEBUG

次に、たとえば、次のように Person クラスを作成して永続化できます。

public class Person {

	private final String id;
	private final String name;
	private final int age;

	public Person(String id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public String getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}

次に、次のようにデータベースにテーブル構造を作成する必要があります。

CREATE TABLE person
  (id VARCHAR(255) PRIMARY KEY,
   name VARCHAR(255),
   age INT);

次のように、実行するメインアプリケーションも必要です。

import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import reactor.test.StepVerifier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;

public class R2dbcApp {

  private static final Log log = LogFactory.getLog(R2dbcApp.class);

  public static void main(String[] args) {

    ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");

    R2dbcEntityTemplate template = new R2dbcEntityTemplate(connectionFactory);

    template.getDatabaseClient().sql("CREATE TABLE person" +
        "(id VARCHAR(255) PRIMARY KEY," +
        "name VARCHAR(255)," +
        "age INT)")
      .fetch()
      .rowsUpdated()
      .as(StepVerifier::create)
      .expectNextCount(1)
      .verifyComplete();

    template.insert(Person.class)
      .using(new Person("joe", "Joe", 34))
      .as(StepVerifier::create)
      .expectNextCount(1)
      .verifyComplete();

    template.select(Person.class)
      .first()
      .doOnNext(it -> log.info(it))
      .as(StepVerifier::create)
      .expectNextCount(1)
      .verifyComplete();
  }
}

メインプログラムを実行すると、前述の例では次のような出力が生成されます。

2018-11-28 10:47:03,893 DEBUG amework.core.r2dbc.DefaultDatabaseClient: 310 - Executing SQL statement [CREATE TABLE person
  (id VARCHAR(255) PRIMARY KEY,
   name VARCHAR(255),
   age INT)]
2018-11-28 10:47:04,074 DEBUG amework.core.r2dbc.DefaultDatabaseClient: 908 - Executing SQL statement [INSERT INTO person (id, name, age) VALUES($1, $2, $3)]
2018-11-28 10:47:04,092 DEBUG amework.core.r2dbc.DefaultDatabaseClient: 575 - Executing SQL statement [SELECT id, name, age FROM person]
2018-11-28 10:47:04,436  INFO        org.spring.r2dbc.example.R2dbcApp:  43 - Person [id='joe', name='Joe', age=34]

この単純な例でも、注意すべき点はほとんどありません。

  • 標準の io.r2dbc.spi.ConnectionFactory オブジェクトを使用して、Spring Data R2DBC(R2dbcEntityTemplate)で主要ヘルパークラスのインスタンスを作成できます。

  • マッパーは、追加のメタデータを必要とせずに、標準の POJO オブジェクトに対して機能します (ただし、オプションでその情報を提供することもできます。ここを参照してください)。

  • マッピング規則では、フィールドアクセスを使用できます。Person クラスには getter しかありません。

  • コンストラクターの引数名が保存された行の列名と一致する場合、オブジェクトのインスタンス化に使用されます。

サンプルリポジトリ

GitHub リポジトリといくつかの例 (英語) をダウンロードして試して、ライブラリの動作を確認してください。

Spring を使用したリレーショナルデータベースへの接続

リレーショナルデータベースと Spring を使用する場合の最初のタスクの 1 つは、IoC コンテナーを使用して io.r2dbc.spi.ConnectionFactory オブジェクトを作成することです。サポートされているデータベースとドライバーを使用してください。

Java 構成を使用した ConnectionFactory インスタンスの登録

次の例は、Java ベースの Bean メタデータを使用して io.r2dbc.spi.ConnectionFactory のインスタンスを登録する例を示しています。

Java 構成を使用した io.r2dbc.spi.ConnectionFactory オブジェクトの登録
@Configuration
public class ApplicationConfiguration extends AbstractR2dbcConfiguration {

  @Override
  @Bean
  public ConnectionFactory connectionFactory() {
    return …
  }
}

このアプローチでは、標準の io.r2dbc.spi.ConnectionFactory インスタンスを使用でき、コンテナーは Spring の AbstractR2dbcConfiguration を使用します。ConnectionFactory インスタンスを直接登録する場合と比較して、構成サポートには、R2DBC 例外を Spring の例外に変換する ExceptionTranslator 実装もコンテナーに提供するという追加の利点があります。@Repository アノテーションが付けられたデータアクセスクラスのポータブル DataAccessException 階層。この階層と @Repository の使用については、Spring の DAO サポート機能で説明されています。

AbstractR2dbcConfiguration は、DatabaseClient も登録します。これは、データベースの相互作用およびリポジトリの実装に必要です。

ダイアレクト

Spring Data R2DBC は、Dialect を使用して、データベースまたはそのドライバーに固有の動作をカプセル化します。Spring Data R2DBC は、ConnectionFactory をインスペクションすることでデータベースの詳細に反応し、それに応じて適切なデータベース言語を選択します。使用可能なダイアレクトがないデータベースを使用すると、アプリケーションは起動しません。その場合、ベンダーに Dialect 実装の提供を依頼する必要があります。あるいは、独自の Dialect を実装することもできます。

ダイアレクトは、通常、ConnectionFactoryMetadata をインスペクションすることによって、ConnectionFactory から DialectResolver (Javadoc) によって解決されます。+ org.springframework.data.r2dbc.dialect.DialectResolver$R2dbcDialectProvider から META-INF/spring.factories まで実装するクラスを登録することで、Spring に R2dbcDialect を自動検出させることができます。DialectResolver は、Spring の SpringFactoriesLoader を使用して、クラスパスからダイアレクトプロバイダー実装を検出します。そうするために:

  1. 独自の Dialect を実装します。

  2. Dialect を返す R2dbcDialectProvider を実装します。

  3. META-INF に spring.factories リソースを作成してプロバイダーを登録し、行を追加して登録を実行します
     org.springframework.data.r2dbc.dialect.DialectResolver$R2dbcDialectProvider=<fully qualified name of your R2dbcDialectProvider>