アプリケーションへの Spring Data Cloud Spanner の追加

Spring Data Cloud Spanner モジュールは、Spring Framework で構築された Java アプリケーションで Cloud Spanner を使用する場合に役立ちます。

すべての Spring Data モジュールと同様に、Spring Data Cloud Spanner では Cloud Spanner の整合性の保証とスケーラビリティを保持する Spring ベースのプログラミング モデルが提供されます。その機能は、Cloud Spanner 用に設計されたアノテーションを使用した Spring Data JPAHibernate ORM に似ています。

Spring についてすでに習熟している場合、Spring Data Cloud Spanner を使用すると、アプリケーションで Cloud Spanner を使いやすくなり、作成する必要があるコードの量を減らすことができます。

このページでは、Spring Data Cloud Spanner を Java アプリケーションに追加する方法について説明します。モジュールの詳細については、Spring Data Cloud Spanner リファレンスをご覧ください。

モジュールのインストール

Maven を使用する場合は、Spring Cloud GCP の部品表(BOM)と Spring Data Cloud Spanner を pom.xml ファイルに追加します。これらの依存関係によって、Spring ApplicationContext に Spring Data Cloud Spanner コンポーネントが提供されます。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-dependencies</artifactId>
      <version>1.2.0.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
  </dependency>
</dependencies>

さらに、サービス アカウントを作成し、サービス アカウント キーを使用して Google Cloud で認証する必要もあります。

詳細については、Java 開発環境の設定の手順をご覧ください。Java 用 Google Cloud クライアント ライブラリをインストールする必要はありません。Spring Boot スターターによってクライアント ライブラリが自動的にインストールされます。

モジュールの構成

このセクションでは、Spring Data Cloud Spanner のよく使用されるいくつかの構成設定について説明します。設定の完全なリストについては、リファレンス ドキュメントをご覧ください。

インスタンスとデータベースを指定する

アプリケーションの接続先の Cloud Spanner インスタンスとデータベースを指定する必要があります。

デフォルトのインスタンスとデータベースを指定するには、アプリケーションの次の構成プロパティを設定します。

プロパティ 説明
spring.cloud.gcp.spanner.project-id 省略可。Google Cloud プロジェクト ID。spring.cloud.gcp.config.project-id の値をオーバーライドします。
spring.cloud.gcp.spanner.instance-id Cloud Spanner インスタンス ID。
spring.cloud.gcp.spanner.database 接続先のデータベース。

Cloud Spanner データのモデリング

Spring Data Cloud Spanner では、POJO(Plain Old Java Object)を使用して Cloud Spanner テーブルに格納するデータをモデリングできます。

データベースの各テーブルに対して、そのテーブル内のレコードを表すエンティティを宣言します。アノテーションを使用して、エンティティとそのプロパティをテーブルとその列にマッピングします。

次のアノテーションを使用して、エンティティとテーブルとのシンプルな関係をモデリングできます。

エンティティ アノテーション
@Column(name = "columnName")

省略可。Cloud Spanner テーブルの特定の列にプロパティをマッピングし、名前を自動的にマッピングする命名方法をオーバーライドします。

このプロパティを省略した場合、Spring Data Cloud Spanner のデフォルトの命名方法では、Java の camelCase プロパティ名が PascalCase 列名にマッピングされます。たとえば、プロパティ singerId は列名 SingerId にマッピングされます。

@Embedded

プロパティが、主キーのコンポーネントを保持できる埋め込みオブジェクトであることを示します。プロパティを主キーで実際に使用する場合、@PrimaryKey アノテーションも含める必要があります。

@Interleaved

@Interleaved(lazy = true)

プロパティに、現在の行でインターリーブされる行の一覧が含まれていることを示します。

デフォルトでは、Spring Data Cloud Spanner はインスタンス作成時にインターリーブされた行をフェッチします。行を必要に応じてフェッチするには、プロパティにアクセスする際に @Interleaved(lazy = true) を使用します。

例: Singer エンティティが Album エントリを子としてインターリーブできた場合、List<Album> プロパティを Singer エンティティに追加します。さらに、@Interleaved アノテーションをプロパティに追加します。

@NotMapped

プロパティがデータベースに保存されず、無視されることを示します。

@PrimaryKey

