目标
本教程将介绍如何使用 Spanner 完成以下步骤: JDBC 驱动程序:
- 创建 Spanner 实例和数据库。
- 写入、读取数据库中的数据和对数据执行 SQL 查询。
- 更新数据库架构。
- 使用读写事务更新数据。
- 向数据库添加二级索引。
- 使用索引来读取数据和对数据执行 SQL 查询。
- 使用只读事务检索数据。
费用
本教程使用 Spanner,它是 Google Cloud如需了解 Spanner 的使用费用,请参阅 定价。
准备工作
完成设置中介绍的步骤,包括创建和设置默认 Google Cloud 项目、启用结算功能、启用 Cloud Spanner API 以及设置 OAuth 2.0 来获取身份验证凭据以使用 Cloud Spanner API。
尤其要确保运行 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 数据库使用的资源。创建实例时,请选择一个实例配置(决定数据的存储位置),同时选择要使用的节点数(决定实例中服务资源和存储资源的数量)。
执行以下命令,在该区域中创建 Spanner 实例
us-central1
,具有 1 个节点:
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.
浏览示例文件
示例代码库包含一个示例,展示了如何使用 Spanner
pom.xml
会将 Spanner JDBC 驱动程序添加到
项目依赖项,并将汇编插件配置为
包含本教程中定义的 Java 类的可执行 JAR 文件。
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]
GoogleSQL
PostgreSQL
下一步是将数据写入数据库。
创建 JDBC 连接
您必须先创建一个Connection
,然后才能执行读写操作。您的所有互动
必须通过 Connection
验证。数据库名称和
属性在 JDBC 连接网址和
已设置 java.util.Properties
。
GoogleSQL
PostgreSQL
有关受支持属性的完整列表,请参阅 连接网址属性。
每个 Connection
都使用资源,因此最好关闭
使用连接池
在整个应用中重复使用连接。
如需了解详情,请参阅 Connection
Javadoc
参考。
将 JDBC 驱动程序连接到模拟器
您可以将 JDBC 驱动程序连接到 Spanner 模拟器,具体如下: 两种方法:
- 设置
SPANNER_EMULATOR_HOST
环境变量:这会指示 用于连接到模拟器的 JDBC 驱动程序。Spanner JDBC 连接网址中的实例和数据库必须已经存在于 模拟器。 - 将
autoConfigEmulator=true
添加到连接网址中:这会指示 JDBC 驱动程序用于连接到模拟器,并自动创建 JDBC 连接网址中的 Spanner 实例和数据库 如果它们不存在,则会发生此错误
此示例展示了如何使用 autoConfigEmulator=true
连接网址
选项。
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()
和
执行多个 DML 语句的 PreparedStatement#executeBatch()
方法
一个批次。
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 数据库中的不同行和表。
newInsertBuilder()
Mutation
类中的方法构造了一个 INSERT
变更,该变更会在
新行。如果该行已经存在,则写入失败。或者
您可以使用newInsertOrUpdateBuilder
用于构建 INSERT_OR_UPDATE
变更(用于更新列值)的方法
如果该行已经存在,则会发生此错误。
write()
CloudSpannerJdbcConnection
接口中的方法写入变更。全部
变更以原子方式应用。
您可以从 Spanner 解封 CloudSpannerJdbcConnection
接口
JDBC Connection
。
此代码演示了如何使用变更写入数据:
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 驱动程序。
在命令行中
执行以下 SQL 语句,读取 Albums
表中所有列的值:
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 查询:createStatement()
Connection
接口中的方法:使用该方法创建新的语句对象 运行 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 驱动程序
使用execute(String)
方法中 java.sql.Statement
修改架构:
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 批次
建议一次性执行多个架构修改。使用
addBatch(String)
java.sql.Statement
方法将多个 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.
将数据写入新列
以下代码可将数据写入新列。对于 Albums(1, 1)
键控的行,该代码会将 MarketingBudget
设置为 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 来更新数据。
设置 AutoCommit=false
以在 JDBC 中执行读写事务。
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
的 JDBC 中的事务标记和请求标记
和 STATEMENT_TAG
会话变量。
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
使用只读事务检索数据
假设您要在同一时间戳执行多个读取操作。只读事务会遵从一致的事务提交历史记录前缀,因此您的应用始终可获得一致的数据。
在 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 的延迟时间比标准
Query API,因为它仅适用于批量操作,例如导出或
扫描整个数据库。
数据提升 执行分析查询和数据导出,费用接近于零 对已预配 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
如需详细了解如何运行分区查询以及如何搭配使用 Data Boost 和 JDBC 驱动程序,请参阅:
分区 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
,请参阅:
清理
为避免因本教程中使用的资源导致您的 Google 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 架构设计最佳实践。