MongoDBによるSpringデータ対応リポジトリ

データ]

  • リンク:/tag/mongodb/[MongoDB]

1前書き

このチュートリアルでは、MongoDBのSpring Data Reactive RepositoriesからReactive Programmingを使用してデータベース操作を構成および実装する方法を説明します。

ReactiveCrudRepository、 ReactiveMongoRepository、 、さらには__ReactiveMongoTemplateの基本的な使い方について説明します。

これらの実装では リアクティブプログラミング を使用しますが、それがこのチュートリアルの主な焦点ではありません。

2環境

Reactive MongoDBを使用するには、__pom.xmlに依存関係を追加する必要があります。

テスト用に埋め込みMongoDBも追加します。

<dependencies>
   //...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
    </dependency>
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3構成

リアクティブサポートを有効にするには、いくつかのインフラストラクチャ設定と共に @ EnableReactiveMongoRepositories を使用する必要があります。

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

    @Bean
    public MongoClient mongoClient() {
        return MongoClients.create();
    }

    @Override
    protected String getDatabaseName() {
        return "reactive";
    }
}

スタンドアロンのMongoDBインストールを使用している場合、上記が必要になることに注意してください。ただし、この例では組み込みのMongoDBと一緒にSpring Bootを使用しているため、上記の構成は必要ありません。

4 Document を作成する

以下の例では、 Account クラスを作成し、それに @ Document というアノテーションを付けてデータベース操作で使用します。

@Document
public class Account {

    @Id
    private String id;
    private String owner;
    private Double value;

   //getters and setters
}

5リアクティブリポジトリの使用

CRUDメソッドはすでに定義されており、他の一般的なものもサポートされています。

Reactiveモデルでは、結果とパラメータを反応的な方法で扱うことを除いて、同じ一連のメソッドと仕様が得られます。

5.1. ReactiveCrudRepository

このリポジトリは、 CrudRepository をブロックするのと同じ方法で使用できます。

@Repository
public interface AccountCrudRepository
  extends ReactiveCrudRepository<Account, String> {

    Flux<Account> findAllByValue(String value);
    Mono<Account> findFirstByOwner(Mono<String> owner);
}

findFirstByOwner() メソッドでわかるように、プレーン( String )、ラップ( Optional Stream )、またはリアクティブ( Mono Flux )など、さまざまなタイプの引数を渡すことができます。

5.2. ReactiveMongoRepository

ReactiveCrudRepository から継承し、いくつかの新しいクエリメソッドを追加した ReactiveMongoRepository インターフェースもあります。

@Repository
public interface AccountReactiveRepository
  extends ReactiveMongoRepository<Account, String> { }

ReactiveMongoRepository を使用して、例としてクエリを実行できます。

Flux<Account> accountFlux = repository
  .findAll(Example.of(new Account(null, "owner", null)));

結果として、渡された例と同じすべての Account が得られます。

私たちのリポジトリが作成されたので、それらはすでに我々が実装する必要がないいくつかのデータベース操作を実行するためのメソッドを定義しました:

Mono<Account> accountMono
  = repository.save(new Account(null, "owner", 12.3));
Mono<Account> accountMono2 = repository
  .findById("123456");

5.3. RxJava2CrudRepository

RxJava2CrudRepositoryを使用すると、 ReactiveCrudRepositoryと同じ動作になります。

@Repository
public interface AccountRxJavaRepository
  extends RxJava2CrudRepository<Account, String> {

    Observable<Account> findAllByValue(Double value);
    Single<Account> findFirstByOwner(Single<String> owner);
}

5.4. 基本操作のテスト

リポジトリメソッドをテストするために、テストサブスクライバを使用します。

@Test
public void givenValue__whenFindAllByValue__thenFindAccount() {
    repository.save(new Account(null, "Bill", 12.3)).block();
    Flux<Account> accountFlux = repository.findAllByValue(12.3);

    StepVerifier
      .create(accountFlux)
      .assertNext(account -> {
          assertEquals("Bill", account.getOwner());
          assertEquals(Double.valueOf(12.3) , account.getValue());
          assertNotNull(account.getId());
      })
      .expectComplete()
      .verify();
}

@Test
public void givenOwner__whenFindFirstByOwner__thenFindAccount() {
    repository.save(new Account(null, "Bill", 12.3)).block();
    Mono<Account> accountMono = repository
      .findFirstByOwner(Mono.just("Bill"));

    StepVerifier
      .create(accountMono)
      .assertNext(account -> {
          assertEquals("Bill", account.getOwner());
          assertEquals(Double.valueOf(12.3) , account.getValue());
          assertNotNull(account.getId());
      })
      .expectComplete()
      .verify();
}

@Test
public void givenAccount__whenSave__thenSaveAccount() {
    Mono<Account> accountMono = repository.save(new Account(null, "Bill", 12.3));

    StepVerifier
      .create(accountMono)
      .assertNext(account -> assertNotNull(account.getId()))
      .expectComplete()
      .verify();
}

6. ReactiveMongoTemplate

リポジトリアプローチの他に、 ReactiveMongoTemplate があります。

まず最初に、 ReactiveMongoTemplate をBeanとして登録する必要があります。

@Configuration
public class ReactiveMongoConfig {

    @Autowired
    MongoClient mongoClient;

    @Bean
    public ReactiveMongoTemplate reactiveMongoTemplate() {
        return new ReactiveMongoTemplate(mongoClient, "test");
    }
}

そして、このBeanをサービスに注入してデータベース操作を実行できます。

@Service
public class AccountTemplateOperations {

    @Autowired
    ReactiveMongoTemplate template;

    public Mono<Account> findById(String id) {
        return template.findById(id, Account.class);
    }

    public Flux<Account> findAll() {
        return template.findAll(Account.class);
    }
    public Mono<Account> save(Mono<Account> account) {
        return template.save(account);
    }
}

ReactiveMongoTemplate には、私たちが持っているドメインに関連しない多くのメソッドもあります。それらをhttps://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/でチェックアウトできますdata/mongodb/core/ReactiveMongoTemplate.html[ドキュメント]。

7. 結論

この短いチュートリアルでは、MongoDBとSpring Data Reactive Repositoriesフレームワークを組み合わせたリアクティブプログラミングを使用したリポジトリとテンプレートの使用について説明しました。

例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-5-data-reactive[over on GitHub]にあります。