我有一个引用用户对象的帐户对象。
@Cache
@Entity
public final class Account {
@Id Long id;
@Index private Ref<User> user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user.get();
}
public void setUser(User user) {
this.user = Ref.create(user);
}
}
我按照此处的建议隐藏了参考:http://code.google.com/p/objectify-appengine/wiki/Entities http://code.google.com/p/objectify-appengine/wiki/Entities- 请注意参考号确实not有@Load注释。
当我从 Android 客户端调用我的 Google Cloud Endpoint 时,即使未指定 @Load,Objectify 也会通过嵌入式用户传递帐户对象。
@ApiMethod(name = "account.get")
public Account getAccount(
@Named("id") final Long id
) {
return ofy().load().type(Account.class).id(id).now();
}
当我直接使用 Apis Explorer 查询帐户时,我还得到了嵌入用户的帐户:
200 OK
{
"id": "5079604133888000",
"user": { "id": "5723348596162560",
"version": "1402003195251",
"firstName": "Karl" },
"kind": "api#accountItem",
"etag": "\"30khohwUBSGWr00rYOZuF9f4BTE/Q31EvnQCQ6E9c5YXKEZHNsD_mlQ\""}
这提出了三个问题:
- Appengine 是否始终返回本机嵌入的 Refs,而 Objectify 是否始终传递它已经知道的对象?
- @Load 到底是做什么用的?有没有办法控制这种行为?加载组?
- 我错过了什么吗?为什么不遵守@Load?
在您的示例代码中,您没有指定@Load
这意味着加载帐户不会获取User
。然而,你的@ApiMethod
正在将帐户序列化回客户端,因此user
属性被访问,因此发出单独的提取来加载用户对象。这就是为什么您在调用该方法时获取用户信息的原因。
未指定@Load
并不意味着您不会得到User
后退。这意味着您不会检索User
除非你稍后特别要求。
重做是这样的:
- 我是一个参考,所以默认情况下我不会获取数据。
- 如果你问我,那么我会先加载数据,然后回答你。
- 哦,如果你告诉我
@Load
我自己,然后我将首先获取数据并为您准备好。
所以这在你的代码中工作得很好......但是你的@ApiMethod
正在序列化你的Account
对象返回给客户。序列化过程将遍历您的每个属性Account
对象,包括user
财产。此时,Ref<User>
正在被访问,因此将从数据存储中获取数据,然后返回给客户端。
这使得你的代码效率非常低,因为Account
加载对象时无需User
信息,但随后您始终可以访问User
稍后(在序列化期间),发出单独的获取。配料gets
从数据存储中发出比单独发出更有效gets
.
对于您的情况,您可以执行以下两种操作之一:
- Add
@Load
到用户属性,所以Account
有效地获取对象。
- 做你的
@ApiMethod
返回不同的Account
没有对象的user
属性(从而避免在不需要时获取用户)。
上面的选项 2 非常有用,因为您可以从客户端看到的内容中抽象出内部数据存储结构。你会发现自己经常使用这种说法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)