Uso de elementos: Java
Puede usar la API de documentos del AWS SDK for Java para realizar operaciones típicas de creación, lectura, actualización y eliminación (CRUD, por sus siglas en inglés) en los elementos de una tabla de Amazon DynamoDB.
nota
Además, SDK para Java proporciona un modelo de persistencia de objetos, que le permite mapear las clases del lado del cliente a las tablas de DynamoDB. Este enfoque puede reducir la cantidad de código que hay que escribir. Para obtener más información, consulte Java 1.x: DynamoDBMapper.
Esta sección contiene ejemplos de Java que permiten realizar diversas acciones con elementos de la API de documentos de Java y varios ejemplos de trabajo completos.
Temas
- Colocación de un elemento
- Obtención de un elemento
- Escritura por lotes: colocación y eliminación de varios elementos
- Obtención por lotes: obtención de varios elementos
- Actualización de un elemento
- Eliminación de un elemento
- Ejemplo: operaciones CRUD mediante la API de documentos de AWS SDK for Java
- Ejemplo: operaciones por lotes mediante la API de documentos de AWS SDK for Java
- Ejemplo: control de atributos de tipo binario mediante la API de documentos de AWS SDK for Java
Colocación de un elemento
El método putItem
almacena un elemento en una tabla. Si el elemento existe, sustituye el elemento completo. En lugar de ello, si prefiere actualizar solamente algunos atributos concretos, puede usar el método updateItem
. Para obtener más información, consulte Actualización de un elemento.
Especificación de parámetros opcionales
Junto con los parámetros requeridos, puede especificar también otros opcionales en el método putItem
. Por ejemplo, en el ejemplo de código Java siguiente se utiliza un parámetro opcional que permite especificar una condición para cargar el elemento. Si la condición especificada no se cumple, AWS SDK for Java genera una excepción ConditionalCheckFailedException
. En el ejemplo de código se especifican los parámetros opcionales siguientes en el método putItem
:
-
Una expresión
ConditionExpression
que define las condiciones de la solicitud. El código define la condición siguiente: si el elemento existente tiene la misma clave principal, solo se sustituirá si tiene también un atributo ISBN igual a un valor específico. -
Un mapa de
ExpressionAttributeValues
que se usa en la condición. En este caso, solo se requiere una sustitución: el marcador de posición:val
de la expresión de condición se sustituye en el tiempo de ejecución por el valor de ISBN real que se va a comprobar.
En el siguiente ejemplo se agrega un nuevo elemento de libro utilizando estos parámetros opcionales.
ejemplo
Item item = new Item() .withPrimaryKey("Id", 104) .withString("Title", "Book 104 Title") .withString("ISBN", "444-4444444444") .withNumber("Price", 20) .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author1", "Author2"))); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val", "444-4444444444"); PutItemOutcome outcome = table.putItem( item, "ISBN = :val", // ConditionExpression parameter null, // ExpressionAttributeNames parameter - we're not using it for this example expressionAttributeValues);
PutItem y documentos JSON
Puede almacenar un documento JSON como atributo en una tabla de DynamoDB. Para ello, se utiliza el método withJSON
de Item
. Este método analiza el documento JSON y mapea cada componente a un tipo de datos nativo de DynamoDB.
Suponga que desea almacenar el siguiente documento JSON, que contiene los proveedores que pueden servir pedidos de un producto determinado.
ejemplo
{ "V01": { "Name": "Acme Books", "Offices": [ "Seattle" ] }, "V02": { "Name": "New Publishers, Inc.", "Offices": ["London", "New York" ] }, "V03": { "Name": "Better Buy Books", "Offices": [ "Tokyo", "Los Angeles", "Sydney" ] } }
Puede utilizar el método withJSON
para almacenar esta información en la tabla ProductCatalog
en un atributo de tipo Map
denominado VendorInfo
. En el siguiente ejemplo de código Java se muestra cómo hacerlo.
// Convert the document into a String. Must escape all double-quotes. String vendorDocument = "{" + " \"V01\": {" + " \"Name\": \"Acme Books\"," + " \"Offices\": [ \"Seattle\" ]" + " }," + " \"V02\": {" + " \"Name\": \"New Publishers, Inc.\"," + " \"Offices\": [ \"London\", \"New York\"" + "]" + "}," + " \"V03\": {" + " \"Name\": \"Better Buy Books\"," + "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\"" + " ]" + " }" + " }"; Item item = new Item() .withPrimaryKey("Id", 210) .withString("Title", "Book 210 Title") .withString("ISBN", "210-2102102102") .withNumber("Price", 30) .withJSON("VendorInfo", vendorDocument); PutItemOutcome outcome = table.putItem(item);
Obtención de un elemento
Para recuperar un solo elemento, utilice el método getItem
de un objeto Table
. Siga estos pasos:
-
Cree una instancia de la clase
DynamoDB
. -
Cree una instancia de la clase
Table
para representar la tabla que desea usar. -
Llame al método
getItem
de la instancia deTable
. Es preciso especificar la clave principal del elemento que se desea recuperar.
En el siguiente ejemplo de código Java se muestran los pasos anteriores. El código obtiene el elemento que tiene la clave de partición especificada.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Item item = table.getItem("Id", 210);
Especificación de parámetros opcionales
Junto con los parámetros requeridos, puede especificar también otros opcionales del método getItem
. Por ejemplo, en el siguiente ejemplo de código Java se utiliza un método opcional para recuperar solo una lista concreta de atributos y especificar lecturas de consistencia alta. Para obtener más información sobre la consistencia de lectura, consulte Coherencia de lectura de DynamoDB.
Puede usar una expresión ProjectionExpression
para recuperar solamente algunos atributos o componentes concretos, en lugar de un elemento completo. Una expresión ProjectionExpression
permite especificar atributos de nivel superior o anidados mediante rutas de documentos. Para obtener más información, consulte Uso de expresiones de proyección en DynamoDB.
Los parámetros del método getItem
no permiten especificar la consistencia de .lectura Sin embargo, puede crear una especificación GetItemSpec
, que proporciona acceso pleno a toda la información de entrada de la operación de bajo nivel GetItem
. En el ejemplo de código siguiente se crea una especificación GetItemSpec
y se utiliza como información de entrada para el método getItem
.
ejemplo
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 206) .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar") .withConsistentRead(true); Item item = table.getItem(spec); System.out.println(item.toJSONPretty());
Para imprimir un Item
en formato fácil de leer, utilice el método toJSONPretty
. El resultado del ejemplo anterior tiene este aspecto.
{ "RelatedItems" : [ 341 ], "Reviews" : { "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ] }, "Id" : 123, "Title" : "20-Bicycle 123" }
GetItem y documentos JSON
En la sección PutItem y documentos JSON, almacena un documento JSON en un atributo Map
denominado VendorInfo
. Puede utilizar el método getItem
para recuperar todo el documento en formato JSON. O puede usar la notación de ruta de documento para recuperar solo algunos de los componentes de ese documento. En el siguiente ejemplo de código Java se muestran estas técnicas.
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210); System.out.println("All vendor info:"); spec.withProjectionExpression("VendorInfo"); System.out.println(table.getItem(spec).toJSON()); System.out.println("A single vendor:"); spec.withProjectionExpression("VendorInfo.V03"); System.out.println(table.getItem(spec).toJSON()); System.out.println("First office location for this vendor:"); spec.withProjectionExpression("VendorInfo.V03.Offices[0]"); System.out.println(table.getItem(spec).toJSON());
El resultado del ejemplo anterior tiene este aspecto.
All vendor info: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}} A single vendor: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}} First office location for a single vendor: {"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
nota
Puede usar el método toJSON
para convertir cualquier elemento (o sus atributos) en una cadena con formato JSON. En el siguiente ejemplo de código se recuperan varios atributos de nivel superior y anidados y se imprimen los resultados como JSON.
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210) .withProjectionExpression("VendorInfo.V01, Title, Price"); Item item = table.getItem(spec); System.out.println(item.toJSON());
El resultado es similar al siguiente.
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
Escritura por lotes: colocación y eliminación de varios elementos
La escritura por lotes se refiere a colocar y eliminar varios elementos en un lote. El método batchWriteItem
permite colocar y eliminar varios elementos de una o varias tablas con una sola llamada. A continuación se indican los pasos para colocar o eliminar varios elementos mediante la API de documentos del AWS SDK for Java.
-
Cree una instancia de la clase
DynamoDB
. -
Cree una instancia de la clase
TableWriteItems
que describe todas las operaciones de colocación y eliminación de una tabla. Si desea escribir en varias tablas en una misma operación de escritura por lotes, debe crear una instancia deTableWriteItems
por cada tabla. -
Llame al método
batchWriteItem
proporcionando los objetosTableWriteItems
que creó en el paso anterior. -
Procese la respuesta. Debe comprobar si en la respuesta se ha devuelto algún elemento de solicitud sin procesar. Esto puede ocurrir si se alcanza la cuota de rendimiento aprovisionado o se produce algún otro error transitorio. Además, DynamoDB limita el tamaño de la solicitud y el número de operaciones que se pueden especificar en ella. Si supera estos límites, DynamoDB rechaza la solicitud. Para obtener más información, consulte Cuotas de tabla, servicio y cuenta en Amazon DynamoDB.
En el siguiente ejemplo de código Java se muestran los pasos anteriores. El ejemplo lleva a cabo una operación batchWriteItem
en dos tablas: Forum
y Thread
. Los objetos TableWriteItems
correspondientes definen las siguientes acciones:
-
Colocar un elemento en la tabla
Forum
. -
Colocar y eliminar un elemento en la tabla
Thread
.
A continuación, el código llama a batchWriteItem
para llevar a cabo la operación.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableWriteItems forumTableWriteItems = new TableWriteItems("Forum") .withItemsToPut( new Item() .withPrimaryKey("Name", "Amazon RDS") .withNumber("Threads", 0)); TableWriteItems threadTableWriteItems = new TableWriteItems("Thread") .withItemsToPut( new Item() .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1") .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value"); BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems); // Code for checking unprocessed items is omitted in this example
Para ver un ejemplo práctico, consulte Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK for Java.
Obtención por lotes: obtención de varios elementos
El método batchGetItem
permite recuperar varios elementos de una o varias tablas. Para recuperar un solo elemento, puede usar el método getItem
.
Siga estos pasos:
-
Cree una instancia de la clase
DynamoDB
. -
Cree una instancia de la clase
TableKeysAndAttributes
que describe una lista de valores de clave principal que se van a recuperar de una tabla. Si desea leer de varias tablas en una misma operación de obtención por lotes, debe crear una instancia deTableKeysAndAttributes
por cada tabla. -
Llame al método
batchGetItem
proporcionando los objetosTableKeysAndAttributes
que creó en el paso anterior.
En el siguiente ejemplo de código Java se muestran los pasos anteriores. El ejemplo recupera dos elementos de la tabla Forum
y tres de la tabla Thread
.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName); threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB","DynamoDB Thread 1", "Amazon DynamoDB","DynamoDB Thread 2", "Amazon S3","S3 Thread 1"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem( forumTableKeysAndAttributes, threadTableKeysAndAttributes); for (String tableName : outcome.getTableItems().keySet()) { System.out.println("Items in table " + tableName); List<Item> items = outcome.getTableItems().get(tableName); for (Item item : items) { System.out.println(item); } }
Especificación de parámetros opcionales
Junto con los parámetros requeridos, puede especificar también otros opcionales cuando use batchGetItem
. Por ejemplo, puede proporcionar una expresión ProjectionExpression
con cada TableKeysAndAttributes
que defina. Esto le permite especificar los atributos que desea recuperar de la tabla.
En el siguiente ejemplo de código se recuperan dos elementos de la tabla Forum
. El parámetro withProjectionExpression
especifica que solamente hay que recuperar el atributo Threads
.
ejemplo
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum") .withProjectionExpression("Threads"); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
Actualización de un elemento
El método updateItem
de un objeto Table
permite actualizar los valores de atributos presentes, agregar atributos nuevos o eliminarlos de un elemento existente.
El método updateItem
se comporta de la siguiente manera:
-
Si un elemento no existe (no hay ningún elemento en la tabla con la clave principal especificada),
updateItem
agrega un elemento nuevo a la tabla. -
Si un elemento ya existe,
updateItem
lleva a cabo la actualización según lo especificado en el parámetroUpdateExpression
.
nota
También es posible actualizar un elemento mediante putItem
. Por ejemplo, si llama a putItem
para agregar un elemento a la tabla pero ya existe uno con la clave principal especificada, putItem
sustituye el elemento completo. Si hay atributos en el elemento existente que no se especifican en la información de entrada, putItem
los elimina del elemento.
En general, recomendamos usar updateItem
siempre que desee modificar atributos de elementos. El método updateItem
solo modifica los atributos del elemento que especifique en la información de entrada, pero deja los demás atributos del elemento tal cual estaban.
Siga estos pasos:
-
Cree una instancia de la clase
Table
para representar la tabla que desea usar. -
Llame al método
updateTable
de la instancia deTable
. Debe especificar la clave principal del elemento que desea recuperar, junto con una expresiónUpdateExpression
que describa los atributos que hay que cambiar y cómo modificarlos.
En el siguiente ejemplo de código Java se muestran las tareas anteriores. El código actualiza un elemento de libro en la tabla ProductCatalog
. Se agrega un nuevo autor al conjunto Authors
y se elimina el atributo ISBN
existente. También se reduce el precio en una unidad.
Se utiliza un mapa ExpressionAttributeValues
en UpdateExpression
. Los marcadores de posición :val1
y :val2
se sustituyen en tiempo de ejecución por los valores reales de Authors
y Price
.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#A", "Authors"); expressionAttributeNames.put("#P", "Price"); expressionAttributeNames.put("#I", "ISBN"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", new HashSet<String>(Arrays.asList("Author YY","Author ZZ"))); expressionAttributeValues.put(":val2", 1); //Price UpdateItemOutcome outcome = table.updateItem( "Id", // key attribute name 101, // key attribute value "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression expressionAttributeNames, expressionAttributeValues);
Especificación de parámetros opcionales
Junto con los parámetros requeridos, puede especificar también parámetros opcionales para el método updateItem
, incluida una condición que debe cumplirse para que se lleve a cabo la actualización. Si la condición especificada no se cumple, AWS SDK for Java genera una excepción ConditionalCheckFailedException
. Por ejemplo, el siguiente ejemplo de código Java actualiza de forma condicional el precio de un elemento de libro a 25. Especifica una expresión ConditionExpression
en la que se indica que el precio solo debe actualizarse si el precio actual es 20.
ejemplo
Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#P", "Price"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", 25); // update Price to 25... expressionAttributeValues.put(":val2", 20); //...but only if existing Price is 20 UpdateItemOutcome outcome = table.updateItem( new PrimaryKey("Id",101), "set #P = :val1", // UpdateExpression "#P = :val2", // ConditionExpression expressionAttributeNames, expressionAttributeValues);
Contador atómico
Puede usar updateItem
para implementar un contador atómico y aumentar o reducir el valor de un atributo existente sin interferir con las demás solicitudes de escritura. Para incrementar un contador atómico, use una expresión UpdateExpression
con la acción set
para sumar un valor numérico a una atributo existente de tipo Number
.
En el siguiente ejemplo se pone en práctica lo anterior y se incrementa el atributo Quantity
en una unidad. También se demuestra cómo usar el parámetro ExpressionAttributeNames
en una expresión UpdateExpression
.
Table table = dynamoDB.getTable("ProductCatalog"); Map<String,String> expressionAttributeNames = new HashMap<String,String>(); expressionAttributeNames.put("#p", "PageCount"); Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", 1); UpdateItemOutcome outcome = table.updateItem( "Id", 121, "set #p = #p + :val", expressionAttributeNames, expressionAttributeValues);
Eliminación de un elemento
El método deleteItem
elimina un elemento de una tabla. Es preciso proporcionar la clave principal del elemento que se desea eliminar.
Siga estos pasos:
-
Cree una instancia del cliente de
DynamoDB
. -
Llame al método
deleteItem
proporcionando la clave del elemento que desea eliminar.
En el siguiente ejemplo de Java se muestran estas tareas.
ejemplo
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); DeleteItemOutcome outcome = table.deleteItem("Id", 101);
Especificación de parámetros opcionales
Puede especificar parámetros opcionales para deleteItem
. Por ejemplo, el siguiente ejemplo de código Java incluye una expresión ConditionExpression
que indica que un elemento de libro de ProductCatalog
solo se puede eliminar si el libro está descatalogado (el atributo InPublication
es false).
ejemplo
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", false); DeleteItemOutcome outcome = table.deleteItem("Id",103, "InPublication = :val", null, // ExpressionAttributeNames - not used in this example expressionAttributeValues);