

# Uso de elementos: Java
<a name="JavaDocumentAPIItemCRUD"></a>

Puede usar la API de documentos del AWS SDK para 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](DynamoDBMapper.md).

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.

**Topics**
+ [Colocación de un elemento](#PutDocumentAPIJava)
+ [Obtención de un elemento](#JavaDocumentAPIGetItem)
+ [Escritura por lotes: colocación y eliminación de varios elementos](#BatchWriteDocumentAPIJava)
+ [Obtención por lotes: obtención de varios elementos](#JavaDocumentAPIBatchGetItem)
+ [Actualización de un elemento](#JavaDocumentAPIItemUpdate)
+ [Eliminación de un elemento](#DeleteMidLevelJava)
+ [Ejemplo: operaciones CRUD mediante la API de documentos de AWS SDK para Java](JavaDocumentAPICRUDExample.md)
+ [Ejemplo: operaciones por lotes mediante la API de documentos de AWS SDK para Java](batch-operation-document-api-java.md)
+ [Ejemplo: control de atributos de tipo binario mediante la API de documentos de AWS SDK para Java](JavaDocumentAPIBinaryTypeExample.md)

## Colocación de un elemento
<a name="PutDocumentAPIJava"></a>

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](#JavaDocumentAPIItemUpdate). 

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To place items into an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client. See the EnhancedPutItem example.
 */
public class PutItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

                Where:
                    tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
                    key - The key used in the Amazon DynamoDB table (for example, Artist).
                    keyval - The key value that represents the item to get (for example, Famous Band).
                    albumTitle - The Album title (for example, AlbumTitle).
                    AlbumTitleValue - The name of the album (for example, Songs About Life ).
                    Awards - The awards column (for example, Awards).
                    AwardVal - The value of the awards (for example, 10).
                    SongTitle - The song title (for example, SongTitle).
                    SongTitleVal - The value of the song title (for example, Happy Day).
                **Warning** This program will  place an item that you specify into a table!
                """;

        if (args.length != 9) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        String albumTitle = args[3];
        String albumTitleValue = args[4];
        String awards = args[5];
        String awardVal = args[6];
        String songTitle = args[7];
        String songTitleVal = args[8];

        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle,
                songTitleVal);
        System.out.println("Done!");
        ddb.close();
    }

    public static void putItemInTable(DynamoDbClient ddb,
            String tableName,
            String key,
            String keyVal,
            String albumTitle,
            String albumTitleValue,
            String awards,
            String awardVal,
            String songTitle,
            String songTitleVal) {

        HashMap<String, AttributeValue> itemValues = new HashMap<>();
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            PutItemResponse response = ddb.putItem(request);
            System.out.println(tableName + " was successfully updated. The request id is "
                    + response.responseMetadata().requestId());

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

------
#### [ Java v1 ]

Siga estos pasos: 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Cree una instancia de la clase `Item` para representar el nuevo elemento. Debe especificar la clave principal del nuevo elemento y sus atributos.

1. Llame al método `putItem` del objeto `Table` utilizando el `Item` que creó en el paso anterior.

En el siguiente ejemplo de código Java se muestran las tareas anteriores. El código escribe un nuevo elemento en la tabla `ProductCatalog`.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

En el ejemplo anterior, el elemento tiene atributos que son escalares (`String`, `Number`, `Boolean`, `Null`), conjuntos (`String Set`) y tipos de documentos (`List`, `Map`).

------

### Especificación de parámetros opcionales
<a name="PutItemJavaDocumentAPIOptions"></a>

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 para 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.

**Example**  

```
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
<a name="PutItemJavaDocumentAPI.JSON"></a>

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.

**Example**  

```
{
    "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
<a name="JavaDocumentAPIGetItem"></a>

Para recuperar un solo elemento, utilice el método `getItem` de un objeto `Table`. Siga estos pasos: 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Llame al método `getItem` de la instancia de `Table`. 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
<a name="GetItemJavaDocumentAPIOptions"></a>

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](HowItWorks.ReadConsistency.md).)

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](Expressions.ProjectionExpressions.md).

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`.

**Example**  

```
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
<a name="GetItemJavaDocumentAPI.JSON"></a>

En la sección [PutItem y documentos JSON](#PutItemJavaDocumentAPI.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
<a name="BatchWriteDocumentAPIJava"></a>

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 para Java.

1. Cree una instancia de la clase `DynamoDB`.

1. 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 de `TableWriteItems` por cada tabla.

1. Llame al método `batchWriteItem` proporcionando los objetos `TableWriteItems` que creó en el paso anterior. 

1. 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 en Amazon DynamoDB](ServiceQuotas.md). 

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 para Java](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite). 

## Obtención por lotes: obtención de varios elementos
<a name="JavaDocumentAPIBatchGetItem"></a>

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: 

1. Cree una instancia de la clase `DynamoDB`.

1. 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 de `TableKeysAndAttributes` por cada tabla.

1. Llame al método `batchGetItem` proporcionando los objetos `TableKeysAndAttributes` 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
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

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`.

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## Actualización de un elemento
<a name="JavaDocumentAPIItemUpdate"></a>

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ámetro `UpdateExpression`.

**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: 

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Llame al método `updateTable` de la instancia de `Table`. Debe especificar la clave principal del elemento que desea recuperar, junto con una expresión `UpdateExpression` 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
<a name="UpdateItemJavaDocumentAPIOptions"></a>

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 para 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.

**Example**  

```
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
<a name="AtomicCounterJavaDocumentAPI"></a>

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
<a name="DeleteMidLevelJava"></a>

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: 

1. Cree una instancia del cliente de `DynamoDB`.

1. Llame al método `deleteItem` proporcionando la clave del elemento que desea eliminar. 

En el siguiente ejemplo de Java se muestran estas tareas.

**Example**  

```
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
<a name="DeleteItemJavaDocumentAPIOptions"></a>

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).

**Example**  

```
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);
```

# Ejemplo: operaciones CRUD mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPICRUDExample"></a>

En el siguiente ejemplo de código se ilustran las operaciones CRUD en un elemento de Amazon DynamoDB. En el ejemplo se crea un elemento, se recupera, se llevan a cabo varias actualizaciones y, por último, se elimina.

**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](DynamoDBMapper.md).

**nota**  
En este ejemplo de código se supone que ya ha cargado datos en DynamoDB para su cuenta siguiendo las instrucciones de la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md).  
Para obtener instrucciones paso a paso acerca de cómo ejecutar el siguiente ejemplo, consulte [Ejemplos de código Java](CodeSamples.Java.md).

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;

public class DocumentAPIItemCRUDExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "ProductCatalog";

    public static void main(String[] args) throws IOException {

        createItems();

        retrieveItem();

        // Perform various updates.
        updateMultipleAttributes();
        updateAddNewAttribute();
        updateExistingAttributeConditionally();

        // Delete the item.
        deleteItem();

    }

    private static void createItems() {

        Table table = dynamoDB.getTable(tableName);
        try {

            Item item = new Item().withPrimaryKey("Id", 120).withString("Title", "Book 120 Title")
                    .withString("ISBN", "120-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author12", "Author22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", false).withString("ProductCategory", "Book");
            table.putItem(item);

            item = new Item().withPrimaryKey("Id", 121).withString("Title", "Book 121 Title")
                    .withString("ISBN", "121-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", true).withString("ProductCategory", "Book");
            table.putItem(item);

        } catch (Exception e) {
            System.err.println("Create items failed.");
            System.err.println(e.getMessage());

        }
    }

    private static void retrieveItem() {
        Table table = dynamoDB.getTable(tableName);

        try {

            Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null);

            System.out.println("Printing item after retrieving it....");
            System.out.println(item.toJSONPretty());

        } catch (Exception e) {
            System.err.println("GetItem failed.");
            System.err.println(e.getMessage());
        }

    }

    private static void updateAddNewAttribute() {
        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 121)
                    .withUpdateExpression("set #na = :val1").withNameMap(new NameMap().with("#na", "NewAttribute"))
                    .withValueMap(new ValueMap().withString(":val1", "Some value"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after adding new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to add new attribute in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void updateMultipleAttributes() {

        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withUpdateExpression("add #a :val1 set #na=:val2")
                    .withNameMap(new NameMap().with("#a", "Authors").with("#na", "NewAttribute"))
                    .withValueMap(
                            new ValueMap().withStringSet(":val1", "Author YY", "Author ZZ").withString(":val2",
                                    "someValue"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after multiple attribute update...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to update multiple attributes in " + tableName);
            System.err.println(e.getMessage());

        }
    }

    private static void updateExistingAttributeConditionally() {

        Table table = dynamoDB.getTable(tableName);

        try {

            // Specify the desired price (25.00) and also the condition (price =
            // 20.00)

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withReturnValues(ReturnValue.ALL_NEW).withUpdateExpression("set #p = :val1")
                    .withConditionExpression("#p = :val2").withNameMap(new NameMap().with("#p", "Price"))
                    .withValueMap(new ValueMap().withNumber(":val1", 25).withNumber(":val2", 20));

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after conditional update to new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error updating item in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void deleteItem() {

        Table table = dynamoDB.getTable(tableName);

        try {

            DeleteItemSpec deleteItemSpec = new DeleteItemSpec().withPrimaryKey("Id", 120)
                    .withConditionExpression("#ip = :val").withNameMap(new NameMap().with("#ip", "InPublication"))
                    .withValueMap(new ValueMap().withBoolean(":val", false)).withReturnValues(ReturnValue.ALL_OLD);

            DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec);

            // Check the response.
            System.out.println("Printing item that was deleted...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error deleting item in " + tableName);
            System.err.println(e.getMessage());
        }
    }
}
```

# Ejemplo: operaciones por lotes mediante la API de documentos de AWS SDK para Java
<a name="batch-operation-document-api-java"></a>

En esta sección se proporcionan ejemplos de operaciones de escritura y obtención por lote en Amazon DynamoDB mediante la API de documentos de AWS SDK para Java.

**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](DynamoDBMapper.md).

**Topics**
+ [Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK para Java](#JavaDocumentAPIBatchWrite)
+ [Ejemplo: operación de obtención por lotes mediante la API de documentos de AWS SDK para Java](#JavaDocumentAPIBatchGet)

## Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBatchWrite"></a>

En el siguiente ejemplo de código Java se usa el método `batchWriteItem` para llevar a cabo las siguientes operaciones de colocación y eliminación:
+ Colocar un elemento en la tabla `Forum`.
+ Colocar un elemento y eliminar un elemento de la tabla `Thread`. 

Al crear la solicitud de escritura por lotes, puede especificar cualquier cantidad de solicitudes de colocación y eliminación en una o varias tablas. Sin embargo, `batchWriteItem` limita el tamaño de una solicitud de escritura por lotes y el número de operaciones de colocación y eliminación que se pueden llevar a cabo en una misma operación de escritura por lotes. Si la solicitud supera estos límites, se rechaza la solicitud. Si la tabla no cuenta con suficiente desempeño provisionado para atender esta solicitud, los elementos de solicitud sin procesar se devuelven en la respuesta. 

En el siguiente ejemplo se comprueba la respuesta para saber si contiene elementos de solicitud sin transformar. En caso afirmativo, entra en bucle y vuelve a enviar la solicitud `batchWriteItem` con elementos sin procesar. Si ha seguido los ejemplos de esta guía, ya debería haber creado las tablas `Forum` y `Thread`. También puede crear estas tablas y cargar los ejemplos de datos mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos de código Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableWriteItems;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;

public class DocumentAPIBatchWrite {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {

        writeMultipleItemsBatchWrite();

    }

    private static void writeMultipleItemsBatchWrite() {
        try {

            // Add a new item to Forum
            TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) // Forum
                    .withItemsToPut(new Item().withPrimaryKey("Name", "Amazon RDS").withNumber("Threads", 0));

            // Add a new item, and delete an existing item, from Thread
            // This table has a partition key and range key, so need to specify
            // both of them
            TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName)
                    .withItemsToPut(
                            new Item().withPrimaryKey("ForumName", "Amazon RDS", "Subject", "Amazon RDS Thread 1")
                                    .withString("Message", "ElastiCache Thread 1 message")
                                    .withStringSet("Tags", new HashSet<String>(Arrays.asList("cache", "in-memory"))))
                    .withHashAndRangeKeysToDelete("ForumName", "Subject", "Amazon S3", "S3 Thread 100");

            System.out.println("Making the request.");
            BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

            do {

                // Check for unprocessed keys which could happen if you exceed
                // provisioned throughput

                Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems();

                if (outcome.getUnprocessedItems().size() == 0) {
                    System.out.println("No unprocessed items found");
                } else {
                    System.out.println("Retrieving the unprocessed items");
                    outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems);
                }

            } while (outcome.getUnprocessedItems().size() > 0);

        } catch (Exception e) {
            System.err.println("Failed to retrieve items: ");
            e.printStackTrace(System.err);
        }

    }

}
```

## Ejemplo: operación de obtención por lotes mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBatchGet"></a>

En el siguiente ejemplo de código Java se usa el método `batchGetItem` para recuperar varios elementos de las tablas `Forum` y `Thread`. La solicitud `BatchGetItemRequest` especifica los nombres de las tablas y una lista de claves para cada elemento que se desea obtener. En el ejemplo se procesa la respuesta y se imprimen los elementos recuperados.

**nota**  
En este ejemplo de código se supone que ya ha cargado datos en DynamoDB para su cuenta siguiendo las instrucciones de la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md).  
Para obtener instrucciones paso a paso acerca de cómo ejecutar el siguiente ejemplo, consulte [Ejemplos de código Java](CodeSamples.Java.md).

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

public class DocumentAPIBatchGet {
    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {
        retrieveMultipleItemsBatchGet();
    }

    private static void retrieveMultipleItemsBatchGet() {

        try {

            TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
            // Add a partition key
            forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB");

            TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
            // Add a partition key and a sort key
            threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB",
                    "DynamoDB Thread 1", "Amazon DynamoDB", "DynamoDB Thread 2", "Amazon S3", "S3 Thread 1");

            System.out.println("Making the request.");

            BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes,
                    threadTableKeysAndAttributes);

            Map<String, KeysAndAttributes> unprocessed = null;

            do {
                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.toJSONPretty());
                    }
                }

                // Check for unprocessed keys which could happen if you exceed
                // provisioned
                // throughput or reach the limit on response size.
                unprocessed = outcome.getUnprocessedKeys();

                if (unprocessed.isEmpty()) {
                    System.out.println("No unprocessed keys found");
                } else {
                    System.out.println("Retrieving the unprocessed keys");
                    outcome = dynamoDB.batchGetItemUnprocessed(unprocessed);
                }

            } while (!unprocessed.isEmpty());

        } catch (Exception e) {
            System.err.println("Failed to retrieve items.");
            System.err.println(e.getMessage());
        }

    }

}
```

# Ejemplo: control de atributos de tipo binario mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBinaryTypeExample"></a>

En el siguiente ejemplo se ilustra cómo se controlan los atributos de tipo Binary. Además, se agrega un elemento a la tabla `Reply`. El elemento incluye un atributo de tipo Binary (`ExtendedMessage`) que almacena datos comprimidos. A continuación, en el ejemplo se recupera el elemento y se imprimen todos los valores de los atributos. Con fines ilustrativos, el ejemplo usa la clase `GZIPOutputStream` para comprimir un ejemplo de secuencia y asignársela al atributo `ExtendedMessage`. Cuando se recupera el atributo binario, se descomprime mediante la clase `GZIPInputStream`. 

**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](DynamoDBMapper.md).

Si ha seguido la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md), seguramente habrá creado ya la tabla `Reply`. También puede crear esta tabla mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos de código Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec;

public class DocumentAPIItemBinaryExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public static void main(String[] args) throws IOException {
        try {

            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";

            dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            String replyDateTime = dateFormatter.format(new Date());

            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);

            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);

            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);
            e.printStackTrace(System.err);
        }
    }

    public static void createItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";

        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());

        table.putItem(new Item().withPrimaryKey("Id", threadId).withString("ReplyDateTime", replyDateTime)
                .withString("Message", "Long message follows").withBinary("ExtendedMessage", compressedMessage)
                .withString("PostedBy", "User A"));
    }

    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)
                .withConsistentRead(true);

        Item item = table.getItem(spec);

        // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));

        System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: "
                + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n"
                + " Message: "
                + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    }

    public static void deleteItem(String threadId, String replyDateTime) {

        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    }

    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        os.write(input.getBytes("UTF-8"));
        os.close();
        baos.close();
        byte[] compressedBytes = baos.toByteArray();

        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling
        // ByteBuffer.wrap(compressedBytes);
        // However, the longer form below shows the importance of resetting the
        // position of the buffer
        // back to the beginning of the buffer if you are writing bytes directly
        // to it, since the SDK
        // will consider only the bytes after the current position when sending
        // data to DynamoDB.
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer
                            // to the beginning
        return buffer;
    }

    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);

        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length = is.read(buffer, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        }

        String result = new String(baos.toByteArray(), "UTF-8");

        is.close();
        baos.close();
        bais.close();

        return result;
    }
}
```