#android #google-app-engine #google-cloud-datastore
#Android #google-app-engine #google-облачное хранилище данных
Вопрос:
Недавно я перешел с JDO на Objectify, чтобы упростить некоторые свои серверные части (я новичок в движке приложений и на стороне сервера в целом).
У меня есть объект appVersion, который раньше выглядел так в облачной консоли:
Когда я переключился на objectify, у него больше нет возможности фильтровать по minVersionRequired и выглядит так:
Код объекта (ранее)
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class AppVersion {
@Id
private String applicationName;
private int minVersionRequired;
public String getApplicationName() {
return applicationName;
}
public int getMinVersionRequired() {
return minVersionRequired;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public void setminVersionRequired(int minVersionRequired) {
this.minVersionRequired = minVersionRequired;
}
}
Код объекта (после)
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
@Entity
public class AppVersion {
@Id
private String applicationName;
private int minVersionRequired;
public String getApplicationName() {
return applicationName;
}
public int getMinVersionRequired() {
return minVersionRequired;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public void setminVersionRequired(int minVersionRequired) {
this.minVersionRequired = minVersionRequired;
}
}
Код конечной точки (ранее) Обратите внимание, что он был автоматически создан в Eclipse
import com.companionfree.zooperthemeviewer.EMF;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.datanucleus.query.JPACursorHelper;
import java.util.List;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@Api(name = "appversionendpoint", namespace = @ApiNamespace(ownerDomain = "company.com", ownerName = "company.com", packagePath = "app"))
public class AppVersionEndpoint {
/**
* This method lists all the entities inserted in datastore.
* It uses HTTP GET method and paging support.
*
* @return A CollectionResponse class containing the list of all entities
* persisted and a cursor to the next page.
*/
@SuppressWarnings({ "unchecked", "unused" })
@ApiMethod(name = "listAppVersion")
public CollectionResponse<AppVersion> listAppVersion(
@Nullable @Named("cursor") String cursorString,
@Nullable @Named("limit") Integer limit) {
EntityManager mgr = null;
Cursor cursor = null;
List<AppVersion> execute = null;
try {
mgr = getEntityManager();
Query query = mgr
.createQuery("select from AppVersion as AppVersion");
if (cursorString != null amp;amp; cursorString != "") {
cursor = Cursor.fromWebSafeString(cursorString);
query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
}
if (limit != null) {
query.setFirstResult(0);
query.setMaxResults(limit);
}
execute = (List<AppVersion>) query.getResultList();
cursor = JPACursorHelper.getCursor(execute);
if (cursor != null)
cursorString = cursor.toWebSafeString();
// Tight loop for fetching all entities from datastore and accomodate
// for lazy fetch.
for (AppVersion obj : execute)
;
} finally {
mgr.close();
}
return CollectionResponse.<AppVersion> builder().setItems(execute)
.setNextPageToken(cursorString).build();
}
/**
* This method gets the entity having primary key id. It uses HTTP GET method.
*
* @param id the primary key of the java bean.
* @return The entity with primary key id.
*/
@ApiMethod(name = "getAppVersion")
public AppVersion getAppVersion(@Named("id") String id) {
EntityManager mgr = getEntityManager();
AppVersion appversion = null;
try {
appversion = mgr.find(AppVersion.class, id);
} finally {
mgr.close();
}
return appversion;
}
/**
* This inserts a new entity into App Engine datastore. If the entity already
* exists in the datastore, an exception is thrown.
* It uses HTTP POST method.
*
* @param appversion the entity to be inserted.
* @return The inserted entity.
*/
@ApiMethod(name = "insertAppVersion")
public AppVersion insertAppVersion(AppVersion appversion) {
EntityManager mgr = getEntityManager();
try {
if (containsAppVersion(appversion)) {
throw new EntityExistsException("Object already exists");
}
mgr.persist(appversion);
} finally {
mgr.close();
}
return appversion;
}
/**
* This method is used for updating an existing entity. If the entity does not
* exist in the datastore, an exception is thrown.
* It uses HTTP PUT method.
*
* @param appversion the entity to be updated.
* @return The updated entity.
*/
@ApiMethod(name = "updateAppVersion")
public AppVersion updateAppVersion(AppVersion appversion) {
EntityManager mgr = getEntityManager();
try {
if (!containsAppVersion(appversion)) {
throw new EntityNotFoundException("Object does not exist");
}
mgr.persist(appversion);
} finally {
mgr.close();
}
return appversion;
}
/**
* This method removes the entity with primary key id.
* It uses HTTP DELETE method.
*
* @param id the primary key of the entity to be deleted.
*/
@ApiMethod(name = "removeAppVersion")
public void removeAppVersion(@Named("id") String id) {
EntityManager mgr = getEntityManager();
try {
AppVersion appversion = mgr.find(AppVersion.class, id);
mgr.remove(appversion);
} finally {
mgr.close();
}
}
private boolean containsAppVersion(AppVersion appversion) {
EntityManager mgr = getEntityManager();
boolean contains = true;
try {
AppVersion item = mgr.find(AppVersion.class,
appversion.getApplicationName());
if (item == null) {
contains = false;
}
} finally {
mgr.close();
}
return contains;
}
private static EntityManager getEntityManager() {
return EMF.get().createEntityManager();
}
}
Код конечных точек (после) Примечание это было создано мной в Android Studio
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import java.util.List;
import javax.inject.Named;
import static com.company.backend.OfyService.ofy;
@Api(name = "appversionendpoint", version = "v1", namespace =
@ApiNamespace(ownerDomain = "backend.company.com",
ownerName = "backend.company.com", packagePath = ""))
public class AppVersionEndpoint {
@ApiMethod(name = "listAppVersion")
public CollectionResponse<AppVersion> listAppVersion() {
List<AppVersion> execute;
execute = ofy().load().type(AppVersion.class).list();
return CollectionResponse.<AppVersion> builder().setItems(execute).build();
}
/**
* This method gets the entity having primary key id. It uses HTTP GET method.
*
* @param id the primary key of the java bean.
* @return The entity with primary key id (null if DNE).
*/
@ApiMethod(name = "getAppVersion")
public AppVersion getAppVersion(@Named("id") String id) {
return ofy().load().type(AppVersion.class).id(id).now();
}
/**
* This inserts a new entity into App Engine datastore. If the entity already
* exists in the datastore, an exception is thrown.
* It uses HTTP POST method.
*
* @param appversion the entity to be inserted.
* @return The inserted entity.
*/
@ApiMethod(name = "insertAppVersion")
public AppVersion insertAppVersion(AppVersion appversion) {
AppVersion exist = getAppVersion(appversion.getApplicationName());
AppVersion resu<
if (exist == null) {
ofy().save().entity(appversion).now();
result = getAppVersion(appversion.getApplicationName());
} else {
throw new IllegalArgumentException(appversion.getApplicationName() " exists already");
}
return resu<
}
}
Я бы предпочел, чтобы он был фильтруемым, как это было изначально, но я не знаю, почему он отличается. Может кто-нибудь ввести меня в курс дела?
Ответ №1:
Здесь происходит две вещи: во-первых, по умолчанию Objectify предполагает, что вы не хотите индексировать свойства своего класса (это сохраняет ваши индексы хранилища данных скудными и средними). Во-вторых, я считаю, что пользовательский интерфейс фильтра новой консоли хранилища данных отображает только те свойства, с которыми связаны индексы (поскольку вы не можете фильтровать неиндексированные свойства).
Итак, если вы хотите иметь возможность запрашивать или сортировать по minVersionRequired, просто добавьте @Index
аннотацию к этому полю в вашем POJO, и Objectify будет использовать setIndexedProperty()
метод в базовом классе Entity в API хранилища данных низкого уровня.
Если вы хотите проиндексировать все свойства в своем классе по умолчанию, вы можете поместить @Index
аннотацию к классу, а затем @Unindex
любую, которую вы специально не хотите индексировать.
Комментарии:
1. Похоже, что это не сработало. Может быть, это займет некоторое время? Мне не нужно повторно добавлять все объекты, верно?
2. Эй, что ты знаешь… Я вернулся и проверил несколько часов спустя, и изменения вступили в силу. Спасибо!