@PrimaryKey(keyOrder = N)

プロパティが主キーのコンポーネントであり、1 から始まる主キー内のプロパティの位置を示します。デフォルトの keyOrder1 です。

例: @PrimaryKey(keyOrder = 3)

@Table(name = "TABLE_NAME")

エンティティによってモデリングされるテーブル。エンティティの各インスタンスは、テーブル内のレコードを表します。TABLE_NAME をテーブルの名前に置換します。

例: @Table(name = "Singers")

より複雑な関係をモデリングする必要がある場合は、モジュールがサポートするその他のアノテーションの詳細について、Spring Data Cloud Spanner リファレンスをご覧ください。

次の例は、Spring Data Cloud Spanner の Singers テーブルと Albums テーブルをモデリングする 1 つの方法を示しています。

  • Singer エンティティの場合、この例では、@Interleaved アノテーションを使用した albums プロパティが含まれます。このプロパティには、Singer エンティティによってインターリーブされるアルバムの一覧が含まれます。Spring Data Cloud Spanner では、このプロパティに自動的に値が設定されます。
  • Album エンティティの場合、この例では、Cloud Spanner に保存されていない relatedAlbums プロパティが含まれます。
import java.util.Date;
import java.util.List;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Embedded;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Interleaved;
import org.springframework.cloud.gcp.data.spanner.core.mapping.PrimaryKey;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Table;

/**
 * An entity and table holding singers.
 */
@Table(name = "Singers")
public class Singer {
  @PrimaryKey
  long singerId;

  String firstName;

  String lastName;

  Date birthDate;

  @Interleaved
  List<Album> albums;
}
import java.util.List;
import org.springframework.cloud.gcp.data.spanner.core.mapping.NotMapped;
import org.springframework.cloud.gcp.data.spanner.core.mapping.PrimaryKey;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Table;

/**
 * An entity class representing an Album.
 */
@Table(name = "Albums")
public class Album {

  @PrimaryKey
  long singerId;

  @PrimaryKey(keyOrder = 2)
  long albumId;

  String albumTitle;

  long marketingBudget;

  @NotMapped
  List<Album> relatedAlbums;

  public Album(long singerId, long albumId, String albumTitle, long marketingBudget) {
    this.singerId = singerId;
    this.albumId = albumId;
    this.albumTitle = albumTitle;
    this.marketingBudget = marketingBudget;
  }
}

データのクエリと変更

Spring Data Cloud Spanner を使用してデータをクエリおよび変更するには、SpannerTemplate Bean を取得できます。これは、SpannerOperations を実装します。SpannerTemplate は、データ操作言語(DML)ステートメントによって、SQL クエリを実行し、データを変更する方法を提供します。この Bean を使用して、Cloud Spanner の読み取り APIMutation API にアクセスすることもできます。

また、SpannerRepository インターフェースを拡張し、Cloud Spanner でデータをクエリおよび変更するすべてのアプリケーション ロジックをカプセル化できます。

次のセクションでは、SpannerTemplateSpannerRepository の操作方法を説明します。

テンプレート Bean の取得

@Autowired アノテーションを使用して、SpannerTemplate Bean を自動的に取得します。その後、クラス全体で SpannerTemplate を使用できます。

次の例は、Bean を取得して使用するクラスを示しています。

import com.google.cloud.spanner.KeySet;
import com.google.cloud.spanner.Statement;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.data.spanner.core.SpannerTemplate;
import org.springframework.stereotype.Component;

/**
 * A quick start code for Spring Data Cloud Spanner. It demonstrates how to use SpannerTemplate to
 * execute DML and SQL queries, save POJOs, and read entities.
 */
@Component
public class SpannerTemplateSample {

  @Autowired
  SpannerTemplate spannerTemplate;

  public void runTemplateExample(Singer singer) {
    // Delete all of the rows in the Singer table.
    this.spannerTemplate.delete(Singer.class, KeySet.all());

    // Insert a singer into the Singers table.
    this.spannerTemplate.insert(singer);

    // Read all of the singers in the Singers table.
    List<Singer> allSingers = this.spannerTemplate
        .query(Singer.class, Statement.of("SELECT * FROM Singers"), null);
  }

}

