Comenzar: Cloud Datastore

Aprende cómo crear una aplicación de App Engine que almacena datos en Google Cloud Datastore, una base de datos no relacional (NoSQL).

Cloud Datastore es la única opción de almacenamiento disponible con App Engine que se puede integrar de manera sencilla en las aplicaciones y almacenar datos de texto. Compara Cloud Datastore, Cloud SQL y Cloud Storage y elige la que mejor se adapte a los requisitos de tu app.

Este ejemplo se basa en una serie de guías y muestra cómo almacenar datos de entradas de blog en Cloud Datastore.

Antes de comenzar

Configura tu entorno de programación y crea tu proyecto de App Engine.

Cómo importar bibliotecas

El ejemplo utiliza las siguientes bibliotecas:

import com.google.appengine.api.datastore.DatastoreFailureException;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

Las bibliotecas que utilizas en tu propio trabajo pueden ser distintas según las características de almacén de datos que usas. No todas las tareas necesitan todas las bibliotecas enumeradas y te recomendamos importar solo las bibliotecas necesarias.

Cómo configurar una conexión a Cloud Datastore

Antes de leer o escribir en Cloud Datastore, debes crear un objeto DatastoreService y usarlo para comunicarte con Cloud Datastore. El siguiente código crea una conexión:

DatastoreService datastore;
datastore = DatastoreServiceFactory.getDatastoreService();

DatastoreService es un objeto de gran tamaño, así que asegúrate de minimizar la cantidad de llamadas utilizando operaciones por lotes.

Cómo crear y almacenar entidades

Los objetos se almacenan en Cloud Datastore como entidades, con los datos de los objetos almacenados en las propiedades de la entidad. Este ejemplo almacena datos en una entidad llamada post que tiene cuatro propiedades: title, body, author, y timestamp.

Los datos se suministran a través de un formulario HTML, como se indica en Cómo manejar los datos del formulario enviado por el usuario.

DatastoreService datastore;

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {

  // Create a map of the httpParameters that we want and run it through jSoup
  Map<String, String> blogContent =
      req.getParameterMap()
          .entrySet()
          .stream()
          .filter(a -> a.getKey().startsWith("blogContent_"))
          .collect(
              Collectors.toMap(
                  p -> p.getKey(), p -> Jsoup.clean(p.getValue()[0], Whitelist.basic())));

  Entity post = new Entity("Blogpost"); // create a new entity

  post.setProperty("title", blogContent.get("blogContent_title"));
  post.setProperty("author", blogContent.get("blogContent_author"));
  post.setProperty("body", blogContent.get("blogContent_description"));
  post.setProperty("timestamp", new Date().getTime());

  try {
    datastore.put(post); // store the entity

    // Send the user to the confirmation page with personalised confirmation text
    String confirmation = "Post with title " + blogContent.get("blogContent_title") + " created.";

    req.setAttribute("confirmation", confirmation);
    req.getRequestDispatcher("/confirm.jsp").forward(req, resp);
  } catch (DatastoreFailureException e) {
    throw new ServletException("Datastore error", e);
  }
}

@Override
public void init() throws ServletException {

  // setup datastore service
  datastore = DatastoreServiceFactory.getDatastoreService();
}

En el ejemplo, cada entidad post tiene un identificador que Cloud Datastore creó de manera automática. Si deseas asignar tu propio identificador, especifica uno cuando creas la entidad:

Entity post = new Entity("Blogpost", "[IDENTIFIER]");

La capacidad de especificar un identificador es importante cuando actualizas una entidad existente que se encuentra documentada en Actualizar entidades.

Luego de crear una entidad post, configura sus propiedades title, author, body y timestamp con setProperty() y almacena la entidad propagada de forma completa en Cloud Datastore mediante put.

datastore.put(post);

Cómo leer entidades

Para leer entidades de Cloud Datastore, debes utilizar una consulta. El ejemplo utiliza una consulta que muestra cinco entradas de blog en la página de información:

final Query q =
    new Query("Blogpost").setFilter(new FilterPredicate("title", FilterOperator.NOT_EQUAL, ""));

PreparedQuery pq = datastore.prepare(q);
List<Entity> posts = pq.asList(FetchOptions.Builder.withLimit(5)); // Retrieve up to five posts

