创建和使用实体键

Datastore 中的每个实体都有一个唯一标识它的键。键由以下部分组成:

  • 实体的命名空间,可实现多租户
  • 实体所属的种类,用于对实体进行分类以执行 Datastore 查询
  • (可选)祖先路径,用于在 Datastore 层次结构中确定实体的位置。
  • 具体实体的标识符,可以是下面任意一种

    • 键名字符串
    • 整数数字 ID

标识符是实体键的一部分,因此与实体永久关联且不可更改。您可以通过下述两种方式分配标识符:

  • 为实体指定自己的“键名”字符串。
  • 让 Datastore 自动为实体分配一个整数数字 ID。

指定实体的键名

要为实体分配键名,请在创建该实体时将名称作为第二个参数提供给构造函数:

Entity employee = new Entity("Employee", "asalieri");

如需让 Datastore 自动分配数字 ID,请省略此参数:

Entity employee = new Entity("Employee");

分配标识符

您可以通过两项不同的自动 ID 政策配置 Datastore,使其生成自动 ID:

  • default 政策会生成大致均匀分布的未使用 ID 的随机序列。每个 ID 最多可包含 16 位十进制数字。
  • legacy 政策会创建一系列不连续的较小整数 ID。

如果希望向用户显示实体 ID 和/或按照顺序显示实体 ID,最好是使用手动分配。

使用祖先实体路径

Cloud Datastore 中的实体形成一个与文件系统目录结构类似的层级结构空间。创建实体时,您可选择指定另一实体作为其父实体;新实体是父实体的子实体(请注意,与文件系统不同,无需实际存在父实体)。没有父实体的实体是根实体。实体与其父实体之间的关联是永久的,实体创建后就无法更改。Cloud Datastore 绝不向父实体相同的两个实体分配同一数字 ID,也不分配给两个根实体(即没有父实体的实体)。

实体的父实体、父实体的父实体和以此类推得出的实体都是该实体的祖先实体;而实体的子实体和子实体的子实体等都是它的后代实体。根实体及其所有后代实体都属于同一个实体组。实体序列从根实体开始,接着从父实体到子实体,再指向给定的实体,这就构成了实体的祖先路径。识别实体的完整键由一系列种类/标识符对构成,它们指定实体的祖先路径并以实体自身的种类/标识符对终止。

[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]

对于根实体,祖先路径为空,且键仅由实体自身的种类和标识符组成:

[Person:GreatGrandpa]

此概念如下图所示:

显示实体组中的根实体与子实体的关系

如需指定实体的父实体,请在创建子实体时将父实体的键作为参数提供给 Entity() 构造函数。您可以通过调用父实体的 getKey() 方法来获取键:

Entity employee = new Entity("Employee");
datastore.put(employee);

Entity address = new Entity("Address", employee.getKey());
datastore.put(address);

如果新实体也有键名,请将键名作为第二个参数提供给 Entity() 构造函数,并提供父实体的键作为第三个参数:

Entity address = new Entity("Address", "addr1", employee.getKey());

生成键

应用可以使用 KeyFactory 类,基于已知组件(如实体的种类和标识符)为实体创建 Key 对象。对于没有父实体的实体,可以将种类和标识符(键名字符串或数字 ID)传递给静态方法 KeyFactory.createKey() 以创建键。以下示例为种类为 Person 且键名为 "GreatGrandpa" 或数字 ID 为 74219 的实体创建键:

Key k1 = KeyFactory.createKey("Person", "GreatGrandpa");
Key k2 = KeyFactory.createKey("Person", 74219);

如果键包含路径组件,您可以使用辅助类 KeyFactory.Builder 来构建路径。该类的 addChild 方法会在路径中添加单个实体,并返回构建器本身,因此您可以将一系列调用连在一起(从根实体开始),为路径一次构建一个实体。构建完整路径后,请调用 getKey 以检索生成的键:

Key k =
    new KeyFactory.Builder("Person", "GreatGrandpa")
        .addChild("Person", "Grandpa")
        .addChild("Person", "Dad")
        .addChild("Person", "Me")
        .getKey();

KeyFactory 类还包括静态方法 keyToStringstringToKey,用于在键与其字符串表示法之间切换:

String personKeyStr = KeyFactory.keyToString(k);

// Some time later (for example, after using personKeyStr in a link).
Key personKey = KeyFactory.stringToKey(personKeyStr);
Entity person = datastore.get(personKey);

键的字符串表示法可在 Web 环境中安全使用:该表示法不包含 HTML 或网址中的特殊字符。