目標
このチュートリアルでは、Spanner JDBC ドライバを使用する以下の手順について説明します。
- Spanner のインスタンスとデータベースを作成します。
- データベースのデータに対し、書き込み、読み取り、SQL クエリの実行を行います。
- データベース スキーマを更新します。
- 読み取り / 書き込みトランザクションを使用してデータを更新します。
- セカンダリ インデックスをデータベースに追加します。
- インデックスを使用して、データの読み込みと SQL クエリの実行を行います。
- 読み取り専用トランザクションを使用してデータを取得します。
費用
このチュートリアルで使用する Spanner は、Google Cloud の有料コンポーネントです。Spanner を使用する際の料金については、料金をご覧ください。
始める前に
設定に示されている手順を完了します。この手順では、デフォルトの Google Cloud プロジェクトの作成と設定、課金の有効化、Cloud Spanner API の有効化、Cloud Spanner API の使用に必要な認証情報を取得するための OAuth 2.0 の設定について説明しています。
特に、ローカルの開発環境に認証情報を設定するために、必ず gcloud auth
application-default login
を実行してください。
ローカル JDBC 環境を準備する
開発マシンに次のものがまだインストールされていない場合はインストールします。
ローカルマシンにサンプルアプリのリポジトリのクローンを作成します。
git clone https://github.com/googleapis/java-spanner-jdbc.git
Spanner のサンプルコードが含まれるディレクトリに移動します。
cd java-spanner-jdbc/samples/snippets
インスタンスを作成する
Spanner を最初に使用する場合は、インスタンスを作成する必要があります。インスタンスとは、Spanner データベースによって使用されるリソースの割り当てのことです。インスタンスを作成するときは、インスタンス構成を選択してデータの格納場所を指定し、さらに使用するノード数も選択して、インスタンスの配信リソースおよびストレージ リソースの量を決定します。
次のコマンドを実行して、1 ノードの us-central1
リージョンに Spanner インスタンスを作成します。
gcloud spanner instances create test-instance --config=regional-us-central1 \
--description="Test Instance" --nodes=1
これにより、次の特性を持つインスタンスが作成されます。
- インスタンス ID
test-instance
- 表示名
Test Instance
- インスタンス構成
regional-us-central1
(リージョン構成ではデータが単一のリージョンに保存され、マルチリージョン構成ではデータが複数のリージョンに分散されます。詳しくは、インスタンスについてをご覧ください)。 - ノード数 1(
node_count
はインスタンスのデータベースで使用可能な配信リソースとストレージ リソースの量に対応します。詳しくは、ノードと処理ユニットをご覧ください)。
以下のように表示されます。
Creating instance...done.
サンプル ファイルの確認
サンプル リポジトリには、JDBC で Spanner を使用する方法を示すサンプルが含まれています。
pom.xml
は、Spanner JDBC ドライバをプロジェクトの依存関係に追加し、このチュートリアルで定義される Java クラスを含む実行可能 JAR ファイルをビルドするためのアセンブリ プラグインを構成します。
samples/snippets
ディレクトリでサンプルをビルドします。
mvn package -DskipTests
データベースの作成
コマンドラインで次のコマンドを実行して、test-instance
というインスタンスに example-db
というデータベースを作成します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
createdatabase test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
createpgdatabase test-instance example-db
次のように表示されます。
Created database [projects/my-project/instances/test-instance/databases/example-db]
次のコードでは、データベースとデータベース内の 2 つのテーブルを作成します。
GoogleSQL
PostgreSQL
次のステップでは、データベースにデータを書き込みます。
JDBC 接続を作成する
読み取りまたは書き込みを行うには、その前にConnection
を作成する必要があります。Spanner とのすべてのやり取りは Connection
を経由する必要があります。データベース名とその他のプロパティは、JDBC 接続 URL と java.util.Properties
セットで指定されます。
GoogleSQL
PostgreSQL
サポートされているプロパティの一覧については、接続 URL のプロパティをご覧ください。
各 Connection
はリソースを使用するため、不要になった接続を閉じるか、接続プールを使用してアプリケーション全体で接続を再利用することをおすすめします。
詳細については、Connection
Javadoc リファレンスをご覧ください。
JDBC ドライバをエミュレータに接続する
JDBC ドライバを Spanner エミュレータに接続するには、次の 2 つの方法があります。
SPANNER_EMULATOR_HOST
環境変数を設定する。これにより、JDBC ドライバはエミュレータに接続するよう指示されます。JDBC 接続 URL の Spanner インスタンスとデータベースが、エミュレータにすでに存在している必要があります。- 接続 URL に
autoConfigEmulator=true
を追加する。これにより、JDBC ドライバはエミュレータに接続するように指示され、Spanner インスタンスとデータベースが存在しない場合は、JDBC 接続 URL に自動的に作成します。
この例では、autoConfigEmulator=true
接続 URL オプションを使用する方法を示します。
GoogleSQL
PostgreSQL
DML でのデータの書き込み
読み取り / 書き込みトランザクションでデータ操作言語(DML)を使用してデータを挿入できます。
PreparedStatement.executeUpdate()
メソッドを使用して DML ステートメントを実行します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writeusingdml test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writeusingdmlpg test-instance example-db
次のように表示されます。
4 records inserted.
DML バッチでのデータの書き込み
PreparedStatement#addBatch()
と PreparedStatement#executeBatch()
メソッドを使用して、複数の DML ステートメントを 1 つのバッチで実行します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writeusingdmlbatch test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writeusingdmlbatchpg test-instance example-db
次のように表示されます。
3 records inserted.
ミューテーションを使用してデータを書き込む
ミューテーションを使ってデータを挿入することもできます。
データの書き込みには Mutation
オブジェクトを使用します。Mutation
オブジェクトは、ミューテーション オペレーションのコンテナです。Mutation
は、Spanner データベース内のさまざまな行やテーブルに対して、Spanner によってアトミックに適用される一連の操作(挿入、更新、削除)を表します。
Mutation
クラスの newInsertBuilder()
メソッドは、テーブルに新しい行を挿入する INSERT
ミューテーションを作成します。行がすでに存在する場合、書き込みは失敗します。または、newInsertOrUpdateBuilder
メソッドを使用して INSERT_OR_UPDATE
ミューテーションを作成できます。これにより、行がすでに存在している場合に列値が更新されます。
CloudSpannerJdbcConnection
インターフェースの write()
メソッドはミューテーションを書き込みます。1 つのバッチ内のミューテーションはすべてアトミックに適用されます。
Spanner JDBC Connection
から CloudSpannerJdbcConnection
インターフェースのラップを解除できます。
次のコードは、ミューテーションを使用してデータを書き込む方法を示しています。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
write test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writepg test-instance example-db
次のように表示されます。
Inserted 10 rows.
SQL を使用したデータのクエリ
Spanner では、データの読み取り用に SQL インターフェースがサポートされています。このインターフェースにアクセスするには、コマンドラインで Google Cloud CLI を使用するか、プログラムで Spanner JDBC ドライバを使用します。
コマンドラインから
Albums
テーブルのすべての列から値を読み取るには、次の SQL ステートメントを実行します。
GoogleSQL
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
PostgreSQL
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT singer_id, album_id, album_title FROM albums'
結果は次のようになります。
SingerId AlbumId AlbumTitle
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
Spanner JDBC ドライバを使用する
コマンドラインで SQL ステートメントを実行するだけでなく、Spanner JDBC ドライバを使用して、同じ SQL ステートメントをプログラマティックに発行できます。
SQL クエリの実行には次のメソッドとクラスが使用されます。Connection
インターフェースのcreateStatement()
メソッド: SQL ステートメントを実行するための新しいステートメント オブジェクトを作成します。Statement
クラスのexecuteQuery(String)
メソッド: データベースに対してクエリを実行します。Statement
クラス: SQL 文字列を実行します。ResultSet
クラス: SQL ステートメントから返されたデータにアクセスします。
クエリを発行してデータにアクセスする方法を次に示します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
query test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
querypg test-instance example-db
次のような結果が表示されます。
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
SQL パラメータを使用したクエリ
アプリケーションに頻繁に実行されるクエリがある場合は、対象のクエリをパラメータ化してパフォーマンスを改善できます。パラメータ クエリをキャッシュに保存して再利用できます。これにより、コンパイルのコストを削減できます。詳細については、クエリ パラメータを使用して、頻繁に実行するクエリを高速化するをご覧ください。
ここでは、WHERE
句のパラメータを使用して、LastName
の特定の値を含むレコードをクエリします。
java.sql.PreparedStatement
を使用して、パラメータを指定してクエリを実行します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
querywithparameter test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
querywithparameterpg test-instance example-db
次のような結果が表示されます。
12 Melissa Garcia
データベース スキーマの更新
MarketingBudget
という列を新たに Albums
テーブルに追加する必要があるとします。既存のテーブルに新しい列を追加するには、データベース スキーマの更新が必要です。Spanner は、データベースがトラフィックの処理を継続している間にデータベースのスキーマを更新することをサポートしています。スキーマの更新では、データベースをオフラインにする必要がなく、テーブル全体または列全体をロックすることもありません。スキーマの更新中もデータベースへのデータの書き込みを続けることができます。サポートされるスキーマの更新とスキーマ変更のパフォーマンスの詳細については、スキーマの更新をご覧ください。
列の追加
列を追加するには、コマンドラインで Google Cloud CLI を使用するか、プログラムで Spanner JDBC ドライバを使用します。
コマンドラインから
テーブルに新しい列を追加するには、次の ALTER TABLE
コマンドを使用します。
GoogleSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'
PostgreSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE albums ADD COLUMN marketing_budget BIGINT'
次のように表示されます。
Schema updating...done.
Spanner JDBC ドライバを使用する
スキーマを変更するには、java.sql.Statement
クラスの execute(String)
メソッドを使用します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
addmarketingbudget test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
addmarketingbudgetpg test-instance example-db
次のように表示されます。
Added MarketingBudget column.
DDL バッチを実行する
複数のスキーマ変更を 1 つのバッチで実行することをおすすめします。java.sql.Statement
の addBatch(String)
メソッドを使用して、複数の DDL ステートメントをバッチに追加します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
ddlbatch test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
ddlbatchpg test-instance example-db
次のように表示されます。
Added Venues and Concerts tables.
新しい列へのデータの書き込み
次のコードは、新しい列にデータを書き込みます。MarketingBudget
の値を、キーが Albums(1, 1)
の行は 100000
に、キーが Albums(2, 2)
の行は 500000
に設定します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
update test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
updatepg test-instance example-db
次のような出力が表示されます。
Updated albums
SQL クエリまたは読み取り呼び出しを実行して、書き込んだばかりの値を取得することもできます。
クエリを実行するコードを次に示します。
GoogleSQL
PostgreSQL
このクエリを実行するには、次のコマンドを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
querymarketingbudget test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
querymarketingbudgetpg test-instance example-db
次のように表示されます。
1 1 100000
1 2 null
2 1 null
2 2 500000
2 3 null
データの更新
読み取り / 書き込みトランザクションで DML を使用してデータを更新できます。
JDBC で読み取り / 書き込みトランザクションを実行するように AutoCommit=false
を設定します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writewithtransactionusingdml test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
writewithtransactionusingdmlpg test-instance example-db
トランザクション タグとリクエストタグ
Spanner でトランザクションとクエリのトラブルシューティングを行うには、トランザクション タグとリクエストタグを使用します。TRANSACTION_TAG
および STATEMENT_TAG
セッション変数を使用すると、JDBC でトランザクション タグとリクエストタグを設定できます。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
tags test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
tagspg test-instance example-db
読み取り専用トランザクションを使用したデータの取得
同じタイムスタンプで複数の読み取りを実行する場合について考えます。読み取り専用トランザクションは、トランザクションの commit 履歴で整合性のあるプレフィックスを監視しているため、アプリケーションは常に整合性のあるデータを取得できます。java.sql.Connection
で ReadOnly=true
と AutoCommit=false
を設定するか、SET TRANSACTION READ ONLY
SQL ステートメントを使用して、読み取り専用トランザクションを実行します。
同じ読み取り専用トランザクションでクエリと読み取りを実行する方法を次に示します。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
readonlytransaction test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
readonlytransactionpg test-instance example-db
次のような出力が表示されます。
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
2 2 Forever Hold Your Peace
1 2 Go, Go, Go
2 1 Green
2 3 Terrified
1 1 Total Junk
パーティション分割クエリと Data Boost
partitionQuery
API は、クエリをより小さな部品またはパーティションに分割し、複数のマシンを使用してパーティションを同時にフェッチします。各パーティションはパーティション トークンによって識別されます。PartitionQuery API は、データベース全体のエクスポートやスキャンなどの一括オペレーションのみを目的としているため、標準クエリ API よりもレイテンシが高くなります。
Data Boost を使用すると、プロビジョニングされた Spanner インスタンス上の既存のワークロードへの影響がほぼゼロの状態で、分析クエリとデータ エクスポートを実行できます。 Data Boost はパーティション分割クエリのみをサポートしています。
GoogleSQL
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
databoost test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
databoostpg test-instance example-db
パーティション分割クエリの実行と JDBC ドライバでの Data Boost の使用の詳細については、以下をご覧ください。
パーティション化された DML
パーティション分割されたデータ操作言語(DML)は、次のタイプの一括更新と一括削除用に設計されています。
- 定期的なクリーンアップとガベージ コレクション
- デフォルト値での新しい列のバックフィリング
PostgreSQL
次のコマンドでサンプルを実行します。
GoogleSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
pdml test-instance example-db
PostgreSQL
java -jar target/jdbc-snippets/jdbc-samples.jar \
pdmlpg test-instance example-db
AUTOCOMMIT_DML_MODE
の詳細については、以下をご覧ください。
クリーンアップ
このチュートリアルで使用したリソースについて Cloud 請求先アカウントに課金されないようにするため、作成したデータベースとインスタンスを削除します。
データベースの削除
インスタンスを削除すると、それに含まれるすべてのデータベースが自動的に削除されます。このステップでは、インスタンスを削除しないでデータベースを削除する方法を示します(インスタンスの料金は引き続き発生します)。
コマンドラインから
gcloud spanner databases delete example-db --instance=test-instance
Google Cloud コンソールの使用
Google Cloud コンソールで、[Spanner インスタンス] ページに移動します。
インスタンスをクリックします。
削除するデータベースをクリックします。
[データベースの詳細] ページで [削除] をクリックします。
データベースを削除することを確認し、[削除] をクリックします。
インスタンスの削除
インスタンスを削除すると、そのインスタンスで作成されたすべてのデータベースが自動的に削除されます。
コマンドラインから
gcloud spanner instances delete test-instance
Google Cloud コンソールの使用
Google Cloud コンソールで、[Spanner インスタンス] ページに移動します。
インスタンスをクリックします。
[削除] をクリックします。
インスタンスを削除することを確認し、[削除] をクリックします。
次のステップ
- Spanner を Spring Data JPA(GoogleSQL 言語)と統合する方法を確認する。
- Spanner を Spring Data JPA(PostgreSQL 言語)と統合する方法を確認する。
- Spanner を Hibernate ORM(GoogleSQL 言語)と統合する方法を確認する。
- Spanner を Hibernate ORM(PostgreSQL 言語)と統合する方法を確認する。
- JDBC セッション管理コマンド(GoogleSQL)の詳細を確認する。
- JDBC セッション管理コマンド(PostgreSQL)の詳細を確認する。
仮想マシン インスタンスで Spanner にアクセスする方法を確認する。
クライアント ライブラリを使用して Cloud サービスに対する認証を行うで、承認と認証情報について学習する。
Spanner のスキーマ設計のベスト プラクティスを確認する。