posts.forEach(
    (result) -> {
      // Grab the key and convert it into a string in preparation for encoding
      String keyString = KeyFactory.keyToString(result.getKey());

      // Encode the entity's key with Base64
      String encodedID = new String(Base64.getUrlEncoder().encodeToString(String.valueOf(keyString).getBytes()));

      // Build up string with values from the Datastore entity
      String recordOutput =
          String.format(blogPostDisplayFormat, result.getProperty("title"), result.getProperty("timestamp"),
              result.getProperty("author"), encodedID, encodedID, result.getProperty("body"));

      out.println(recordOutput); // Print out HTML
    });

El objeto de la consulta de Cloud Datastore es compatible con filtros que utilizan setFilter, que es similar a la cláusula WHERE SQL. Este ejemplo utiliza la clase FetchOptions.Builder para recuperar cinco entradas de blog.

Para ver un ejemplo que muestra una cantidad ilimitada de elementos en lotes con cursores, consulta el instructivo de Bookshelf.

Cómo actualizar entidades

Para actualizar una entidad, crea una entidad nueva con la misma clave que la entidad original. Este ejemplo crea una entidad post nueva que tiene la misma clave que la original, pero la propaga con texto actualizado antes de almacenarla.

// Decode the websafe ID
String decodedKey = new String(Base64.getUrlDecoder().decode(blogContent.get("blogContent_id")));

// Create a key from the decoded websafe string
Key originalPostKey = KeyFactory.stringToKey(decodedKey);

// Create a new entity with the same key as the original
Entity post = new Entity("Blogpost", originalPostKey.getId());

// Populate the new entity with the updated blog post contents
post.setProperty("title", blogContent.get("blogContent_title"));
post.setProperty("author", blogContent.get("blogContent_author"));
post.setProperty("body", blogContent.get("blogContent_body"));
post.setProperty("timestamp", new Date());

try {
  datastore.put(post); // Store the post

  // Send the user to the confirmation page with personalised confirmation text
  String confirmation = "Post with title " + blogContent.get("blogContent_title") + " updated.";

  req.setAttribute("confirmation", confirmation);
  req.getRequestDispatcher("/confirm.jsp").forward(req, resp);
} catch (DatastoreFailureException e) {
  throw new ServletException("Datastore error", e);
}

Cómo borrar entidades

Para borrar entidades en Cloud Datastore, llama al método delete que pasa la Key de la publicación que deseas eliminar.

// Get the websafe cursor and then convert it into a usable key
// for retrieving a particular post
Map<String, String[]> blogContent = req.getParameterMap();
String[] postId = blogContent.get("id");
String decodedKey = new String(Base64.getUrlDecoder().decode(postId[0])); // Decode the websafe ID

try {
  try {
    Entity deletePost = datastore.get(KeyFactory.stringToKey(decodedKey));
    // Delete the entity based on its key
    datastore.delete(deletePost.getKey());

    // Send the user to the confirmation page with personalised confirmation text
    String confirmation = "Post " + deletePost.getProperty("title") + " has been deleted.";

    req.setAttribute("confirmation", confirmation);
    req.getRequestDispatcher("/confirm.jsp").forward(req, resp);

  } catch (EntityNotFoundException e) {
    throw new ServletException("Datastore error", e);
  }
} catch (DatastoreFailureException e) {
  throw new ServletException("Datastore error", e);
}

El ID de clave original codificada en este ejemplo se pasa a través de la URL a la aplicación de muestra, en la que se decodifica y se utiliza como el valor clave en una llamada a createKey desde la clase KeyFactory. createKey requiere un tipo de entidad, una Blogpost y un identificador que se recupera de las variables de solicitud de servlet y se convierte en un número entero Long.

Cómo implementar en App Engine

Puedes implementar tu aplicación en App Engine con Maven.

Ve al directorio raíz de tu proyecto y escribe:

mvn appengine:deploy

Luego de que Maven implemente tu app, escribe lo siguiente para abrir una pestaña del navegador web de forma automática en tu nueva app:

gcloud app browse

Próximos pasos

Cloud Datastore es útil para almacenar datos basados en texto; sin embargo, si deseas almacenar imágenes, deberías considerar Cloud Storage.

Cómo usar Cloud Storage

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

Enviar comentarios sobre...

Entorno estándar de App Engine para Java 8