SpannerTemplate Bean を使用して、読み取り専用トランザクション読み取り / 書き込みトランザクションを実行できます。さらに、@Transactional アノテーションを使用して、宣言型トランザクションを作成できます。

リポジトリ Bean の取得

SpannerRepository を使用する場合、@Autowired アノテーションを使用して、リポジトリのインターフェースを実装する Bean を取得できます。リポジトリには、Java 関数を読み取り専用トランザクション読み取り / 書き込みトランザクションとして実行するためのメソッドが含まれています。下位レベルのオペレーションでは、リポジトリで使用するテンプレート Bean を取得できます。

次の例は、Bean を取得して使用するリポジトリとクラスのインターフェースを示しています。

import com.google.cloud.spanner.Key;
import java.util.List;
import org.springframework.cloud.gcp.data.spanner.repository.SpannerRepository;
import org.springframework.cloud.gcp.data.spanner.repository.query.Query;
import org.springframework.data.repository.query.Param;

/**
 * An interface of various Query Methods. The behavior of the queries is defined only by
 * their names, arguments, or annotated SQL strings. The implementation of these functions
 * is generated by Spring Data Cloud Spanner.
 */
public interface SingerRepository extends SpannerRepository<Singer, Key> {
  List<Singer> findByLastName(String lastName);

  int countByFirstName(String firstName);

  int deleteByLastName(String lastName);

  List<Singer> findTop3DistinctByFirstNameAndSingerIdIgnoreCaseOrLastNameOrderByLastNameDesc(
      String firstName, String lastName, long singerId);

  @Query("SELECT * FROM Singers WHERE firstName LIKE '%@fragment';")
  List<Singer> getByQuery(@Param("fragment") String firstNameFragment);
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * A quick start code for Spring Data Cloud Spanner.
 * It demonstrates how to use a SpannerRepository to execute read-write queries
 * generated from interface definitions.
 *
 */
@Component
public class SpannerRepositorySample {

  @Autowired
  SingerRepository singerRepository;

  public void runRepositoryExample() {
    List<Singer> lastNameSingers = this.singerRepository.findByLastName("a last name");

    int fistNameCount = this.singerRepository.countByFirstName("a first name");

    int deletedLastNameCount = this.singerRepository.deleteByLastName("a last name");
  }

}

Cloud Spanner の管理

Cloud Spanner データベースに関する情報を取得したり、データ定義言語(DDL)ステートメントでスキーマを更新したり、他の管理タスクを行ったりするには、SpannerDatabaseAdminTemplate Bean を取得できます。

@Autowired アノテーションを使用して、Bean を自動的に取得します。その後、クラス全体で SpannerDatabaseAdminTemplate を使用できます。

次の例は、Bean を取得して使用するクラスを示しています。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.data.spanner.core.admin.SpannerDatabaseAdminTemplate;
import org.springframework.cloud.gcp.data.spanner.core.admin.SpannerSchemaUtils;
import org.springframework.stereotype.Component;

/**
 * This sample demonstrates how to generate schemas for interleaved tables from POJOs and how to
 * execute DDL.
 */
@Component
public class SpannerSchemaToolsSample {

  @Autowired
  SpannerDatabaseAdminTemplate spannerDatabaseAdminTemplate;

  @Autowired
  SpannerSchemaUtils spannerSchemaUtils;

  /**
   * Creates the Singers table. Also creates the Albums table, because Albums is interleaved with
   * Singers.
   */
  public void createTableIfNotExists() {
    if (!this.spannerDatabaseAdminTemplate.tableExists("Singers")) {
      this.spannerDatabaseAdminTemplate.executeDdlStrings(
          this.spannerSchemaUtils
              .getCreateTableDdlStringsForInterleavedHierarchy(Singer.class),
          true);
    }
  }

  /**
   * Drops both the Singers and Albums tables using just a reference to the Singer entity type ,
   * because they are interleaved.
   */
  public void dropTables() {
    if (this.spannerDatabaseAdminTemplate.tableExists("Singers")) {
      this.spannerDatabaseAdminTemplate.executeDdlStrings(
          this.spannerSchemaUtils.getDropTableDdlStringsForInterleavedHierarchy(Singer.class),
          false);
    }
  }
}

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud Spanner のドキュメント