密钥与ID /名称?

时间:2015-12-08 07:50:19

标签: google-app-engine google-cloud-datastore

我不想为我的实体创建自动生成的密钥,因此我指定了自己的密钥:

Entity employee = Entity.newBuilder().setKey(makeKey("Employee", "bobby"))
        .addProperty(makeProperty("fname", makeValue("fname").setIndexed(false)))
        .addProperty(makeProperty("lname", makeValue("lname").setIndexed(false)))    
        .build();

CommitRequest request = CommitRequest.newBuilder()
    .setMode(CommitRequest.Mode.NON_TRANSACTIONAL)
    .setMutation(Mutation.newBuilder().addInsert(employee))
    .build();
datastore.commit(request);

当我检查实体的外观时,它看起来像这样:

enter image description here

如果我指定了自己的密钥(bobby),为什么会生成这个自动生成的密钥?似乎鲍比也被创造了,但现在我有了鲍比和这个自动生成的钥匙。密钥和ID /名称之间有什么区别?

3 个答案:

答案 0 :(得分:4)

您无法指定自己的密钥,密钥实际上包含数据存储区操作所需的信息。 the documentation中的这条说明为您提供了一个想法:

  

注意:URL安全字符串看起来很神秘,但它没有加密!它   可以很容易地解码以恢复原始实体的种类和   标识符

key = Key(urlsafe=url_string)
kind_string = key.kind()
ident = key.id()
     

如果您使用此类网址安全密钥,请勿使用电子邮件等敏感数据   地址作为实体标识符。 (可能的解决方案是使用   敏感数据的MD5哈希值作为标识符。这停止了​​第三   可以看到加密密钥的各方使用它们来收获   电子邮件地址,但它并不能独立阻止它们   生成他们自己的已知电子邮件地址的哈希并使用它   检查数据存储区中是否存在该地址。)

you can specify是密钥的ID部分,无论是数字还是字符串:

  

密钥是一系列种类ID对。你想确保每个实体   有一个在其应用程序和命名空间中唯一的键。一个   应用程序可以创建实体而无需指定ID;该   数据存储区自动生成数字ID。如果申请   选择一些ID"手工"并且它们是数字,应用程序允许   数据存储可以自动生成一些ID,数据存储可能会生成   选择应用程序已使用的一些ID。为了避免,这个,   申请应该"保留"它将用于的数字范围   选择ID(或使用字符串ID完全避免此问题)。

答案 1 :(得分:2)

这是您的密钥的网址安全版,适合在链接中使用。使用KeyFactory.stringToKey将其转换为实际密钥,您会看到它包含您的字符串名称。

答案 2 :(得分:1)

使用bobby创建的内容是实体名称为Dec 08, 2015 1:50:40 PM org.apache.catalina.startup.SetAllPropertiesRule begin WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxSpareThreads' to '50' did not find a matching property. Dec 08, 2015 1:50:40 PM org.apache.catalina.startup.SetAllPropertiesRule begin WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxSpareThreads' to '50' did not find a matching property. Dec 08, 2015 1:50:40 PM org.apache.tomcat.util.digester.Digester endElement WARNING: No rules found matching 'Server/Service/Realm'. Dec 08, 2015 1:50:40 PM org.apache.tomcat.util.digester.Digester endElement WARNING: No rules found matching 'Server/Service/Host'. Dec 08, 2015 1:50:40 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-nio-8491"] Dec 08, 2015 1:50:40 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector INFO: Using a shared selector for servlet write/read Dec 08, 2015 1:50:40 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-nio-8492"] Dec 08, 2015 1:50:40 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector INFO: Using a shared selector for servlet write/read Dec 08, 2015 1:50:40 PM org.apache.catalina.startup.Catalina load INFO: Initialization processed in 1482 ms Dec 08, 2015 1:50:41 PM org.apache.catalina.core.StandardService startInternal INFO: Starting service Nightfire-webapps Dec 08, 2015 1:50:41 PM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet Engine: Apache Tomcat/8.0.24 Dec 08, 2015 1:50:41 PM org.apache.catalina.mapper.MapperListener findDefaultHost WARNING: Unknown default host [localhost] for service [StandardService[Nightfire-webapps]] Dec 08, 2015 1:50:41 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-8491"] Dec 08, 2015 1:50:41 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-8492"] Dec 08, 2015 1:50:41 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 173 ms 且名称为private void createJsonArray() { billType = (invEstSwitch.isChecked() ? textViewEstimate : textViewInvoice) .getText().toString(); String invNumber = textViewInvNo.getText().toString(); String bcode = barCode.getText().toString(); String description = itemDesc.getText().toString(); String wt = weightLine.getText().toString(); String rateAmt = rateAmount.getText().toString(); String making = makingAmount.getText().toString(); String netr = netRate.getText().toString(); String iTotal = itemtotal.getText().toString(); String vatAmt = textViewVat.getText().toString(); String sumAmt = textViewSum.getText().toString(); String crtDate = textViewCurrentDate.getText().toString(); try { jsonObject.put("custInfo", custSelected.toString()); jsonObject.put("invoiceNo", invNumber); jsonObject.put("barcode", bcode); jsonObject.put("description", description); jsonObject.put("weight", wt); jsonObject.put("rate", rateAmt); jsonObject.put("makingAmt", making); jsonObject.put("net_rate", netr); jsonObject.put("itemTotal", iTotal); jsonObject.put("vat", vatAmt); jsonObject.put("sum_total", sumAmt); jsonObject.put("bill_type", billType); jsonObject.put("date", crtDate); } catch (JSONException e) { e.printStackTrace(); } try { itemSelectedJson.put(index, jsonObject); index++; } catch (JSONException e) { e.printStackTrace(); } } 的实体的密钥。您在数据存储区查看器中看到的Key就是这样的表示。

一般来说,密钥总是由

组成
  • 可选父键(具有实体类型和名称/ ID)
  • 实体类型
  • 实体名称/ ID

也许这里的某个人可以告诉你如何将密钥解码到其组件中,但是确保你正在做的一切正确并且行为符合预期。