2015-11-13 3 views
1

Я разрабатываю приложение с бэкэнд, и я решил попробовать использовать Google App Engine для моего бэкэнд. Поскольку я действительно новичок в Google App Engine, я немного путаюсь с логикой.Использование Android и Google App Engine на Android Studio

В принципе, у меня есть пара классов моделей для представления моих типов объектов. Допустим, что один из них - Пользователь, а другой - Item. Пользователи имеют элементы, и элемент может принадлежать более чем одному пользователю. Таким образом, пользователь X может иметь 25 пунктов, включая Пункт А, и пользователь Y может иметь совершенно разные 20 пунктов, а также Пункт А.

Сейчас мой класс пользователя выглядит следующим образом:

@Entity 
public class User { 

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

    //All getters and setters... 
} 

И мой класс Item примерно такой же. Один из моих вопросов: где я должен добавить какой-то список, например список элементов в User. И какую аннотацию я должен использовать? Что даст мне эта аннотация (ссылка, идентификатор или полный объект)?

Другой вопрос, связанный с этим, в моем классе конечных точек, как я могу получить список элементов, которые есть у конкретного пользователя (или список пользователей, которым принадлежит определенный элемент)?

Один последний совершенно не связанный вопрос, должен ли я сделать что-нибудь, чтобы сделать id auto increment или будет автоматически, если я не укажу идентификатор во время ввода элемента?

+1

Все зависит от вашего удобства и того, как вы хотите. Вы можете внедрять объекты или помещать ссылки на другие объекты: https://github.com/objectify/objectify/wiki/Entities#embedded-classes и относительно идентификаторов в несколько абзацев выше: * «Поле @Id может иметь тип« Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'или примитивный' long' тип, значения никогда не будут автогенерированы. * Идентификаторы, вероятно, не являются инкрементальными, я предполагаю, что они распределены случайным образом. – zapl

+0

Спасибо @zapl, я получил свой ответ о @Id. Что касается встроенных классов, я не думаю, что это мое решение. Я хочу иметь возможность самостоятельно получать предметы из обоих классов. Я видел такие структуры, как 'Ref ' или аннотации, такие как '@ Load' или' @ Parent', но я не уверен, что это то, что я ищу. – iamkaan

+0

Да, [эти] (https://github.com/objectify/objectify/wiki/Entities#relationships) * являются * дроидами, которые вы ищете. Key или Ref для построения отношений, Auto '@ Load'ed, если вы загрузили их так или иначе, чтобы объективировать can [batch] (https://github.com/objectify/objectify/wiki/BestPractices#use-batch-gets-instead запросов). Родитель, вероятно, нет, использование для этого ограничено. PS: рекомендовал бы прочитать эту документацию один или два раза, это немного неорганизованный, но полный полезной информации в местах, которые вы не ожидали :) – zapl

ответ

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

Каждый подход это взлеты и падения по отношению к последовательности данных и возможность поиска/перфорация Манс. В начальном примере тривиально искать все элементы пользователя, так как все, что вам нужно, это загрузить этого одного пользователя, и у вас есть список элементов. Для другого направления требуется подход запроса.

Так что в отношении эффективности поиска вы получаете преимущество от наличия списка владельцев в элементах, а также список элементов в пользователе, потому что таким образом вам вообще не нужны запросы. Большой недостаток становится согласованностью данных. Если вы не можете одновременно обновить пользователя и элемент, у вас могут быть элементы, которые, как полагают, принадлежат пользователю, в котором пользователь думает иначе.

Последний подход, используя явную сущность «Собственность», по существу представляет собой традиционную таблицу pivot/junction https://en.wikipedia.org/wiki/Many-to-many_%28data_model%29, которая является результатом преобразования отношения многих-многих в 2 отношения «один-много». Использование этого приведет к легкой согласованности, но к худшей производительности запросов.

Родительские отношения иногда могут быть полезны, но только если существует фактическое отношение 1 к многим, где должен существовать родитель.

Также обратите внимание, как ключи не являются внешними ключами, как в традиционных SQL-базах данных, поскольку они могут существовать без сущности. Поэтому вам нужно будет заботиться о последовательности, независимо от того, что вы делаете.

+0

Большое спасибо за впечатляющий ответ! Мне плохо, что у меня есть вопросы. Когда я пытаюсь вернуть List , я получаю такую ​​ошибку: «Параметрированный тип com.googlecode.objectify.Ref <> не поддерживается.» Я смог избежать этой ошибки, добавив '@ApiResourceProperty (ignored = AnnotationBoolean.TRUE) 'аннотации к методу, но в этом случае я не могу использовать метод getter в коде Android. – iamkaan

Смежные вопросы