Usar Cloud Datastore con Java para el entorno estándar de App Engine

En esta parte del tutorial de Bookshelf para Java, se muestra cómo crear, leer, actualizar y eliminar datos estructurados en Google Cloud Datastore.

Esta página forma parte de un tutorial de varias páginas. Para empezar en orden y consultar las instrucciones de configuración, ve a la aplicación Bookshelf de Java.

Establecer configuración

El archivo pom.xml contiene información de configuración para todas las partes del tutorial de Bookshelf. En esta parte del tutorial, no se necesita agregar ninguna información de configuración. El único requisito es que la propiedad bookshelf.storageType se establezca en como datastore, y ya lo hicimos por ti.

Ejecutar la aplicación en la máquina local

Para ejecutar la aplicación de forma local, sigue estos pasos:

  1. En el directorio getting-started-java/bookshelf-standard/2-structured-data, introduce el siguiente comando para iniciar un servidor web local:

    mvn -Plocal clean appengine:devserver
  2. En el navegador web, ve a http://localhost:8080

Ahora puedes navegar por las páginas web de la aplicación donde podrás agregar, editar y eliminar libros.

Desplegar la aplicación en el entorno estándar de App Engine

Para realizar el despliegue en el entorno estándar de App Engine, sigue estos pasos:

  1. Asegúrate de haber utilizado la aplicación Bookshelf de forma completamente local, especialmente mediante la creación de al menos un libro y luego haz clic en Mis libros. Al hacerlo, se crea un índice de Cloud Datastore requerido que se sube con Bookshelf. Ten en cuenta que compilar la aplicación mediante clean elimina ese índice local, así que asegúrate de hacer esto en la compilación de la aplicación que vas a desplegar.
  2. Para desplegar la aplicación, introduce el comando a continuación en el directorio getting-started-java/bookshelf-standard/2-structured-data:
    mvn appengine:update -Dappengine.appId=[YOUR-PROJECT-ID] -Dappengine.version=[YOUR-VERSION]
    Reemplaza [YOUR-PROJECT-ID] por el ID del proyecto y [YOUR-VERSION] por la versión, por ejemplo, 1, o 2, o algún otro valor de cadena que quieras usar.
  3. Introduce la siguiente dirección en el navegador web:
    https://[YOUR-PROJECT-ID].appspot.com
    Reemplaza [YOUR-PROJECT-ID] por el ID del proyecto.

Después de actualizar la aplicación, si quieres volver a desplegar la versión actualizada, puedes introducir el mismo comando que utilizaste para desplegar la aplicación por primera vez, especificando el mismo ID y versión del proyecto; al hacerlo, se sobrescribe la aplicación desplegada actualmente. Si especificas una cadena con una versión diferente en la línea de comando de actualización, el nuevo despliegue crea una nueva versión de la aplicación y la promociona para que sea la versión publicada actual.

Si eliminas las versiones no publicadas de la aplicación, puedes reducir los costes.

Para eliminar una versión de la aplicación, sigue las instrucciones a continuación:

  1. In the GCP Console, go to the Versions page for App Engine.

    Go to the Versions page

  2. Select the checkbox for the non-default app version you want to delete.
  3. Click Delete to delete the app version.

Si quieres obtener información completa sobre cómo limpiar los recursos facturables, consulta la sección sobre limpiar los recursos en el último paso de este tutorial.

Estructura de la aplicación

En el siguiente diagrama, se muestran los componentes de la aplicación y su funcionamiento.

Proceso y estructura de despliegue de la aplicación Bookshelf

Información sobre el código

En esta sección, se explica detalladamente el código de la aplicación y su funcionamiento.

Interactuar con Cloud Datastore

La aplicación utiliza un objeto de servicio Datastore autorizado para interactuar con Cloud Datastore. Se trata de un objeto pesado, debido a que ha intercambiado credenciales por un token que puede usar para acceder a las API de Datastore. La aplicación también crea un objeto KeyFactory de tipo Book. El libro es el único tipo de datos que esta aplicación almacena. Sin embargo, en general, puedes almacenar cualquier tipo de datos que desees. Cloud Datastore admite una gran variedad de tipos de datos.

private DatastoreService datastore;
private static final String BOOK_KIND = "Book2";

public DatastoreDao() {
  datastore = DatastoreServiceFactory.getDatastoreService(); // Authorized Datastore service
}

Crear libros

