我有三个实体,分别是人,狗,请客。 Treat实体具有键Key<Dog>,而Dog实体具有键Key<Human>。当我查询Treat时,我需要一个包含Dog实际实体的响应,而Dog实体必须包含Human:的实际实体,而不是键。我怎么做?

更新

所以我希望能够执行以下两个查询


getAllTreats()应该返回所有零食的列表,通过每种零食,我可以访问Dog数据,然后通过上述Dog数据找到Human数据。
给定一个Treat ID,我想使用它的Dog数据和上述Dog的Human数据来检索该Treat。


代码:(我给pgiecek +1是因为他提到了@Parent表示法。但是问题仍然存在,至少对于单用TreatId而言)

@Entity
public class Human {
    @Id
    private Long id;
    private String name;
}

@Entity
public class Dog {
    @Id
    private Long id;
    private String name;
    @Load
    @Parent
    private Ref<Human> human;
}


@Entity
public class Treat {
    @Id
    private Long id;
    private String name;
    @Load
    @Parent
    private Ref<Dog> dog;
}

最佳答案

尝试与Ref<?>注释一起使用@Load而不是Key<?>Ref<?>的作用与Key<?>相似,但是允许您直接访问实际的实体对象。此外,使用@Load批注可以更有效地加载关联的实体对象。

在这里,您可以找到有关Ref<?>@Load的更多详细信息。

更新资料

查询1

List<Treat> treats = ofy.load().type(Treat.class).list()


对于每个Treat对象,您必须访问Dog引用并通过Ref<?>.get()方法手动获取。 Human也是如此。但是,可以对父字段使用@Load批注。

查询2

如果您只有Treat的ID,则不可能加载该实体,因为所有祖先路径实际上是该实体的键。


标识实体的完整密钥由以下序列组成:
种类标识符对,指定其祖先路径并终止
与实体本身的那些。


在您的情况下,Treat的密钥如下所示。

Key = [Human:ID, Dog:ID, Treat:ID]


为了检索具体的Treat实例,您需要知道其ID以及所有父级(在您的情况下为DogHuman实例/ ID)或其密钥。查看Key<?>.toWebSafeString()Key<?>.create(String)(或Key<?>.valueOf(String))方法,这些方法可以帮助您将密钥序列化为String并在以后还原。

Treat treat = ... // create a new instance along with its parents

String webSafeKey = Key.create(treat).toWebSafeString();

// do whatever you need

Key<Treat> treatKey = Key.<Treat>create(webSafeKey);

Treat loaded = ofy.load().key(treatKey).now();

09-30 15:36
查看更多