Java 使用安卓&;Android Studio上的谷歌应用程序引擎

Java 使用安卓&;Android Studio上的谷歌应用程序引擎,java,android,google-app-engine,objectify,Java,Android,Google App Engine,Objectify,我正在开发一个带有后端的应用程序,我决定尝试在我的后端使用谷歌应用程序引擎。因为我对谷歌应用程序引擎是个新手,所以我对它的逻辑有点困惑 基本上,我有两个模型类来表示我的对象类型。假设其中一个是用户,另一个是项目。用户有项目,一个项目可以属于多个用户。因此,用户X可以有25个项目,包括项目A,用户Y可以有完全不同的20个项目和项目A 现在,我的用户类如下所示: @Entity public class User { @Id private Long id; private Str

我正在开发一个带有后端的应用程序,我决定尝试在我的后端使用谷歌应用程序引擎。因为我对谷歌应用程序引擎是个新手,所以我对它的逻辑有点困惑

基本上,我有两个模型类来表示我的对象类型。假设其中一个是用户,另一个是项目。用户有项目,一个项目可以属于多个用户。因此,用户X可以有25个项目,包括项目A,用户Y可以有完全不同的20个项目和项目A

现在,我的用户类如下所示:

@Entity
public class User {

    @Id private Long id;
    private String name;
    private String emailAddress;
    private String photoURL;

    //All getters and setters...
}
我的Item类大致相同。我的一个问题是,我应该在哪里添加某种列表,比如在用户中添加项目列表。我应该使用哪种注释?作为结果,该注释将为我提供什么(引用、id或完整对象)

与此相关的另一个问题是,在我的endpoint类中,如何获取特定用户拥有的项目列表(或拥有特定项目的用户列表)


最后一个完全不相关的问题,我应该做些什么使
id
自动递增,还是在插入项目时不提供任何id时自动递增?

您可以在数据存储中搜索两件事:键和索引属性

class Thing {
   @Id Long id;
   @Index String property;
}
在某个时刻,您可以保存一些实体

Thing thing1 = new Thing();
thing1.property = "yes";
Thing thing2 = new Thing();
thing2.property = "no";
ofy().save().entities(thing1, thing2).now();
现在,您可以根据索引属性搜索所有实体。例如,对于所有具有
属性==“yes”
的事物

过滤器
适用于参照、键和实体实例

要找到的东西必须编入索引/

剩下的要由你决定的是你如何塑造你的关系。有多种方法。一个拥有一组项目的用户实际上是一个多对多关系。你可以这样表现

class User { List<Key<Item>> items; }
class Item { }
类用户{列表项;}
类项{}

类用户{}
类项{列表所有者;}

类用户{列表项;}
类项{列表所有者;}
甚至

class User { }
class Item { }
class Ownership { Key<Item> item; Key<User> user; }
类用户{}
类项{}
类所有权{Key item;Key user;}
每种方法在数据一致性和可搜索性/性能方面都有其起伏。在最初的示例中,搜索一个用户的所有项目是很简单的,因为您所要做的就是加载该用户,并且您拥有项目列表。另一个方向需要查询方法

因此,在搜索性能方面,您可以从项目中的所有者列表以及用户中的项目列表中获益,因为这样您根本不需要查询。最大的缺点是数据的一致性。如果您未能同时更新用户和项目,您可以拥有用户认为不同的用户拥有的项目

最后一种方法,使用显式的“所有权”实体本质上是传统的透视/连接表,它是将多个关系转换为2个一个多关系的结果。使用它会导致容易的一致性,但查询性能最差

父关系有时可能有用,但仅当父关系需要存在的实际1对多关系时


还要注意,键不是传统SQL数据库中的外键,因为它们可以在没有实体的情况下存在。因此,无论您做什么,您都必须注意一致性。

这一切都取决于您的用例和您想要的方式。您可以嵌入对象或放置对其他对象的引用:关于ID,请参阅上面的几段:@Id字段的类型可以是
Long
Long
String
。如果您使用
Long
并使用
null
id保存实体,将使用此类的标准GAE分配器为您生成一个数值。如果使用
String
或原语
long
类型,将永远不会自动生成值。“Id可能不是增量的,我猜是随机分布的。谢谢@zapl,我得到了关于@Id的答案。关于嵌入式类,我认为这不是我的解决方案。我希望能够独立地访问这两个类中的项目。我看到了像
Ref
这样的结构或像
@Load
@Parent
这样的注释,但我不确定这些是否是我要找的。是的,是你要找的机器人。键或Ref以建立关系,自动加载,以防您以任何方式加载它们,从而可以对象化请求。家长可能不会,但其用途有限。PS:我建议您阅读该文档一两次,它有点杂乱无章,但在您意想不到的地方充满了有用的信息:)我很快检查了整篇文章(将仔细阅读)。因此,在本例中,我可以添加
List items=new ArrayList()行到我的用户类。但是,我将如何搜索具有相同项目的用户?你能写一个答案吗?非常感谢你给我留下深刻印象的答案!我对仍然有问题感到很难过。当我试图返回列表时,我得到了这样的错误:
参数化类型com.googlecode.objectify.Ref不受支持。
我可以通过向方法添加
@ApiResourceProperty(ignored=AnnotationBoolean.TRUE)
注释来避免这个错误,但在这种情况下,我不能在Android代码中使用getter方法。
class User { List<Key<Item>> items; }
class Item { }
class User { }
class Item { List<Key<User>> owners; }
class User { List<Key<Item>> items; }
class Item { List<Key<User>> owners; }
class User { }
class Item { }
class Ownership { Key<Item> item; Key<User> user; }