Para guardar un libro, la aplicación almacena una entidad en Cloud Datastore. Una entidad tiene una clave y una colección de pares de nombres o valores. El método createBook crea una nueva entidad de tipo BOOK y establece los valores proporcionados por el usuario para el autor, la descripción, la fecha de publicación y el título. Observa que la clave se asigna a la entidad cuando la entidad se agrega al almacén de datos.

@Override
public Long createBook(Book book) {
  Entity incBookEntity = new Entity(BOOK_KIND);  // Key will be assigned once written
  incBookEntity.setProperty(Book.AUTHOR, book.getAuthor());
  incBookEntity.setProperty(Book.DESCRIPTION, book.getDescription());
  incBookEntity.setProperty(Book.PUBLISHED_DATE, book.getPublishedDate());
  incBookEntity.setProperty(Book.TITLE, book.getTitle());

  Key bookKey = datastore.put(incBookEntity); // Save the Entity
  return bookKey.getId();                     // The ID of the Key
}

Leer de Cloud Datastore

El método readBook toma el ID de un libro y lo convierte en una clave. Luego envía la clave al método getProperty, que devuelve un objeto Entity.

@Override
public Book readBook(Long bookId) {
  try {
    Entity bookEntity = datastore.get(KeyFactory.createKey(BOOK_KIND, bookId));
    return entityToBook(bookEntity);
  } catch (EntityNotFoundException e) {
    return null;
  }
}

El método entityToBook convierte la entidad que Cloud Datastore ha devuelto a un objeto Book mediante los métodos getProperty para cada tipo, de forma similar a como se usa setProperty para crear la entidad. Ten en cuenta que los nombres de propiedades son valores de String.

public Book entityToBook(Entity entity) {
  return new Book.Builder()                                     // Convert to Book form
      .author((String)entity.getProperty(Book.AUTHOR))
      .description((String)entity.getProperty(Book.DESCRIPTION))
      .id(entity.getKey().getId())
      .publishedDate((String)entity.getProperty(Book.PUBLISHED_DATE))
      .title((String)entity.getProperty(Book.TITLE))
      .build();
}

Actualizar libros

La actualización solo requiere llamar al método put con una Entity.

@Override
public void updateBook(Book book) {
  Key key = KeyFactory.createKey(BOOK_KIND, book.getId());  // From a book, create a Key
  Entity entity = new Entity(key);         // Convert Book to an Entity
  entity.setProperty(Book.AUTHOR, book.getAuthor());
  entity.setProperty(Book.DESCRIPTION, book.getDescription());
  entity.setProperty(Book.PUBLISHED_DATE, book.getPublishedDate());
  entity.setProperty(Book.TITLE, book.getTitle());

  datastore.put(entity);                   // Update the Entity
}

Para eliminar con Datastore, se requiere llamar al método delete con una Key.

Eliminar libros

@Override
public void deleteBook(Long bookId) {
  Key key = KeyFactory.createKey(BOOK_KIND, bookId);        // Create the Key
  datastore.delete(key);                      // Delete the Entity
}

Mostrar libros

El método listBooks devuelve una lista de libros, de diez en uno, junto con un Cursor seguro para URLs:

@Override
public Result<Book> listBooks(String startCursorString) {
  FetchOptions fetchOptions = FetchOptions.Builder.withLimit(10); // Only show 10 at a time
  if (startCursorString != null && !startCursorString.equals("")) {
    fetchOptions.startCursor(Cursor.fromWebSafeString(startCursorString)); // Where we left off
  }
  Query query = new Query(BOOK_KIND) // We only care about Books
      .addSort(Book.TITLE, SortDirection.ASCENDING); // Use default Index "title"
  PreparedQuery preparedQuery = datastore.prepare(query);
  QueryResultIterator<Entity> results = preparedQuery.asQueryResultIterator(fetchOptions);

  List<Book> resultBooks = entitiesToBooks(results);     // Retrieve and convert Entities
  Cursor cursor = results.getCursor();              // Where to start next time
  if (cursor != null && resultBooks.size() == 10) {         // Are we paging? Save Cursor
    String cursorString = cursor.toWebSafeString();               // Cursors are WebSafe
    return new Result<>(resultBooks, cursorString);
  } else {
    return new Result<>(resultBooks);
  }
}

Indexación

Datastore crea automáticamente un índice para cada una de tus propiedades de forma predeterminada, aunque se puede cambiar este comportamiento. Algunas consultas necesitan más de una sola propiedad en el índice para completarse, como la consulta por usuario, ordenada por Consulta de título anterior. Puedes crear índices para admitir dichas consultas manualmente o mediante el uso del servidor de desarrollo para crear índices.

¿Te ha resultado útil esta página? Enviar comentarios: