1. 序章

同じアプリケーションで複数のデータベーステクノロジーに接続する必要がある場合があります。

このチュートリアルでは、同じアプリケーションで複数のSpring Dataモジュールを使用するに関して、さまざまな構成オプションについて説明します。

おもちゃのSpring Boot書店を使ってトピックを調べてみましょう。

2. 必要な依存関係

まず、 pom.xml ファイルに依存関係を追加して、spring-boot-starter-data-mongodbおよびspring-boot-を使用できるようにする必要があります。 starter-data-cassandra Spring Bootデータバインディング:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-cassandra</artifactId>
  <version>2.2.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
  <version>2.2.2.RELEASE</version>
</dependency>

3. データベースの設定

次に、 CassandraMongoのビルド済みDocker イメージを使用して、実際のデータベースをセットアップする必要があります。[ X141X]

$ docker run --name mongo-db -d -p 27017:27017 mongo:latest
$ docker run --name cassandra-db -d -p 9042:9042 cassandra:latest

これらの2つのコマンドは、最新のCassandraおよびMongoDB Dockerイメージを自動的にダウンロードし、実際のコンテナーを実行します。

また、アプリケーションがデータベースにアクセスできるように、実際のOS環境のコンテナー内から( -p オプションを使用して)ポートを転送する必要があります。

cqlsh ユーティリティを使用して、Cassandraのデータベース構造を作成する必要があります。 キースペースの作成はCassandraDataAutoConfigurationでは自動的に実行できないため、CQL構文を使用して宣言する必要があります。

まず、Cassandraコンテナのbashシェルに接続します。

$ docker exec -it cassandra-db /bin/bash
root@419acd18891e:/# cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> CREATE KEYSPACE IF NOT exists baeldung 
WITH replication = {'class':'SimpleStrategy', 'replication_factor':1};
cqlsh> USE baeldung;
cqlsh> CREATE TABLE bookaudit(
   bookid VARCHAR,
   rentalrecno VARCHAR,
   loandate VARCHAR,
   loaner VARCHAR,
   primary key(bookid, rentalrecno)
);

6行目と9行目で、関連するキースペースとテーブルを作成します。

テーブルの作成をスキップして、 spring-boot-starter-data-cassandra に依存してスキーマを初期化することもできますが、フレームワーク構成を個別に調査するため、これは必要な手順です。

デフォルトでは、Mongoはいかなる種類のスキーマ検証も課しません。したがって、他に何も設定する必要はありません

最後に、application.propertiesでデータベースに関する関連情報を構成します。

spring.data.cassandra.username=cassandra
spring.data.cassandra.password=cassandra
spring.data.cassandra.keyspaceName=baeldung
spring.data.cassandra.contactPoints=localhost
spring.data.cassandra.port=9042
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=baeldung

4. データストア検出メカニズム

クラスパスで複数のSpringDataモジュールが検出されると、Springフレームワークは厳密なリポジトリ構成モードに入ります。これは、どのリポジトリがどの永続化テクノロジーに属しているかを識別するために、その下にあるさまざまな検出メカニズムを使用することを意味します。

4.1. モジュール固有のリポジトリインターフェイスの拡張

最初のメカニズムは、リポジトリがSpringDataモジュール固有のリポジトリタイプを拡張するかどうかを判断しようとします。

public interface BookAuditRepository extends CassandraRepository<BookAudit, String> {

}

この例では、 BookAudit.java には、本を貸し出したユーザーを追跡するための基本的なストレージ構造が含まれています。

public class BookAudit {
  private String bookId;
  private String rentalRecNo;
  private String loaner;
  private String loanDate;
 
  // standard getters and setters
}

同じことがMongoDB関連のリポジトリ定義にも当てはまります。

public interface BookDocumentRepository extends MongoRepository<BookDocument, String> {

}

これは、本の内容とそれに関連するいくつかのメタデータを格納します。

public class BookDocument {
  private String bookId;
  private String bookName;
  private String bookAuthor;
  private String content;
  
  // standard getters and setters
}

