Clase DynamoDBMapper - Amazon DynamoDB

Clase DynamoDBMapper

La clase DynamoDBMapper es el punto de entrada de Amazon DynamoDB. Proporciona acceso a un punto de enlace de DynamoDB y le permite obtener acceso a sus datos en diversas tablas. También permite realizar varias operaciones de creación, lectura, actualización y eliminación (CRUD, Create, Read, Update y Delete) en elementos y ejecutar consultas y análisis en tablas. Esta clase proporciona los siguientes métodos para trabajar con DynamoDB.

Para obtener la documentación de Javadoc correspondiente, consulte DynamoDBMapper en la Referencia de la API de AWS SDK for Java.

save

Guarda el objeto especificado en la tabla. El objeto que se desea guardar es el único parámetro obligatorio para este método. Puede usar el objeto DynamoDBMapperConfig para proporcionar parámetros de configuración opcionales.

Si no hay un elemento que tenga la misma clave principal, este método crea un nuevo elemento en la tabla. Si hay un elemento que tiene la misma clave principal, lo actualiza. Si las claves de partición y orden son de tipo String y se han anotado con @DynamoDBAutoGeneratedKey, se les asigna un identificador universal único (UUID) aleatorio si se deja sin inicializar. Los campos de versión que se anotan con @DynamoDBVersionAttribute se incrementan en una unidad. Además, si se actualiza un campo de versión o se genera una clave, el objeto que se ha pasado se actualiza como consecuencia de la operación.

De forma predeterminada, solo se actualizan los atributos correspondientes a propiedades de clases mapeadas. Ningún atributo existente adicional de un elemento se ve afectado. Sin embargo, si especifica SaveBehavior.CLOBBER, puede forzar que se sobrescriba el elemento completo.

DynamoDBMapperConfig config = DynamoDBMapperConfig.builder() .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER).build(); mapper.save(item, config);

Si el control de versiones está habilitado, las versiones del elemento del lado del cliente y del lado del servidor deben coincidir. Sin embargo, no es preciso que coincidan las versiones si se utiliza la opción SaveBehavior.CLOBBER. Para obtener más información sobre el control de versiones, consulte Bloqueo positivo con el número de versión.

carga

Recupera un elemento de una tabla. Es preciso proporcionar la clave principal del elemento que se desea recuperar. Puede usar el objeto DynamoDBMapperConfig para proporcionar parámetros de configuración opcionales. Por ejemplo, si lo desea puede solicitar lecturas de consistencia alta para asegurarse de que este método recupere solamente los valores más recientes de los elementos, como se muestra en la siguiente instrucción de Java.

DynamoDBMapperConfig config = DynamoDBMapperConfig.builder() .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT).build(); CatalogItem item = mapper.load(CatalogItem.class, item.getId(), config);

De forma predeterminada, DynamoDB devuelve el elemento cuyos valores presentan consistencia final. Para obtener más información sobre el modelo de consistencia final de DynamoDB, consulte Coherencia de lectura.

eliminar

Elimina un elemento de la tabla. Debe pasar una instancia de objeto de la clase mapeada.

Si el control de versiones está habilitado, las versiones del elemento del lado del cliente y del lado del servidor deben coincidir. Sin embargo, no es preciso que coincidan las versiones si se utiliza la opción SaveBehavior.CLOBBER. Para obtener más información sobre el control de versiones, consulte Bloqueo positivo con el número de versión.

consulta

Consulta una tabla o un índice secundario.

Supongamos que tenemos una tabla Reply en la que se almacenan respuestas de conversaciones. Para cada tema de conversación puede haber cero o más respuestas. La clave principal de la tabla Reply consta de los campos Id y ReplyDateTime, donde Id es la clave de partición y ReplyDateTime es la clave de orden de la clave principal.

Reply ( Id, ReplyDateTime, ... )

Supongamos que creamos un mapeo entre una clase Reply y la tabla Reply correspondiente de DynamoDB. En el siguiente código Java se usa DynamoDBMapper para buscar todas las respuestas de las últimas dos semanas para un tema de conversación concreto.

ejemplo
String forumName = "&DDB;"; String forumSubject = "&DDB; Thread 1"; String partitionKey = forumName + "#" + forumSubject; long twoWeeksAgoMilli = (new Date()).getTime() - (14L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS(partitionKey)); eav.put(":v2",new AttributeValue().withS(twoWeeksAgoStr.toString())); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2") .withExpressionAttributeValues(eav); List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);

