1. 概要

このチュートリアルでは、Spring Data リポジトリを使用して、Couchbaseでリアクティブな方法でデータベース操作を構成および実装する方法を学習します。

ReactionCrudRepositoryおよびReactiveSortingRepositoryの基本的な使用法について説明します。 さらに、AbstractReactiveCouchbaseConfigurationを使用してテストアプリケーションを構成します。

2. Mavenの依存関係

まず、必要な依存関係を追加しましょう。

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-couchbase-reactive</artifactId>
</dependency>

spring-boot-starter-data-couchbase-reactive 依存関係には、リアクティブAPIを使用してCouchbaseで操作するために必要なすべてのものが含まれています。

Project Reactor APIを使用するために、 reactor-core依存関係も含めます。

3. 構成

次に、Couchbaseとアプリケーション間の接続設定を定義しましょう。

プロパティを保持するクラスを作成することから始めましょう。

@Configuration
public class CouchbaseProperties {

    private List<String> bootstrapHosts;
    private String bucketName;
    private String bucketPassword;
    private int port;

    public CouchbaseProperties(
      @Value("${spring.couchbase.bootstrap-hosts}") List<String> bootstrapHosts, 
      @Value("${spring.couchbase.bucket.name}") String bucketName, 
      @Value("${spring.couchbase.bucket.password}") String bucketPassword, 
      @Value("${spring.couchbase.port}") int port) {
        this.bootstrapHosts = Collections.unmodifiableList(bootstrapHosts);
        this.bucketName = bucketName;
        this.bucketPassword = bucketPassword;
        this.port = port;
    }

    // getters
}

リアクティブサポートを使用するには、AbstractReactiveCouchbaseConfigurationを拡張する構成クラスを作成する必要があります。

@Configuration
@EnableReactiveCouchbaseRepositories("com.baeldung.couchbase.domain.repository")
public class ReactiveCouchbaseConfiguration extends AbstractReactiveCouchbaseConfiguration {

    private CouchbaseProperties couchbaseProperties;

    public ReactiveCouchbaseConfiguration(CouchbaseProperties couchbaseProperties) {
        this.couchbaseProperties = couchbaseProperties;
    }

    @Override
    protected List<String> getBootstrapHosts() {
        return couchbaseProperties.getBootstrapHosts();
    }

    @Override
    protected String getBucketName() {
        return couchbaseProperties.getBucketName();
    }

    @Override
    protected String getBucketPassword() {
        return couchbaseProperties.getBucketPassword();
    }

    @Override
    public CouchbaseEnvironment couchbaseEnvironment() {
        return DefaultCouchbaseEnvironment
          .builder()
          .bootstrapHttpDirectPort(couchbaseProperties.getPort())
          .build();
    }
}

さらに、 @EnableReactiveCouchbaseRepositories を使用して、指定されたパッケージの下にあるリアクティブリポジトリを有効にしました。

さらに、Couchbase接続ポートを通過させるために、 couchbaseEnvironment()をオーバーライドしました。

4. リポジトリ

このセクションでは、リアクティブリポジトリを作成して使用する方法を学習します。 デフォルトでは、「すべて」のビューがほとんどのCRUD操作をサポートしています。 カスタムリポジトリメソッドはN1QLによってサポートされています。 クラスタがN1QLをサポートしていない場合、 UnsupportedCouchbaseFeatureException 初期化中にスローされます。

まず、リポジトリが機能するPOJOクラスを作成しましょう。

@Document
public class Person {
    @Id private UUID id;
    private String firstName;

   //getters and setters
}

4.1. ビューベースのリポジトリ

次に、Personのリポジトリを作成します。

@Repository
@ViewIndexed(designDoc = ViewPersonRepository.DESIGN_DOCUMENT)
public interface ViewPersonRepository extends ReactiveCrudRepository<Person, UUID> {

    String DESIGN_DOCUMENT = "person";
}

リポジトリは、Reactor APIを使用してCouchbaseと対話するために、ReactiveCrudRepositoryインターフェイスを拡張します。

さらに、カスタムメソッドを追加し、 @View アノテーションを使用して、ビューベースにすることができます。

@View(designDocument = ViewPersonRepository.DESIGN_DOCUMENT)
Flux<Person> findByFirstName(String firstName);

デフォルトでは、クエリはbyFirstNameという名前のビューを検索します。 カスタムビュー名を指定する場合は、viewName引数を使用する必要があります。

最後に、テストサブスクライバーの助けを借りて簡単なCRUDテストを作成しましょう。

@Test
public void shouldSavePerson_findById_thenDeleteIt() {
    final UUID id = UUID.randomUUID();
    final Person person = new Person(id, "John");
    personRepository
      .save(person)
      .subscribe();
 
    final Mono<Person> byId = personRepository.findById(id);
 
    StepVerifier
      .create(byId)
      .expectNextMatches(result -> result
        .getId()
        .equals(id))
      .expectComplete()
      .verify();
 
    personRepository
      .delete(person)
      .subscribe();
}

4.2. N1QL/ビューベースのリポジトリ

次に、N1QLクエリを使用するPersonのリアクティブリポジトリを作成します。

@Repository
@N1qlPrimaryIndexed
public interface N1QLPersonRepository extends ReactiveCrudRepository<Person, UUID> {
    Flux<Person> findAllByFirstName(String firstName);
}

リポジトリは、Reactor APIも使用するために、ReactiveCrudRepositoryを拡張します。 さらに、カスタム findAllByFirstName メソッドを追加しました。これにより、N1QLに裏打ちされたクエリが作成されます。

その後、findAllByFirstNameメソッドのテストを追加しましょう。

@Test
public void shouldFindAll_byLastName() {
    final String firstName = "John";
    final Person matchingPerson = new Person(UUID.randomUUID(), firstName);
    final Person nonMatchingPerson = new Person(UUID.randomUUID(), "NotJohn");
    personRepository
      .save(matchingPerson)
      .subscribe();
    personRepository
      .save(nonMatchingPerson)
      .subscribe();
 
    final Flux<Person> allByFirstName = personRepository.findAllByFirstName(firstName);
 
    StepVerifier
      .create(allByFirstName)
      .expectNext(matchingPerson)
      .verifyComplete();
}

さらに、並べ替えの抽象化を使用してユーザーを取得できるリポジトリを作成します。

@Repository
public interface N1QLSortingPersonRepository extends ReactiveSortingRepository<Person, UUID> {
    Flux<Person> findAllByFirstName(String firstName, Sort sort);
}

最後に、データが実際に並べ替えられているかどうかを確認するテストを作成しましょう。

@Test
public void shouldFindAll_sortedByFirstName() {
    final Person firstPerson = new Person(UUID.randomUUID(), "John");
    final Person secondPerson = new Person(UUID.randomUUID(), "Mikki");
    personRepository
      .save(firstPerson)
      .subscribe();
    personRepository
      .save(secondPerson)
      .subscribe();
 
    final Flux<Person> allByFirstName = personRepository
      .findAll(Sort.by(Sort.Direction.DESC, "firstName"));
 
    StepVerifier
      .create(allByFirstName)
      .expectNextMatches(person -> person
        .getFirstName()
        .equals(secondPerson.getFirstName()))
      .expectNextMatches(person -> person
        .getFirstName()
        .equals(firstPerson.getFirstName()))
      .verifyComplete();
}

5. 結論

この記事では、CouchbaseとSpringDataReactiveフレームワークでリアクティブプログラミングを使用してリポジトリを使用する方法を学びました。

いつものように、これらの例のコードはGithubから入手できます。