本指南演示了如何从 App Engine Datastore 迁移到 Datastore 模式 Firestore(也称为 Datastore)。
Datastore 模式 Firestore 与 App Engine Datastore 类似,两者都引用同一底层 Datastore 服务。虽然 App Engine Datastore 只能通过 App Engine 旧版捆绑服务进行访问,但 Datastore 模式 Firestore 是一种独立 Google Cloud 产品,可通过 Cloud 客户端库访问它。
Datastore 模式 Firestore 还提供了一个免费层级,可让您管理可扩缩性极强的 NoSQL 文档数据库,并在将来灵活地迁移到 Cloud Run 或其他 Google Cloud 应用托管平台。
须知事项
查看不同的 Firestore 数据库模式,以确保了解适用于您的应用的最佳使用场景。请注意,本指南介绍了如何迁移到 Datastore 模式。
查看并了解 Datastore 模式 Firestore 的价格和配额。
Datastore 模式 Firestore 提供具有每日上限的免费用量,另提供付费账号,拥有无限存储、读取和写入操作次数。App Engine 应用被停用后,不会产生任何流量产生费用,但如果超出免费配额上限,则 Datastore 使用量可能会计费。
在包含您的应用的项目中启用以下 API:
- 用于存储和管理您的构建工件的 Artifact Registry API
- Cloud Build API,用于持续构建、测试和部署应用。
Cloud Datastore API,用于从 App Engine 捆绑数据存储区迁移到 Datastore 模式 Firestore。
具有运行 Java 8 或 11 且已连接到 App Engine Datastore 服务的现有 App Engine 应用。
过程概览
概括来讲,从 App Engine Datastore 迁移到 Datastore 模式 Firestore 的过程包括以下步骤:
更新配置文件
更新配置文件以使用 Datastore 模式客户端库。
更新基准 Java 应用的 pom.xml
文件:
移除 App Engine SDK
appengine-api-1.0-sdk
导入,如以下所示:<dependency> <groupId>com.google.appengine</groupId> <artifactId>appengine-api-1.0-sdk</artifactId> <version>2.0.4</version> </dependency>
添加
Datastore
客户端,如以下所示:<dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-datastore</artifactId> <!-- Use latest version --> <version>2.2.9</version> </dependency>
更新 Java 应用
更新导入语句
通过更新导入和初始化行来修改应用文件:
移除 App Engine Datastore
com.google.appengine.api.datastore.*
的以下 App Engine 导入语句:import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.DatastoreServiceFactory; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.FetchOptions; import com.google.appengine.api.datastore.Query;
添加以下 Datastore 模式 Firestore
com.google.cloud.datastore.*
导入:import com.google.cloud.Timestamp; import com.google.cloud.datastore.Datastore; import com.google.cloud.datastore.DatastoreOptions; import com.google.cloud.datastore.Entity; import com.google.cloud.datastore.Key; import com.google.cloud.datastore.FullEntity; import com.google.cloud.datastore.KeyFactory; import com.google.cloud.datastore.Query; import com.google.cloud.datastore.QueryResults; import com.google.cloud.datastore.StructuredQuery;
修改应用访问 Datastore 服务的方式
Datastore 模式 Firestore 使用 Datastore
类,而不是 DatastoreService
。如需修改应用访问 Datastore 服务的方式,请执行以下操作:
找到使用
DatastoreServiceFactory.getDatastoreService()
方法的行,如以下所示:// Initialize a client DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
将
DatastoreServiceFactory.getDatastoreService()
替换为DatastoreOptions.getDefaultInstance().getService()
方法,如以下所示:// Initialize a client Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
获取 Datastore 生成的键
初始化客户端后,通过创建相应 Kind
的新 KeyFactory
来获取键,然后让 Datastore 为您生成一个键。如需获取 Datastore 生成的键,请执行以下操作:
创建
newKeyFactory
。调用
setKind()
方法以确定用于查询分类的实体的kind
。附加
newKey()
方法以生成 Datastore 键://Prepare a new entity String kind = "visit"; Key key = datastore.allocateId(datastore.newKeyFactory().setKind(kind).newKey());
修改实体创建
获取 Datastore 键后,使用以下方法创建实体:
使用
Entity.newBuilder
并传递 Datastore 生成的键。找到使用
Entity
构造函数调用的行,如以下所示:Entity visit = new Entity(kind);
将
Entity
构造函数调用替换为Entity.newBuilder
构造函数调用,如以下所示:Entity visit = Entity.newBuilder(key);
使用
set
方法设置实体的属性。第一个参数是预期属性,第二个参数是值。 对于
timestamp
属性,该值为Timestamp
,而不是Instant.toString()
。找到使用
setProperty
方法的行,如以下所示:visit.setProperty("user_ip", userIp); visit.setProperty("timestamp", Instant.now().toString());
将
setProperty
方法替换为set
方法,如以下所示:Entity visit = Entity.newBuilder(key).set("user_ip", userIp).set("timestamp", Timestamp.now()).build();
提交事务
Datastore 模式 Firestore 客户端库使用 add()
方法来提交事务。如需提交事务,请运行以下命令:
查找使用
put()
方法的行,如以下所示:// Save the entity datastore.put(visit);
将
put()
方法替换为add()
方法,如以下所示:// Save the entity datastore.add(visit);
查询结果
查询会检索满足一组指定条件的 entities
。您可以使用以下方法显示结果:
查询使用带有 kind
变量的构建器模式方法。在获取 Datastore 生成的键步骤中,kind
变量设置为 Visit
。
如需检索前 10 个结果,请执行以下操作:
查找使用
addSort()
方法的行,如以下所示:// Retrieve the last 10 visits from the datastore, ordered by timestamp. Query query = new Query(kind).addSort("timestamp", Query.SortDirection.DESCENDING); List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));
将
addSort()
方法替换为setOrderBy()
方法,并附加setLimit()
方法,如以下所示:// Retrieve the last 10 visits from the datastore, ordered by timestamp. Query<Entity> query = Query.newEntityQueryBuilder() .setKind(kind) .setOrderBy(StructuredQuery.OrderBy.desc("timestamp")) .setLimit(10) .build();
查询准备就绪后,使用
datastore.run()
执行该代码,然后将结果收集到QueryResultsEntity
集合中。生成的
QueryResults
对象是具有hasNext()
函数的迭代器。检查结果集是否有要处理的
next
对象,而不是循环遍历结果列表。例如:QueryResults<Entity> results = datastore.run(query); resp.setContentType("text/plain"); PrintWriter out = resp.getWriter(); out.print("Last 10 visits:\n"); while (results.hasNext()) { Entity entity = results.next(); out.format( "Time: %s Addr: %s\n", entity.getTimestamp("timestamp"), entity.getString("user_ip")); }
示例
如需查看将 Java 8 应用迁移到 Datastore 模式 Firestore 的示例,请比较 Java 8 版 App Engine Datastore 代码示例和 Datastore 模式 Firestore 代码示例。
后续步骤
- 了解如何使用 Datastore 模式 Firestore。
- 如需了解详情,请参阅 Datastore 模式 Firestore 文档。
- 了解如何从 Java 版旧版捆绑服务迁出。