1. 概要
Cloud Spanner は、可用性が高く水平スケーリングが可能なマルチリージョン RDBMS です。この Codelab では Cloud Spanner の最小インスタンスを使用しますが、作業が終了したら必ずシャットダウンしてください。
学習内容
- Cloud Spanner を使用して Spring Boot でデータを保存および取得する方法
必要なもの
このチュートリアルの利用方法をお選びください。
Google Cloud Platform サービスのご利用経験についてどのように評価されますか?
<ph type="x-smartling-placeholder">2. 設定と要件
セルフペース型の環境設定
- Cloud Console にログインし、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントまたは G Suite アカウントをお持ちでない場合は、アカウントを作成する必要があります)。
プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID
と呼びます。
- 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。
このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。
Cloud Shell をアクティブにする
- Cloud Console で、[Cloud Shell をアクティブにする] をクリックします。
Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。このワンタイム スクリーンは次のようになります。
Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。
この仮想マシンには、必要な開発ツールがすべて準備されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。
Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。
- Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list
コマンド出力
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
gcloud config list project
コマンド出力
[core] project = <PROJECT_ID>
上記のようになっていない場合は、次のコマンドで設定できます。
gcloud config set project <PROJECT_ID>
コマンド出力
Updated property [core/project].
3. Cloud Spanner を初期化する
gcloud CLI を使用して Cloud Spanner API を有効にします。
gcloud services enable spanner.googleapis.com
Cloud Spanner インスタンスを作成します。
gcloud spanner instances create spanner-instance \ --config=regional-us-central1 \ --nodes=1 --description="A Spanner Instance"
インスタンス内にデータベースを作成します。
gcloud spanner databases create orders \ --instance=spanner-instance
データスキーマを記述する schema.ddl
ファイルを作成します。
cat << EOF > schema.ddl CREATE TABLE orders ( order_id STRING(36) NOT NULL, description STRING(255), creation_timestamp TIMESTAMP, ) PRIMARY KEY (order_id); CREATE TABLE order_items ( order_id STRING(36) NOT NULL, order_item_id STRING(36) NOT NULL, description STRING(255), quantity INT64, ) PRIMARY KEY (order_id, order_item_id), INTERLEAVE IN PARENT orders ON DELETE CASCADE; EOF
Cloud Spanner データベースにスキーマを適用します。
gcloud spanner databases ddl update orders \ --instance=spanner-instance \ --ddl="$(<schema.ddl)"
4. 新しい Spring Boot Java アプリケーションをブートストラップする
Cloud Shell 環境から次のコマンドを使用して、新しい Spring Boot アプリケーションを初期化し、ブートストラップします。
$ curl https://start.spring.io/starter.tgz \ -d packaging=jar \ -d dependencies=cloud-gcp,web,lombok \ -d baseDir=spanner-example \ -d type=maven-project \ -d bootVersion=3.2.6 | tar -xzvf - $ cd spanner-example
これにより、新しい Maven プロジェクトを含む新しい spanner-example/
ディレクトリ、Maven の pom.xml
、Maven ラッパー、アプリケーション エントリポイントが作成されます。
pom.xml
ファイルで、Spring Data Cloud Spanner スターターを追加します。
spanner-example/pom.xml
<project>
...
<dependencies>
...
<!-- Add Spring Cloud GCP Spanner Starter -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
</dependency>
...
</dependencies>
...
</project>
application.properties で、Spanner データベースの接続情報を構成します。
spanner-example/src/main/resources/application.properties
spring.cloud.gcp.spanner.instance-id=spanner-instance spring.cloud.gcp.spanner.database=orders
JAVA_HOME
が正しいバージョンに設定されていることを確認します。
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/
アプリを再ビルドして、Maven の構成が正しいことを確認します。
./mvnw package
5. エンティティを作成する
Spring Cloud GCP の Spring Data Spanner サポートにより、Spring Data を使用して Java オブジェクトと Spanner テーブルへの慣用的な ORM マッピングを簡単に作成できます。
まず、Order Item クラスを作成します。
spanner-example/src/main/java/com/example/demo/OrderItem.java
package com.example.demo;
import com.google.cloud.spring.data.spanner.core.mapping.Column;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
@Table(name="order_items")
@Data
class OrderItem {
@PrimaryKey(keyOrder = 1)
@Column(name="order_id")
private String orderId;
@PrimaryKey(keyOrder = 2)
@Column(name="order_item_id")
private String orderItemId;
private String description;
private Long quantity;
}
Spanner の親子関係には、複合主キーを使用する必要があります。この例では、複合キーは order_id
と order_item_id
です。
次に、Order クラスを作成します。
spanner-example/src/main/java/com/example/demo/Order.java
package com.example.demo;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Data;
import com.google.cloud.spring.data.spanner.core.mapping.Column;
import com.google.cloud.spring.data.spanner.core.mapping.Interleaved;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
@Table(name="orders")
@Data
public class Order {
@PrimaryKey
@Column(name="order_id")
private String id;
private String description;
@Column(name="creation_timestamp")
private LocalDateTime timestamp;
@Interleaved
private List<OrderItem> items;
}
このクラスでは、@Interleaved
アノテーションを使用して、Order Item との 1 対多のリレーションを作成します。
6. OrderRepository インターフェースを作成する
次の内容で OrderRepository
クラスを作成します。
spanner-example/src/main/java/com/example/demo/OrderRepository.java
package com.example.demo;
import com.google.cloud.spring.data.spanner.repository.SpannerRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderRepository extends SpannerRepository<Order, String> {
}
このインターフェースは SpannerRepository<Order, String>
を拡張します。ここで、Order
はドメインクラス、String
は主キーの型です。Spring Data はこのインターフェースを通じて自動的に CRUD アクセスを提供するため、追加のコードを作成する必要はありません。
7. 基本的なオペレーション用の REST コントローラを作成する
メイン アプリケーションの DemoApplication
クラスを開き、次のように変更します。
spanner-example/src/main/java/com/example/demo/DemoApplication.java
package com.example.demo;
import java.time.LocalDateTime;
import java.util.UUID;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class OrderController {
private final OrderRepository orderRepository;
OrderController(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@GetMapping("/api/orders/{id}")
public Order getOrder(@PathVariable String id) {
return orderRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found"));
}
@PostMapping("/api/orders")
public String createOrder(@RequestBody Order order) {
// Spanner currently does not auto generate IDs
// Generate UUID on new orders
order.setId(UUID.randomUUID().toString());
order.setTimestamp(LocalDateTime.now());
order.getItems().forEach(item -> {
// Assign parent ID, and also generate child ID
item.setOrderId(order.getId());
item.setOrderItemId(UUID.randomUUID().toString());
});
Order saved = orderRepository.save(order);
return saved.getId();
}
}
8. アプリケーションを実行する
アプリケーションを再ビルドして実行します。
./mvnw spring-boot:run
正常に開始され、ポート 8080 をリッスンするはずです。
注文レコードをエンドポイントに送信することができます。
curl -H"Content-Type: application/json" -d'{"description": "My orders", "items": [{"description": "Android Phone", "quantity": "1"}]}' \ http://localhost:8080/api/orders
オーダーの UUID
が返されます。
その後、UUID
を使用して Order を取得できます。
curl http://localhost:8080/api/orders/REPLACE_WITH_ORDER_UUID
Cloud Spanner にデータがどのように保存されているかを確認するには、Cloud コンソールに移動して [Spanner] → [Spanner インスタンス] → [注文データベース] → [注文テーブル] → [データ] に移動します。
9. クリーンアップ
クリーンアップするには、Spanner インスタンスを削除して、料金が発生しないようにします。
gcloud spanner instances delete spanner-instance -q
10. 完了
この Codelab では、Cloud Spanner にデータを保存および取得できるインタラクティブな CLI アプリケーションを作成しました。
詳細
- Cloud Spanner: https://cloud.google.com/spanner/
- GCP プロジェクトの Spring: https://googlecloudplatform.github.io/spring-cloud-gcp/reference/html/
- GCP の Spring の GitHub リポジトリ: https://github.com/spring-cloud/spring-cloud-gcp
- Google Cloud Platform での Java: https://cloud.google.com/java/
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。