La consulta devuelve una colección de objetos Reply.

De forma predeterminada, el método query devuelve una colección de "carga diferida". Inicialmente devuelve una sola página de resultados y, a continuación, realiza una llamada de servicio para obtener la página siguiente si es necesario. Para obtener todos los elementos coincidentes, recorra en iteración la colección latestReplies.

Tenga en cuenta que llamar al método size() en la colección cargará todos los resultados para proporcionar un recuento preciso. Esto puede provocar que se consuma una gran cantidad de rendimiento aprovisionado y en una tabla muy grande incluso podría agotar toda la memoria en su JVM.

Para consultar un índice, antes es preciso modelarlo como clase de mapeador. Supongamos que la tabla Reply tiene un índice secundario global denominado PostedBy-Message-Index. La clave de partición de este índice es PostedBy y la de orden, Message. La definición de clase de un elemento del índice tendría el siguiente aspecto:

@DynamoDBTable(tableName="Reply") public class PostedByMessage { private String postedBy; private String message; @DynamoDBIndexHashKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "PostedBy") public String getPostedBy() { return postedBy; } public void setPostedBy(String postedBy) { this.postedBy = postedBy; } @DynamoDBIndexRangeKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } // Additional properties go here. }

La anotación @DynamoDBTable indica que este índice está asociado a la tabla Reply. La anotación @DynamoDBIndexHashKey se refiere a la clave de partición (PostedBy) del índice y la anotación @DynamoDBIndexRangeKey, a su clave de ordenación (Message).

Ahora, puede usar DynamoDBMapper para consultar el índice y recuperar un subconjunto de los mensajes publicados por un usuario determinado. No necesita especificar el nombre del índice si no tiene asignaciones conflictivas entre tablas e índices y las asignaciones ya están hechas en el mapeador. El mapeador deducirá en función de la clave principal y la clave de clasificación. El siguiente código consulta el índice secundario global. Es imprescindible especificar withConsistentRead(false), ya que los índices secundarios globales admiten las lecturas consistentes finales, pero no las de consistencia alta.

HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("User A")); eav.put(":v2", new AttributeValue().withS("DynamoDB")); DynamoDBQueryExpression<PostedByMessage> queryExpression = new DynamoDBQueryExpression<PostedByMessage>() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false) .withKeyConditionExpression("PostedBy = :v1 and begins_with(Message, :v2)") .withExpressionAttributeValues(eav); List<PostedByMessage> iList = mapper.query(PostedByMessage.class, queryExpression);

La consulta devuelve una colección de objetos PostedByMessage.

queryPage

Consulta una tabla o un índice secundario y devuelve una sola página de resultados coincidentes. Al igual que con el método query, es preciso especificar un valor de clave de partición y un filtro de consulta que se aplica al atributo de clave de ordenación. Sin embargo, queryPage solamente devuelve la primera "página" de datos; es decir, la cantidad de datos que se ajusta a 1 MB

scan

Examina una tabla o un índice secundario completos. Si lo desea, puede especificar una expresión FilterExpression para filtrar el conjunto de resultados.

Supongamos que tenemos una tabla Reply en la que se almacenan respuestas de conversaciones. Para cada tema de conversación puede haber cero o más respuestas. La clave principal de la tabla Reply consta de los campos Id y ReplyDateTime, donde Id es la clave de partición y ReplyDateTime es la clave de orden de la clave principal.

Reply ( Id, ReplyDateTime, ... )

Si ha mapeado una clase de Java a la tabla Reply, puede usar DynamoDBMapper para examinar la tabla. Por ejemplo, en el siguiente código Java se examina toda la tabla Reply y únicamente se devuelven las respuestas de un año determinado.

ejemplo
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("2015")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("begins_with(ReplyDateTime,:v1)") .withExpressionAttributeValues(eav); List<Reply> replies = mapper.scan(Reply.class, scanExpression);

De forma predeterminada, el método scan devuelve una colección de "carga diferida". Inicialmente devuelve una sola página de resultados y, a continuación, realiza una llamada de servicio para obtener la página siguiente si es necesario. Para obtener todos los elementos coincidentes, recorra en iteración la colección replies.

Tenga en cuenta que llamar al método size() en la colección cargará todos los resultados para proporcionar un recuento preciso. Esto puede provocar que se consuma una gran cantidad de rendimiento aprovisionado y en una tabla muy grande incluso podría agotar toda la memoria en su JVM.

