在 Google App Engine (GAE) 上,如何搜索“密钥/ID”字段?
我有这段代码(Java,GAE):
// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);
// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200
它会生成此错误:
javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query. Are you certain that a field named __key__ exists on your object?
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
at myapp.Player.validPlayerWithKey(Player.java:200)
// [etc., snip]
但我不确定它想要什么。我正在尝试搜索 JDO id 字段,我认为我读到的该字段具有特殊名称 __key__
, 文档中。
我已经尝试过两者
query.setFilter("__key__ == keyParam");
并
query.setFilter("ID == keyParam");
得到相同的结果。那么,我做错了什么?或者,更重要的是,我该如何正确地做到这一点?
谢谢!
编辑:为了完整起见,这里是最终的工作代码(基于戈登的答案,我已接受该答案是正确的):
Player result = null;
if (playerKey == null)
{
log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
try {
result = (Player) pm.getObjectById(Player.class, playerKey);
} catch (javax.jdo.JDOObjectNotFoundException notFound) {
// Player not found; we will return null.
result = null;
}
pm.close();
}
return result;
I've got this code (Java, GAE):
// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);
// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200
which generates this error:
javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query. Are you certain that a field named __key__ exists on your object?
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
at myapp.Player.validPlayerWithKey(Player.java:200)
// [etc., snip]
But I'm not sure what it wants. I'm trying to search on the JDO id field, which I I thought I read had the special name __key__
, in the documentation.
I've tried it with both
query.setFilter("__key__ == keyParam");
and
query.setFilter("ID == keyParam");
with the same results. So, what am I doing wrong? Or, more importantly, how do I do it correctly?
Thanks!
Edit: For completeness's sake, here is the final, working code (based on Gordon's answer, which I have accepted as correct):
Player result = null;
if (playerKey == null)
{
log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
try {
result = (Player) pm.getObjectById(Player.class, playerKey);
} catch (javax.jdo.JDOObjectNotFoundException notFound) {
// Player not found; we will return null.
result = null;
}
pm.close();
}
return result;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的目标是通过键获取对象,那么您应该使用 PersistenceManager 的 getObjectByID() 方法。如需了解更多详情,请访问此处。
顺便说一句,尝试构建一个查询来通过其键来获取某些内容是您不需要做的事情。虽然这就是您使用 SQL 数据库的方式,但 Google 数据存储的做法有所不同,这是其中一种情况,Google App Engine 可以让您直接获得您想要的内容,而不是经历构建查询的麻烦。毕竟,数据库中应该只有一个具有特定键的实体,因此在这种情况下,GQL 查询的其余部分中没有您需要的任何内容,因此可以将其全部跳过以提高效率。
If your objective is to get an object by key, then you should use the PersistenceManager's getObjectByID() method. More details here.
As an aside, trying to construct a query to get something by it's key is something you shouldn't need to do. Although this is how you would work with an SQL database, the Google Data Store does things differently, and this is one of those cases where rather than go through the trouble of constructing a query, Google App Engine lets you get what you want directly. After all, you should only have one entity in the database with a particular key, so there's nothing in the rest of the machinery of a GQL query that you need in this case, hence it can all be skipped for efficiency.
我建议您使用 JPA ( http://code.google .com/appengine/docs/java/datastore/usingjpa.html )来访问 GAE 中的数据,它有一个非常重要的优势,即您可以使用广为人知且有文档记录的 JPA 标准(及其 JPAQL 查询语言)以可移植的方式做这类事情(如果您坚持 JPA 标准,您的代码将适用于 GAE、Hibernate 或 EclipseLink,无需修改)
I would recommend you to use the JPA ( http://code.google.com/appengine/docs/java/datastore/usingjpa.html ) to access your data in GAE, it has the very important advantage that you can use the widely known and documented JPA standard (and its JPAQL querying language) to do this kind of things, in portable way (if you stick to the JPA standard, your code will work for GAE, for Hibernate or with EclipseLink without modification)