MongoDB リポジトリ

この章では、MongoDB のリポジトリサポートの特殊性について説明します。この章は、コア概念で説明したコアリポジトリサポートに基づいて構築されています。そこで説明されている基本概念を十分に理解している必要があります。

使用方法

MongoDB に保存されているドメインエンティティにアクセスするには、実装を大幅に容易にする高度なリポジトリサポートを使用できます。これを行うには、次の例に示すように、リポジトリのインターフェースを作成します。

例 1: サンプル Person エンティティ
public class Person {

  @Id
  private String id;
  private String firstname;
  private String lastname;
  private Address address;

  // … getters and setters omitted
}

前の例に示されているドメイン型には、型 String の id という名前のプロパティがあることに注意してください。MongoTemplate (リポジトリサポートを支援する) で使用されるデフォルトの直列化メカニズムは、id という名前のプロパティをドキュメント ID とみなします。現在、ID 型として StringObjectIdBigInteger をサポートしています。id フィールドがマッピング層でどのように処理されるかについての詳細は、ID マッピングを参照してください。

ドメインオブジェクトを取得したため、次のようにそれを使用するインターフェースを定義できます。

Person エンティティを永続化する基本的なリポジトリインターフェース
  • 命令的

  • リアクティブ

public interface PersonRepository extends PagingAndSortingRepository<Person, String> {

    // additional custom query methods go here
}
public interface PersonRepository extends ReactiveSortingRepository<Person, String> {

    // additional custom query methods go here
}

リポジトリの使用を開始するには、@EnableMongoRepositories アノテーションを使用します。このアノテーションは、名前空間要素と同じ属性を持ちます。基本パッケージが構成されていない場合、インフラストラクチャーは、アノテーションが付けられた構成クラスのパッケージをスキャンします。次の例は、MongoDB リポジトリを使用するようにアプリケーションを構成する方法を示しています。

  • 命令的

  • リアクティブ

  • XML

@Configuration
@EnableMongoRepositories("com.acme..repositories")
class ApplicationConfig extends AbstractMongoClientConfiguration {

  @Override
  protected String getDatabaseName() {
    return "e-store";
  }

  @Override
  protected String getMappingBasePackage() {
    return "com.acme..repositories";
  }
}
@Configuration
@EnableReactiveMongoRepositories("com.acme..repositories")
class ApplicationConfig extends AbstractReactiveMongoConfiguration {

  @Override
  protected String getDatabaseName() {
    return "e-store";
  }

  @Override
  protected String getMappingBasePackage() {
    return "com.acme..repositories";
  }
}
MongoDB は、命令型 (同期 / ブロッキング) およびリアクティブ (ノンブロッキング) データアクセスに 2 つの異なるドライバーを使用します。Spring Data の Reactive MongoDB サポートに必要なインフラストラクチャを提供するには、Reactive Streams ドライバーを使用して接続を作成する必要があります。MongoDB の Reactive Streams ドライバー用に別の構成を提供する必要があります。リアクティブおよびブロッキング Spring Data MongoDB テンプレートおよびリポジトリを使用する場合、アプリケーションは 2 つの異なる接続で動作することに注意してください。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:mongo="http://www.springframework.org/schema/data/mongo"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/data/mongo
    https://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">

  <mongo:mongo-client id="mongoClient" />

  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongoClient" />
    <constructor-arg value="databaseName" />
  </bean>

  <mongo:repositories base-package="com.acme.*.repositories" />

</beans>

この名前空間要素により、基本パッケージで MongoRepository を継承するインターフェースがスキャンされ、見つかったインターフェースごとに Spring Bean が作成されます。デフォルトでは、リポジトリは mongoTemplate と呼ばれる MongoTemplate Spring Bean を有線で取得するため、この規則から逸脱する場合のみ mongo-template-ref を明示的に構成する必要があります。

ドメインリポジトリは PagingAndSortingRepository を継承しているため、エンティティへのページ分割および並べ替えられたアクセスのためのメソッドが提供されます。リアクティブリポジトリの場合は、Page の概念が適用できないため、ReactiveSortingRepository のみが利用可能です。ただし、ファインダーメソッドは引き続き Sort および Limit パラメーターを受け入れます。

リアクティブスペースでは、さまざまなリアクティブ組成ライブラリを提供します。最も一般的なライブラリは RxJava [GitHub] (英語) およびプロジェクト Reactor (英語) です。

Spring Data MongoDB は MongoDB Reactive Streams (英語) ドライバー上に構築されており、Reactive Streams (英語) イニシアチブに依存することで最大限の相互運用性を提供します。ReactiveMongoOperations などの静的 API は、プロジェクト Reactor の Flux および Mono 型を使用して提供されます。プロジェクト Reactor は、リアクティブラッパー型 (Flux から Observable、またはその逆) を変換するためのさまざまなアダプターを提供しますが、変換によりコードが簡単に乱雑になる可能性があります。

Spring Data のリアクティブリポジトリ抽象化は動的 API であり、クエリメソッドを宣言する際に、主にユーザーと要件によって定義されます。リアクティブ MongoDB リポジトリは、次のライブラリ固有のリポジトリインターフェースのいずれかを継承することにより、RxJava または Project Reactor ラッパー型を使用して実装できます。

  • ReactiveCrudRepository

  • ReactiveSortingRepository

  • RxJava3CrudRepository

  • RxJava3SortingRepository

Spring Data はバックグラウンドでリアクティブラッパー型を変換するため、お気に入りの合成ライブラリをそのまま使用できます。

基本的な CRUD 操作のメソッドを取得したい場合は、CrudRepository インターフェースも追加します。リポジトリインスタンスの操作は、依存関係をクライアントに注入するだけの問題です。ページサイズ 10 で Person オブジェクトの 2 番目のページにアクセスすると、次のコードのようになります。

個人エンティティへのページングアクセス
  • 命令的

  • リアクティブ

@ExtendWith(SpringExtension.class)
@ContextConfiguration
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsFirstPageCorrectly() {

      Page<Person> persons = repository.findAll(PageRequest.of(0, 10));
      assertThat(persons.isFirstPage()).isTrue();
    }
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsFirstPageCorrectly() {

        Flux<Person> persons = repository.findAll(Sort.unsorted(), Limit.of(10));

        persons.as(StepVerifer::create)
            .expectNextCount(10)
            .verifyComplete();
    }
}

前述の例では、Spring の単体テストサポートを使用してアプリケーションコンテキストを作成し、テストケースへのアノテーションベースの依存関係の注入を実行します。テストメソッド内では、リポジトリを使用してデータストアにクエリを実行します。ページサイズ 10 で Person オブジェクトの最初のページをリクエストする PageRequest インスタンスをリポジトリに渡します。