Para examinar un índice, antes es preciso modelarlo como clase de mapeador. Supongamos que la tabla Reply tiene un índice secundario global denominado PostedBy-Message-Index. La clave de partición de este índice es PostedBy y la de orden, Message. En la sección consulta se muestra una clase de mapeador para este índice. Usa las anotaciones @DynamoDBIndexHashKey y @DynamoDBIndexRangeKey para especificar la clave de ordenación y la de partición del índice.

En el siguiente ejemplo de código se examina PostedBy-Message-Index. No se utiliza ningún filtro de examen, por lo que se devuelven todos los elementos del índice.

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false); List<PostedByMessage> iList = mapper.scan(PostedByMessage.class, scanExpression); Iterator<PostedByMessage> indexItems = iList.iterator();

scanPage

Examina una tabla o un índice secundario y devuelve una sola página de resultados coincidentes. Al igual que sucede con el método scan, si lo desea, puede especificar una expresión FilterExpression para filtrar el conjunto de resultados. Sin embargo, scanPage solamente devuelve la primera "página" de datos, es decir, la cantidad de datos que caben en 1 MB.

parallelScan

Realiza un examen en paralelo de una tabla o un índice secundario completos. Se especifica un número de segmentos lógicos de la tabla, junto con una expresión de examen para filtrar los resultados. parallelScan divide la tarea de examen entre varios procesos de trabajo, uno para cada segmento lógico. Los procesos de trabajo examinan los datos en paralelo y devuelven los resultados.

En el siguiente ejemplo de código Java se realiza un examen paralelo de la tabla Product.

int numberOfThreads = 4; Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":n", new AttributeValue().withN("100")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("Price <= :n") .withExpressionAttributeValues(eav); List<Product> scanResult = mapper.parallelScan(Product.class, scanExpression, numberOfThreads);

Para obtener un ejemplo de código Java que ilustra el uso de parallelScan, consulte Operaciones de consulta y escaneo de DynamoDBMapper.

batchSave

Guarda objetos en una o varias tablas mediante una o varias llamadas al método AmazonDynamoDB.batchWriteItem. Este método no proporciona garantías de transacción.

En el siguiente código Java se guardan dos elementos (libros) en la tabla ProductCatalog.

Book book1 = new Book(); book1.setId(901); book1.setProductCategory("Book"); book1.setTitle("Book 901 Title"); Book book2 = new Book(); book2.setId(902); book2.setProductCategory("Book"); book2.setTitle("Book 902 Title"); mapper.batchSave(Arrays.asList(book1, book2));

batchLoad

Recupera varios elementos de una o varias tablas mediante sus claves principales.

En el siguiente código Java se recuperan dos elementos de dos tablas distintas.

ArrayList<Object> itemsToGet = new ArrayList<Object>(); ForumItem forumItem = new ForumItem(); forumItem.setForumName("Amazon DynamoDB"); itemsToGet.add(forumItem); ThreadItem threadItem = new ThreadItem(); threadItem.setForumName("Amazon DynamoDB"); threadItem.setSubject("Amazon DynamoDB thread 1 message text"); itemsToGet.add(threadItem); Map<String, List<Object>> items = mapper.batchLoad(itemsToGet);

batchDelete

Elimina objetos de una o varias tablas mediante una o varias llamadas al método AmazonDynamoDB.batchWriteItem. Este método no proporciona garantías de transacción.

En el siguiente código Java se eliminan dos elementos (libros) de la tabla ProductCatalog.

Book book1 = mapper.load(Book.class, 901); Book book2 = mapper.load(Book.class, 902); mapper.batchDelete(Arrays.asList(book1, book2));

batchWrite

Guarda o elimina objetos en una o varias tablas mediante una o varias llamadas al método AmazonDynamoDB.batchWriteItem. Este método no proporciona garantías de transacción ni admite el control de versiones (colocaciones o eliminaciones condicionales).

En el siguiente código Java se escribe un nuevo elemento en la tabla Forum, se escribe un nuevo elemento en la tabla Thread y se elimina un elemento de la tabla ProductCatalog.

// Create a Forum item to save Forum forumItem = new Forum(); forumItem.setName("Test BatchWrite Forum"); // Create a Thread item to save Thread threadItem = new Thread(); threadItem.setForumName("AmazonDynamoDB"); threadItem.setSubject("My sample question"); // Load a ProductCatalog item to delete Book book3 = mapper.load(Book.class, 903); List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem); List<Book> objectsToDelete = Arrays.asList(book3); mapper.batchWrite(objectsToWrite, objectsToDelete);