アプリケーションコンテキストがロードされると、フレームワークは、から派生した基本クラスを使用して各リポジトリタイプと一致します。

@Test
public void givenBookAudit_whenPersistWithBookAuditRepository_thenSuccess() {

  // given
  BookAudit bookAudit = 
    new BookAudit("lorem", "ipsum", "Baeldung", "19:30/20.08.2017");

  // when
  bookAuditRepository.save(bookAudit);

  // then
  List<BookAudit> result = bookAuditRepository.findAll();
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookAudit), is(true));
}

ドメインクラスは単純なJavaオブジェクトであることがわかります。 この特定の状況では、セクション3で行ったように、CassandraデータベーススキーマをCQLを使用して外部で作成する必要があります。

4.2. ドメインオブジェクトでのモジュール固有の注釈の使用

2番目の戦略は、ドメインオブジェクトのモジュール固有の注釈に基づいて永続化テクノロジーを決定します。

一般的なCrudRepostitoryを拡張し、検出のために管理対象オブジェクトの注釈に依存してみましょう。

public interface BookAuditCrudRepository extends CrudRepository<BookAudit, String> {

}
public interface BookDocumentCrudRepository extends CrudRepository<BookDocument, String> {

}

BookAudit.java は、Cassandra固有の @Table で注釈が付けられるようになり、複合主キーが必要になります。

@Table
public class BookAudit {
  
  @PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED)
  private String bookId;
  @PrimaryKeyColumn
  private String rentalRecNo;
  private String loaner;
  private String loanDate;
  
  // standard getters and setters
}

アプリケーションは、誰かが本を貸し出すたびに新しいレンタルレコードをログに記録するだけなので、bookIdrentalRecNoの組み合わせを独自の基準として選択します。

BookDocument.java には、MongoDB固有の@Documentアノテーションを使用します。

@Document
public class BookDocument {

  private String bookId;
  private String bookName;
  private String bookAuthor;
  private String content;
 
  // standard getters and setters
}

CrudRepositoryを使用してBookDocument saveをトリガーすることは引き続き成功しますが、11行目に返されるタイプはListではなくIterableになります。 :

@Test
public void givenBookAudit_whenPersistWithBookDocumentCrudRepository_thenSuccess() {
 
  // given
  BookDocument bookDocument = 
    new BookDocument("lorem", "Foundation", "Isaac Asimov", "Once upon a time ...");
 
  // when
  bookDocumentCrudRepository.save(bookDocument);
  
  // then
  Iterable<BookDocument> resultIterable = bookDocumentCrudRepository.findAll();
  List<BookDocument> result = StreamSupport.stream(resultIterable.spliterator(), false)
                                           .collect(Collectors.toList());
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookDocument), is(true));
}

4.3. パッケージベースのスコープの使用

最後に、 @EnableCassandraRepositoriesおよび@EnableMongoRepositoriesアノテーションを使用して、リポジトリが定義されている基本パッケージを指定できます。

@EnableCassandraRepositories(basePackages="com.baeldung.multipledatamodules.cassandra")
@EnableMongoRepositories(basePackages="com.baeldung.multipledatamodules.mongo")
public class SpringDataMultipleModules {

  public static void main(String[] args) {
    SpringApplication.run(SpringDataMultipleModules.class, args);
  }
}

1行目と2行目にあるように、この構成モードは、CassandraリポジトリとMongoDBリポジトリに異なるパッケージを使用することを前提としています。

5. 結論

このチュートリアルでは、2つの異なるSpring Dataモジュールを3つの方法で使用するように単純なSpring Bootアプリケーションを構成しました。

最初の例として、CassandraRepositoryMongoRepositoryを拡張し、ドメインオブジェクトに単純なクラスを使用しました。

2番目のアプローチでは、汎用の CrudRepository インターフェイスを拡張し、管理対象オブジェクトの@Table@Documentなどのモジュール固有のアノテーションに依存しました。

最終的に、@EnableCassandraRepositoriesおよび@EnableMongoRepositoriesを使用してアプリケーションを構成するときに、パッケージベースの検出を使用しました。

いつものように、完全なコードはGitHubから入手できます。