2015-11-13 37 views
1

我正在開發帶有後端的應用程序,並決定嘗試將Google App Engine用於我的後端。由於我在Google App Engine上真的很新,所以我對這個邏輯有點困惑。在Android Studio上使用Android和Google App Engine

基本上,我有幾個模型類來表示我的對象類型。可以說,其中一個是用戶,另一個是項目。用戶具有項目並且項目可以屬於多個用戶。因此,用戶X可以有25個項目,包括項目A,和用戶Y可以有完全不同的20個項目,也是項目A.

現在我的User類是這樣的:

@Entity 
public class User { 

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

    //All getters and setters... 
} 

我的Item類幾乎相同。我的一個問題是,我應該在哪裏添加某種列表,如項目列表中的用戶列表。我應該使用哪個註釋?那個註釋將爲我提供什麼結果(一個引用,一個id或一個完整的對象)?

與此相關的另一個問題是,在我的端點類中,如何獲取特定用戶擁有的項目列表(或擁有特定項目的用戶列表)?

最後一個完全不相關的問題,我應該做什麼使id自動遞增,或者如果我在插入項目時不提供任何ID,它會自動?

+1

這一切都取決於你的用例和你想要它。您可以嵌入對象或將對其他對象的引用:https://github.com/objectify/objectify/wiki/Entities#embedded-classes,關於id幾個段落:*「@Id字段的類型可以是Long '''''''''','''''''如果您使用'Long'並保存一個帶有'null' id的實體,那麼使用標準的GAE分配器就會爲您生成一個數值,如果您使用'String ''或原始'長'類型,值將永遠不會自動生成。「* Ids可能不是遞增的,我猜想是隨機分佈的。 – zapl

+0

謝謝@zapl,我得到了關於@Id的答案。關於嵌入式類,我不認爲這是我的解決方案。我希望能夠獨立訪問這兩個課程中的項目。我看到像'Ref '這樣的結構或'@ Load'或'@ Parent'這樣的註釋,但我不確定這些是我正在尋找的。 – iamkaan

+0

是的,[這些](https://github.com/objectify/objectify/wiki/Entities#relationships)*是您正在尋找的機器人。關鍵或參考建立關係,自動'@負載'的情況下,你會加載它們,因此objectify可以[批次](https://github.com/objectify/objectify/wiki/BestPractices#use-batch-gets-instead查詢)請求。父母可能不是,用途是有限的。 PS:會建議閱讀一次或兩次文檔,這是有點無組織,但在你不會期望的地方充滿有用的信息:) – zapl

回答

2

您可以在數據存儲中搜索2件事:密鑰和索引屬性。

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(); 

現在,你可以搜索基於其索引屬性的所有實體。例如。對於所有與property == "yes"的事情。

List<Thing> things = ofy().load().type(Thing.class).filter("property", "yes").list(); 

準確地返回thing1

與屬性列表一樣。它可以與其他屬性的引用/鍵列表一起使用。

class User { 
    @Id Long id; 
    @Index List<Key<Item>> items; 
} 

class Item { 
    @Id 
    Long id; 
} 

List<User> searchUsersWithItem(long itemId) { 
    Key<Item> itemKey = Key.create(Item.class, itemId); 
    return ofy().load().type(User.class).filter("items", itemKey).list(); 
} 
List<User> searchUsersWithItem(Item item) { 
    return ofy().load().type(User.class).filter("items", item).list(); 
} 
// just loads all the referenced items in the owner 
List<Item> searchItemsWithOwner(User owner) { 
    return new ArrayList<Item>(ofy().load().<Item>values(owner.items).values()); 
} 

filter適用於refs,keys和entitiy實例。

要找到的東西必須是索引你來決定,剩下的是什麼https://cloud.google.com/datastore/docs/concepts/indexes/https://github.com/objectify/objectify/wiki/Queries

是你如何建模的關係。有多種方式。擁有一組可由用戶組擁有的項目的用戶實際上是多對多關係。你可以代表它像

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; } 

每一種方法都有它的漲跌相對於數據的一致性和可搜索性/ perfor曼斯。在最初的例子中,搜索用戶的所有項目並不重要,因爲您只需加載該用戶並且擁有項目列表。另一個方向需要查詢方法。

因此,就搜索性能而言,您可以從項目中的所有者列表以及用戶項目列表中受益,因爲這樣您根本不需要查詢。數據一致性的缺點在於大的缺點。如果您無法同時更新用戶和物品,則可以讓相信屬於用戶認爲不同的用戶所擁有的物品。

使用明確的「所有權」實體的最後一種方法本質上是傳統的樞軸/聯結表https://en.wikipedia.org/wiki/Many-to-many_%28data_model%29,它是將多對多關係轉換爲2一對多關係的結果。使用它會導致一致性較好,但是查詢性能最差。

父關係有時可能是有用的,但只有在父母需要存在的實際1對多關係時纔有用。

另請注意,鍵不像傳統SQL數據庫中的外鍵,因爲它們可以在沒有實體的情況下存在。所以無論你做什麼,你都必須注意一致性。

+0

非常感謝你給出了令人印象深刻的答案!我仍然有問題,我感到不好。當我嘗試返回列表,我得到這樣的錯誤:'參數化類型com.googlecode.objectify.Ref <>不支持.'我能夠通過添加@ApiResourceProperty(ignored = AnnotationBoolean。TRUE)'註釋,但在這種情況下,我無法在Android代碼中使用getter方法。 – iamkaan

相關問題