Springデータを使用したR2DBCの概要

1. 前書き

https://r2dbc.io/[R2DBC](Reactive Relational Database Connectivity)は、Spring One Platform 2018でPivotalが発表した取り組みです。 SQLデータベースに対するリアクティブAPIを作成する予定です。
*言い換えれば、この努力は完全にノンブロッキングドライバーを使用してデータベース接続を作成します。*
このチュートリアルでは、Spring Data R2BDCを使用したアプリケーションの例を見ていきます。 より低レベルのR2DBC APIのガイドについては、https://www.baeldung.com/r2dbc-operations [以前の記事]をご覧ください。

2. 最初のSpring Data R2DBCプロジェクト

まず、R2DBCプロジェクトはごく最近のものです。 現時点では、** PostGres、MSSQL、およびH2にのみR2DBCドライバーがあります。*さらに、*すべてのSpring Boot機能を使用することはできません*。 そのため、手動で追加する必要がある手順がいくつかあります。 ただし、* https://www.baeldung.com/spring-data [Spring Data]のようなプロジェクトを活用して支援することができます。*
最初にMavenプロジェクトを作成します。 この時点で、R2DBCにはいくつかの依存関係の問題があるため、_pom.xml_は通常より大きくなります。
この記事の範囲では、データベースとしてhttps://search.maven.org/search?q=g:com.h2database[H2]を使用し、アプリケーションのリアクティブCRUD関数を作成します。
生成されたプロジェクトの_pom.xml_を開き、適切な依存関係といくつかの初期リリースのSpringリポジトリを追加しましょう。
<dependencies>
     <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-r2dbc</artifactId>
        <version>1.0.0.M2</version>
    </dependency>
    <dependency>
        <groupId>io.r2dbc</groupId>
        <artifactId>r2dbc-h2</artifactId>
        <version>0.8.0.M8</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.199</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

マイルストーンの依存関係を使用するには、これらのリポジトリが必要です。
その他の必要なアーティファクトには、https://search.maven.org/search?q = g:org.projectlombok%20AND%20a:lombok&core = gav [Lombok、] https://search.maven.org/search?q=gが含まれます。 :org.springframework.boot%20AND%20a:spring-boot-starter-webflux&core = gav [Spring WebFlux]およびプロジェクトを完了する他のいくつかhttps://github.com/rodrigolgraciano/tutorials/blob/master/spring- 5-data-reactive / pom.xml [依存関係]。

3. 接続ファクトリー

データベースを使用する場合、接続ファクトリーが必要です。 したがって、もちろん、R2DBCでも同じことが必要です。
そこで、インスタンスに接続するための詳細を追加します。
@Configuration
@EnableR2dbcRepositories
class R2DBCConfiguration extends AbstractR2dbcConfiguration {
    @Bean
    public H2ConnectionFactory connectionFactory() {
        return new H2ConnectionFactory(
            H2ConnectionConfiguration.builder()
              .url("mem:testdb;DB_CLOSE_DELAY=-1;")
              .username("sa")
              .build()
        );
    }
}
上記のコードで最初に気付くのは、_ @ EnableR2dbcRepositories_です。 Spring Data機能を使用するには、この注釈が必要です。 さらに、後で必要になる多くのBeanを提供するため、_AbstractR2dbcConfiguration_を拡張しています。

4. 初めてのR2DBCアプリケーション

次のステップは、リポジトリを作成することです。
interface PlayerRepository extends ReactiveCrudRepository<Player, Integer> {}
  • _ReactiveCrudRepository_インターフェースは非常に便利です。 たとえば、基本的なCRUD機能を提供します。*

    最後に、モデルクラスを定義します。 Lombokを使用して、定型コードを回避します。
@Data
@NoArgsConstructor
@AllArgsConstructor
class Player {
    @Id
    Integer id;
    String name;
    Integer age;
}

5. テスト

コードをlink:/reactive-streams-step-verifier-test-publisher[test]する時間です。 それでは、いくつかのテストケースを作成することから始めましょう。
@Test
public void whenDeleteAll_then0IsExpected() {
    playerRepository.deleteAll()
      .as(StepVerifier::create)
      .expectNextCount(0)
      .verifyComplete();
}

@Test
public void whenInsert6_then6AreExpected() {
    insertPlayers();
    playerRepository.findAll()
      .as(StepVerifier::create)
      .expectNextCount(6)
      .verifyComplete();
}

6. カスタムクエリ

*カスタムクエリを生成することもできます*。 追加するには、プレーヤーリポジトリを変更する必要があります。
@Query("select id, name, age from player where name = $1")
Flux<Player> findAllByName(String name);

@Query("select * from player where age = $1")
Flux<Player> findByAge(int age);
既存のテストに加えて、最近更新されたリポジトリにテストを追加します。
@Test
public void whenSearchForCR7_then1IsExpected() {
    insertPlayers();
    playerRepository.findAllByName("CR7")
      .as(StepVerifier::create)
      .expectNextCount(1)
      .verifyComplete();
}

@Test
public void whenSearchFor32YearsOld_then2AreExpected() {
    insertPlayers();
    playerRepository.findByAge(32)
      .as(StepVerifier::create)
      .expectNextCount(2)
      .verifyComplete();
}

private void insertPlayers() {
    List<Player> players = Arrays.asList(
        new Player(1, "Kaka", 37),
        new Player(2, "Messi", 32),
        new Player(3, "Mbappé", 20),
        new Player(4, "CR7", 34),
        new Player(5, "Lewandowski", 30),
        new Player(6, "Cavani", 32)
    );
    playerRepository.saveAll(players).subscribe();
}

7. バッチ

R2DBCのもう1つの機能は、バッチを作成することです。 バッチは、複数のSQLステートメントを実行するときに便利です。個々の操作よりもパフォーマンスが向上します。
_Batch_を作成するには、_Connection_オブジェクトが必要です。
Batch batch = connection.createBatch();
アプリケーションが_Batch_インスタンスを作成した後、必要な数のSQLステートメントを追加できます。 実行するには、__ execute()__methodを呼び出します。 バッチの結果は、各ステートメントの結果オブジェクトを返す_Publisher_です。
それでは、コードにジャンプして、_Batch_を作成する方法を見てみましょう。
@Test
public void whenBatchHas2Operations_then2AreExpected() {
    Mono.from(factory.create())
      .flatMapMany(connection -> Flux.from(connection
        .createBatch()
        .add("select * from player")
        .add("select * from player")
        .execute()))
      .as(StepVerifier::create)
      .expectNextCount(2)
      .verifyComplete();
}

8. 結論

要約すると、R2DBCはまだ初期段階です。 SQLデータベースに対するリアクティブAPIを定義するSPIを作成する試みです。 R2DBCをlink:/spring-webflux[Spring WebFlux]と共に使用すると、データを上からデータベースまで非同期的に処理するアプリケーションを作成できます。
いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/spring-5-data-reactive[GitHub]で入手できます。