transactionWrite

Guarda o elimina objetos en una o varias tablas mediante una llamada al método AmazonDynamoDB.transactWriteItems.

Para ver una lista de excepciones específicas de la transacción, consulte Errores de TransactWriteItems.

Para obtener más información sobre las transacciones de DynamoDB y las garantías proporcionadas de atomicidad, coherencia, aislamiento y durabilidad (ACID), consulte Amazon DynamoDB Transactions.

nota

Este método no admite lo siguiente:

El siguiente código Java escribe un nuevo elemento en cada una de las tablas Forum y Thread de un modo transaccional.

Thread s3ForumThread = new Thread(); s3ForumThread.setForumName("S3 Forum"); s3ForumThread.setSubject("Sample Subject 1"); s3ForumThread.setMessage("Sample Question 1"); Forum s3Forum = new Forum(); s3Forum.setName("S3 Forum"); s3Forum.setCategory("Amazon Web Services"); s3Forum.setThreads(1); TransactionWriteRequest transactionWriteRequest = new TransactionWriteRequest(); transactionWriteRequest.addPut(s3Forum); transactionWriteRequest.addPut(s3ForumThread); mapper.transactionWrite(transactionWriteRequest);

transactionLoad

Carga objetos de una o varias tablas mediante una llamada al método AmazonDynamoDB.transactGetItems.

Para ver una lista de excepciones específicas de transacciones, consulte Errores de TransactGetItems.

Para obtener más información sobre las transacciones de DynamoDB y las garantías proporcionadas de atomicidad, coherencia, aislamiento y durabilidad (ACID), consulte Amazon DynamoDB Transactions.

El siguiente código Java carga un elemento en cada una de las tablas Forum y Thread de un modo transaccional.

Forum dynamodbForum = new Forum(); dynamodbForum.setName("DynamoDB Forum"); Thread dynamodbForumThread = new Thread(); dynamodbForumThread.setForumName("DynamoDB Forum"); TransactionLoadRequest transactionLoadRequest = new TransactionLoadRequest(); transactionLoadRequest.addLoad(dynamodbForum); transactionLoadRequest.addLoad(dynamodbForumThread); mapper.transactionLoad(transactionLoadRequest);

count

Evalúa la expresión de examen especificada y devuelve el recuento de elementos coincidentes. No se devuelven datos de elementos.

generateCreateTableRequest

Analiza una clase de objeto Java estándar (POJO) que representa una tabla de DynamoDB y devuelve una solicitud de CreateTableRequest para esa tabla.

Crea un enlace a un objeto en Amazon S3. Debe especificar un nombre de bucket y un nombre de clave para identificar el objeto en el bucket de forma exclusiva.

Para usar createS3Link, la clase de mapeador debe definir métodos getter y setter. Esto se ilustra en el siguiente ejemplo de código con la adición de un nuevo atributo y de métodos getter/setter a la clase CatalogItem.

@DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { ... public S3Link productImage; .... @DynamoDBAttribute(attributeName = "ProductImage") public S3Link getProductImage() { return productImage; } public void setProductImage(S3Link productImage) { this.productImage = productImage; } ... }

En el siguiente código Java se define un nuevo elemento para escribirlo en la tabla Product. El elemento incluye un enlace a la imagen de un producto; los datos de la imagen se cargan en Amazon S3.

CatalogItem item = new CatalogItem(); item.setId(150); item.setTitle("Book 150 Title"); String myS3Bucket = "myS3bucket"; String myS3Key = "productImages/book_150_cover.jpg"; item.setProductImage(mapper.createS3Link(myS3Bucket, myS3Key)); item.getProductImage().uploadFrom(new File("/file/path/book_150_cover.jpg")); mapper.save(item);

La clase S3Link proporciona muchos métodos más para manipular objetos en Amazon S3. Para obtener más información, consulte los javadocs en Class S3Link.

getS3ClientCache

Devuelve el objeto S3ClientCache subyacente para obtener acceso a Amazon S3. Un objeto S3ClientCache es un mapa inteligente para objetos AmazonS3Client. Si tiene varios clientes, S3ClientCache puede ayudarle a organizarlos por región de AWS y a crear nuevos clientes de Amazon S3 en diferido.