Cassandra リポジトリ

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

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

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

  // … getters and setters omitted
}

エンティティには、String 型の id という名前のプロパティがあることに注意してください。MappingCassandraConverter で使用されるデフォルトの変換メカニズム (リポジトリサポートをサポートする) は、id という名前のプロパティを行 ID とみなします。

次の例は、Person エンティティを永続化するためのリポジトリ定義を示しています。

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

  • リアクティブ

interface PersonRepository extends CrudRepository<Person, String> {

  // additional custom finder methods go here
}
interface PersonRepository extends ReactiveCrudRepository<Person, String> {

  // additional custom finder methods go here
}

現時点では、前の例のインターフェースは入力のみを目的としていますが、後で追加のメソッドを追加します。

次に、Spring 構成に次の内容を追加します (構成に Java を使用する場合)。

Java 構成を使用する場合は、@EnableCassandraRepositories および @EnableReactiveCassandraRepositories アノテーションをそれぞれ使用します。アノテーションは名前空間要素と同じ属性を持ちます。基本パッケージが構成されていない場合、インフラストラクチャーは、アノテーションが付けられた構成クラスのパッケージをスキャンします。次の例は、さまざまな構成アプローチの方法を示しています。

リポジトリの構成
  • 命令的な Java 構成

  • XML

  • リアクティブ Java 構成

@Configuration
@EnableCassandraRepositories
class ApplicationConfig extends AbstractCassandraConfiguration {

  @Override
  protected String getKeyspaceName() {
    return "keyspace";
  }

  public String[] getEntityBasePackages() {
    return new String[] { "com.oreilly.springdata.cassandra" };
  }
}
<?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:cassandra="http://www.springframework.org/schema/data/cassandra"
  xsi:schemaLocation="
    http://www.springframework.org/schema/data/cassandra
    https://www.springframework.org/schema/data/cassandra/spring-cassandra.xsd
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">

    <cassandra:session port="9042" keyspace-name="keyspaceName"/>

    <cassandra:mapping
            entity-base-packages="com.acme..entities">
    </cassandra:mapping>

    <cassandra:converter/>

    <cassandra:template/>

    <cassandra:repositories base-package="com.acme..entities"/>
</beans>
@Configuration
@EnableReactiveCassandraRepositories
class ApplicationConfig extends AbstractReactiveCassandraConfiguration {

  @Override
  protected String getKeyspaceName() {
    return "keyspace";
  }

  public String[] getEntityBasePackages() {
    return new String[] { "com.oreilly.springdata.cassandra" };
  }
}

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

ドメインリポジトリは CrudRepository それぞれの ReactiveCrudRepository を継承するため、基本的な CRUD 操作が提供されます。リポジトリインスタンスの操作は、次の例のように PersonRepository をオートワイヤリングすることで、リポジトリを依存関係としてクライアントに挿入することになります。

人物エンティティへの基本アクセス
  • 命令的

  • リアクティブ

@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsPersonTableCorrectly() {

      List<Person> persons = repository.findAll();
      assertThat(persons.isEmpty()).isFalse();
    }
}
public class PersonRepositoryTests {

    @Autowired ReactivePersonRepository repository;

    @Test
    public void sortsElementsCorrectly() {
        Flux<Person> people = repository.findAll(Sort.by(new Order(ASC, "lastname")));
    }
}

Cassandra リポジトリは、エンティティへのページ分割および並べ替えられたアクセスのためのページングと並べ替えをサポートしています。Cassandra ページングでは、ページ内を順方向のみに移動するにはページング状態が必要です。Slice は現在のページング状態を追跡し、次のページをリクエストする Pageable の作成を可能にします。次の例は、Person エンティティへのページングアクセスを設定する方法を示しています。

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

  • リアクティブ

@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsPagesCorrectly() {

      Slice<Person> firstBatch = repository.findAll(CassandraPageRequest.first(10));

      assertThat(firstBatch).hasSize(10);

      Slice<Person> nextBatch = repository.findAll(firstBatch.nextPageable());

      // …
    }
}
@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsPagesCorrectly() {

      Mono<Slice<Person>> firstBatch = repository.findAll(CassandraPageRequest.first(10));

      Mono<Slice<Person>> nextBatch = firstBatch.flatMap(it -> repository.findAll(it.nextPageable()));

      // …
    }
}}
Cassandra リポジトリは PagingAndSortingRepository を継承しません。これは、制限 / オフセットを使用する従来のページングパターンが Cassandra に適用できないためです。

前述の例では、Spring の単体テストサポートを使用してアプリケーションコンテキストを作成し、テストクラスへのアノテーションベースの依存関係の注入を実行します。テストケース (テストメソッド) 内では、リポジトリを使用してデータストアにクエリを実行します。すべての Person インスタンスをリクエストするリポジトリクエリメソッドを呼び出します。

リアクティブリポジトリ

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

  • ReactiveCrudRepository

  • ReactiveSortingRepository

  • RxJava3CrudRepository

  • RxJava3SortingRepository

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