

# Java 1.x: DynamoDBMapper
<a name="DynamoDBMapper"></a>

**nota**  
El SDK para Java tiene dos versiones: 1.x y 2.x. El 12 de enero de 2024 se [anunció](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) el fin de soporte de la versión 1.x. Lo hará y está previsto que se dé por terminado el 31 de diciembre de 2025. Para nuevos desarrollos, recomendamos encarecidamente el uso de 2.x.

El AWS SDK para Java proporciona la clase `DynamoDBMapper` que permite mapear las clases del lado del cliente a las tablas de Amazon DynamoDB. Para usar `DynamoDBMapper`, se define la relación entre los elementos de una tabla de DynamoDB y sus instancias de objetos correspondientes en el código. La clase `DynamoDBMapper` 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.

**Topics**
+ [Clase DynamoDBMapper](DynamoDBMapper.Methods.md)
+ [Tipos de datos compatibles con asignador DynamoDBMapper para Java](DynamoDBMapper.DataTypes.md)
+ [Anotaciones de Java para DynamoDB](DynamoDBMapper.Annotations.md)
+ [Ajustes de configuración opcionales para DynamoDBMapper](DynamoDBMapper.OptionalConfig.md)
+ [DynamoDB y bloqueo positivo con el número de versión](DynamoDBMapper.OptimisticLocking.md)
+ [Asignación de datos arbitrarios en DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md)
+ [Ejemplos de DynamoDBMapper](DynamoDBMapper.Examples.md)

**nota**  
La clase `DynamoDBMapper` no permite crear, actualizar o eliminar tablas. Para realizar estas tareas, utilice la interfaz de bajo nivel del SDK para Java en su lugar.

El SDK para Java proporciona un conjunto de tipos de anotación para que pueda mapear las clases de tablas. Por ejemplo, tomemos una tabla `ProductCatalog` cuya clave de partición es `Id`. 

```
ProductCatalog(Id, ...)
```

Puede mapear una clase de la aplicación cliente a la tabla `ProductCatalog` tal y como se muestra en el siguiente código Java. En este código se define un objeto Java estándar (POJO) denominado `CatalogItem` que utiliza anotaciones para mapear campos de objetos a nombres de atributos de DynamoDB.

**Example**  

```
package com.amazonaws.codesamples;

import java.util.Set;

import software.amazon.dynamodb.datamodeling.DynamoDBAttribute;
import software.amazon.dynamodb.datamodeling.DynamoDBHashKey;
import software.amazon.dynamodb.datamodeling.DynamoDBIgnore;
import software.amazon.dynamodb.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) {this.id = id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN; }

    @DynamoDBAttribute(attributeName="Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp; }
    public void setSomeProp(String someProp) { this.someProp = someProp; }
}
```

En el código anterior, la anotación `@DynamoDBTable` mapea la clase `CatalogItem` a la tabla `ProductCatalog`. Puede almacenar instancias de clases individuales como los elementos de la tabla. En la definición de clase, la anotación `@DynamoDBHashKey` mapea la propiedad `Id` a la clave principal. 

De forma predeterminada, las propiedades de la clase se mapean a los atributos de la tabla que tienen el mismo nombre. Las propiedades `Title` e `ISBN` se mapean a los atributos de la tabla que tienen el mismo nombre. 

La anotación `@DynamoDBAttribute` es opcional cuando el nombre del atributo de DynamoDB coincide con el nombre de la propiedad declarada en la clase. Si son distintos, use esta anotación con el parámetro `attributeName` para especificar qué atributo de DynamoDB se corresponde con esta propiedad. 

En el ejemplo anterior, la anotación `@DynamoDBAttribute` se agrega a cada propiedad para garantizar que los nombres de las propiedades coincidan exactamente con las tablas creadas en un paso anterior y para mantener la coherencia con los nombres de atributo utilizados en otros ejemplos de código de esta guía. 

La definición de clase puede tener propiedades que no se mapeen a ningún atributo de la tabla. Estas propiedades se identifican agregándoles la anotación `@DynamoDBIgnore`. En el ejemplo anterior, la propiedad `SomeProp` se ha marcado con la anotación `@DynamoDBIgnore`. Al cargar una instancia de `CatalogItem` en la tabla, la instancia de `DynamoDBMapper` no incluye la propiedad `SomeProp`. Tampoco el mapeador devuelve este atributo cuando se recupera un elemento de la tabla. 

Después de haber definido la clase de mapeo, puede usar métodos `DynamoDBMapper` para escribir una instancia de esa clase en un elemento correspondiente de la tabla `Catalog`. En el siguiente ejemplo de código se muestra esta técnica.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapper mapper = new DynamoDBMapper(client);

CatalogItem item = new CatalogItem();
item.setId(102);
item.setTitle("Book 102 Title");
item.setISBN("222-2222222222");
item.setBookAuthors(new HashSet<String>(Arrays.asList("Author 1", "Author 2")));
item.setSomeProp("Test");

mapper.save(item);
```

En el siguiente ejemplo de código se muestra cómo recuperar el elemento y obtener acceso a algunos de sus atributos.

```
CatalogItem partitionKey = new CatalogItem();

partitionKey.setId(102);
DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
    .withHashKeyValues(partitionKey);

List<CatalogItem> itemList = mapper.query(CatalogItem.class, queryExpression);

for (int i = 0; i < itemList.size(); i++) {
    System.out.println(itemList.get(i).getTitle());
    System.out.println(itemList.get(i).getBookAuthors());
}
```

`DynamoDBMapper` ofrece un modo natural e intuitivo de usar los datos de DynamoDB en Java. También ofrece varias características integradas, tales como el bloqueo optimista, las transacciones ACID, la generación automática de valores de claves de partición y de orden y el control de versiones de objetos.

# Clase DynamoDBMapper
<a name="DynamoDBMapper.Methods"></a>



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](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) en la *Referencia de la API de AWS SDK para Java*.

**Topics**
+ [save](#DynamoDBMapper.Methods.save)
+ [carga](#DynamoDBMapper.Methods.load)
+ [eliminar](#DynamoDBMapper.Methods.delete)
+ [consulta](#DynamoDBMapper.Methods.query)
+ [queryPage](#DynamoDBMapper.Methods.queryPage)
+ [scan](#DynamoDBMapper.Methods.scan)
+ [scanPage](#DynamoDBMapper.Methods.scanPage)
+ [parallelScan](#DynamoDBMapper.Methods.parallelScan)
+ [batchSave](#DynamoDBMapper.Methods.batchSave)
+ [batchLoad](#DynamoDBMapper.Methods.batchLoad)
+ [batchDelete](#DynamoDBMapper.Methods.batchDelete)
+ [batchWrite](#DynamoDBMapper.Methods.batchWrite)
+ [transactionWrite](#DynamoDBMapper.Methods.transactionWrite)
+ [transactionLoad](#DynamoDBMapper.Methods.transactionLoad)
+ [count](#DynamoDBMapper.Methods.count)
+ [generateCreateTableRequest](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [createS3Link](#DynamoDBMapper.Methods.createS3Link)
+ [getS3ClientCache](#DynamoDBMapper.Methods.getS3ClientCache)

## save
<a name="DynamoDBMapper.Methods.save"></a>

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 [DynamoDB y bloqueo positivo con el número de versión](DynamoDBMapper.OptimisticLocking.md).

## carga
<a name="DynamoDBMapper.Methods.load"></a>

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

## eliminar
<a name="DynamoDBMapper.Methods.delete"></a>

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 [DynamoDB y bloqueo positivo con el número de versión](DynamoDBMapper.OptimisticLocking.md). 

## consulta
<a name="DynamoDBMapper.Methods.query"></a>

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.

**Example**  

```
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 , ya que los índices secundarios globales admiten las lecturas consistentes finales, pero no las de consistencia alta `withConsistentRead(false)`.

```
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
<a name="DynamoDBMapper.Methods.queryPage"></a>

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
<a name="DynamoDBMapper.Methods.scan"></a>

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.

**Example**  

```
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](#DynamoDBMapper.Methods.query) 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
<a name="DynamoDBMapper.Methods.scanPage"></a>

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
<a name="DynamoDBMapper.Methods.parallelScan"></a>

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

## batchSave
<a name="DynamoDBMapper.Methods.batchSave"></a>

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
<a name="DynamoDBMapper.Methods.batchLoad"></a>

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
<a name="DynamoDBMapper.Methods.batchDelete"></a>

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
<a name="DynamoDBMapper.Methods.batchWrite"></a>

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
<a name="DynamoDBMapper.Methods.transactionWrite"></a>

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](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors). 

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](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

**nota**  
 Este método no admite lo siguiente:  
[DynamoDBMapperConfig.SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html).

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
<a name="DynamoDBMapper.Methods.transactionLoad"></a>

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](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors). 

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](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

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
<a name="DynamoDBMapper.Methods.count"></a>

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

## generateCreateTableRequest
<a name="DynamoDBMapper.Methods.generateCreateTableRequest"></a>

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

## createS3Link
<a name="DynamoDBMapper.Methods.createS3Link"></a>

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 amzn-s3-demo-bucket = "amzn-s3-demo-bucket";
String myS3Key = "productImages/book_150_cover.jpg";
item.setProductImage(mapper.createS3Link(amzn-s3-demo-bucket, 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`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html).

## getS3ClientCache
<a name="DynamoDBMapper.Methods.getS3ClientCache"></a>

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.

# Tipos de datos compatibles con asignador DynamoDBMapper para Java
<a name="DynamoDBMapper.DataTypes"></a>

En esta sección se describen los tipos de datos arbitrarios, las colecciones y los tipos de datos de Java primitivos compatibles en Amazon DynamoDB. 

Amazon DynamoDB admite los siguientes tipos de datos y clases contenedoras Java primitivos. 
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (como una cadena [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) con precisión de milisegundos, convertida a UTC)
+ `Calendar` (como una cadena [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) con precisión de milisegundos, convertida a UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**nota**  
Para obtener más información sobre las reglas de asignación de nombres de DynamoDB y los distintos tipos de datos admitidos, consulte [Tipos de datos y reglas de nomenclatura admitidos en Amazon DynamoDB](HowItWorks.NamingRulesDataTypes.md). 
DynamoDBMapper admite valores binarios vacíos.
Los valores de cadena vacíos son compatibles con AWS SDK for Java 2.x.  
En AWS SDK para Java 1.x, DynamoDBMapper admite leer valores de atributo de cadena vacíos; sin embargo, no escribirá valores de atributo de cadena vacíos, ya que estos atributos se eliminan de la solicitud.

DynamoDB admite los tipos de colecciones de Java [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html), [List](http://docs.oracle.com/javase/6/docs/api/java/util/List.html) y [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html). En la tabla siguiente se resume el mapeo de estos tipos de Java a los tipos de DynamoDB.


****  

| Tipo de Java | Tipo DynamoDB | 
| --- | --- | 
|  Todos los tipos de números  |  `N` (tipo Number)  | 
|  Cadenas  |  `S` (tipo String)   | 
|  Booleano  |  `BOOL` (tipo booleano), 0 o 1.  | 
|  ByteBuffer  |  `B` (tipo Binary)  | 
|  Date  |  `S` (tipo String). Los valores Date se almacenan como cadenas con formato ISO-8601.  | 
| Tipos de colección [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) |  `SS` (tipo String Set), `NS` (tipo Number Set) o `BS` (tipo Binary Set)  | 

 La interfaz `DynamoDBTypeConverter` permite mapear sus propios tipos de datos arbitrarios a un tipo de datos que sea compatible de forma nativa con DynamoDB. Para obtener más información, consulte [Asignación de datos arbitrarios en DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md). 

# Anotaciones de Java para DynamoDB
<a name="DynamoDBMapper.Annotations"></a>

En esta sección se describen las anotaciones que están disponibles para mapear las clases y las propiedades a las tablas y los atributos en Amazon DynamoDB.

Para obtener la documentación de Javadoc correspondiente, consulte [Annotation Types Summary (Resumen de tipos de anotaciones)](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html) en la [Referencia de la API AWS SDK para Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

**nota**  
En las anotaciones siguientes, solo son obligatorias `DynamoDBTable` y `DynamoDBHashKey`. 

**Topics**
+ [DynamoDBAttribute](#DynamoDBMapper.Annotations.DynamoDBAttribute)
+ [DynamoDBAutoGeneratedKey](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey)
+ [DynamoDBAutoGeneratedTimestamp](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp)
+ [DynamoDBDocument](#DynamoDBMapper.Annotations.DynamoDBDocument)
+ [DynamoDBHashKey](#DynamoDBMapper.Annotations.DynamoDBHashKey)
+ [DynamoDBIgnore](#DynamoDBMapper.Annotations.DynamoDBIgnore)
+ [DynamoDBIndexHashKey](#DynamoDBMapper.Annotations.DynamoDBIndexHashKey)
+ [DynamoDBIndexRangeKey](#DynamoDBMapper.Annotations.DynamoDBIndexRangeKey)
+ [DynamoDBRangeKey](#DynamoDBMapper.Annotations.DynamoDBRangeKey)
+ [DynamoDBTable](#DynamoDBMapper.Annotations.DynamoDBTable)
+ [DynamoDBTypeConverted](#DynamoDBMapper.Annotations.DynamoDBTypeConverted)
+ [DynamoDBTyped](#DynamoDBMapper.Annotations.DynamoDBTyped)
+ [DynamoDBVersionAttribute](#DynamoDBMapper.Annotations.DynamoDBVersionAttribute)

## DynamoDBAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBAttribute"></a>

Mapea una propiedad a un atributo de tabla. De forma predeterminada, cada propiedad de clase se mapea a un atributo de elemento con el mismo nombre. Sin embargo, si los nombres no son iguales, puede utilizar esta anotación para mapear una propiedad al atributo. En el siguiente fragmento de Java, `DynamoDBAttribute` mapea la propiedad `BookAuthors` al nombre de atributo `Authors` de la tabla.

```
@DynamoDBAttribute(attributeName = "Authors")
public List<String> getBookAuthors() { return BookAuthors; }
public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; }
```

`DynamoDBMapper` utiliza `Authors` como nombre de atributo al guardar el objeto en la tabla. 

## DynamoDBAutoGeneratedKey
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey"></a>

Marca una propiedad de clave de partición o de clave de ordenación como generada automáticamente. `DynamoDBMapper` genera un [UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html) aleatorio al guardar estos atributos. Solo se pueden marcar propiedades de tipo String como claves generadas automáticamente. 

El siguiente ejemplo muestra el uso de claves generadas automáticamente.

```
@DynamoDBTable(tableName="AutoGeneratedKeysExample")
public class AutoGeneratedKeys {
    private String id;
    private String payload;

    @DynamoDBHashKey(attributeName = "Id")
    @DynamoDBAutoGeneratedKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    @DynamoDBAttribute(attributeName="payload")
    public String getPayload() { return this.payload; }
    public void setPayload(String payload) { this.payload = payload; }

    public static void saveItem() {
        AutoGeneratedKeys obj = new AutoGeneratedKeys();
        obj.setPayload("abc123");

        // id field is null at this point
        DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
        mapper.save(obj);

        System.out.println("Object was saved with id " + obj.getId());
    }
}
```

## DynamoDBAutoGeneratedTimestamp
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp"></a>

Genera automáticamente una marca de tiempo.

```
@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.ALWAYS)
public Date getLastUpdatedDate() { return lastUpdatedDate; }
public void setLastUpdatedDate(Date lastUpdatedDate) { this.lastUpdatedDate = lastUpdatedDate; }
```

La estrategia de generación automática también puede definirse si se proporciona un atributo de estrategia. El valor predeterminado es `ALWAYS`.

## DynamoDBDocument
<a name="DynamoDBMapper.Annotations.DynamoDBDocument"></a>

Indica que una clase se puede serializar como un documento de Amazon DynamoDB.

Por ejemplo, supongamos que desea mapear un documento JSON a un atributo de DynamoDB de tipo Map (`M`). En el siguiente ejemplo de código se define un elemento que contiene un atributo anidado (Pictures) de tipo Map.

```
public class ProductCatalogItem {

    private Integer id;  //partition key
    private Pictures pictures;
    /* ...other attributes omitted... */

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id;}
    public void setId(Integer id) {this.id = id;}

    @DynamoDBAttribute(attributeName="Pictures")
    public Pictures getPictures() { return pictures;}
    public void setPictures(Pictures pictures) {this.pictures = pictures;}

    // Additional properties go here.

    @DynamoDBDocument
    public static class Pictures {
        private String frontView;
        private String rearView;
        private String sideView;

        @DynamoDBAttribute(attributeName = "FrontView")
        public String getFrontView() { return frontView; }
        public void setFrontView(String frontView) { this.frontView = frontView; }

        @DynamoDBAttribute(attributeName = "RearView")
        public String getRearView() { return rearView; }
        public void setRearView(String rearView) { this.rearView = rearView; }

        @DynamoDBAttribute(attributeName = "SideView")
        public String getSideView() { return sideView; }
        public void setSideView(String sideView) { this.sideView = sideView; }

     }
}
```

A continuación, podría guardar un nuevo elemento `ProductCatalog`, con `Pictures`, tal como se muestra en el siguiente ejemplo.

```
ProductCatalogItem item = new ProductCatalogItem();

Pictures pix = new Pictures();
pix.setFrontView("http://example.com/products/123_front.jpg");
pix.setRearView("http://example.com/products/123_rear.jpg");
pix.setSideView("http://example.com/products/123_left_side.jpg");
item.setPictures(pix);

item.setId(123);

mapper.save(item);
```

El elemento `ProductCatalog` resultante tendría este aspecto (en formato JSON).

```
{
  "Id" : 123
  "Pictures" : {
    "SideView" : "http://example.com/products/123_left_side.jpg",
    "RearView" : "http://example.com/products/123_rear.jpg",
    "FrontView" : "http://example.com/products/123_front.jpg"
  }
}
```

## DynamoDBHashKey
<a name="DynamoDBMapper.Annotations.DynamoDBHashKey"></a>

Mapea una propiedad de clase a la clave de partición de la tabla. La propiedad debe ser un escalar de tipo String, Number o Binary. La propiedad no puede ser un tipo de colección. 

Supongamos que tenemos una tabla, `ProductCatalog`, cuya clave principal es `Id`. En el siguiente código Java se define una clase `CatalogItem` y se mapea su propiedad `Id` a la clave principal de la tabla `ProductCatalog` utilizando la etiqueta `@DynamoDBHashKey`.

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
    private Integer Id;
   @DynamoDBHashKey(attributeName="Id")
   public Integer getId() {
        return Id;
   }
   public void setId(Integer Id) {
        this.Id = Id;
   }
   // Additional properties go here.
}
```

## DynamoDBIgnore
<a name="DynamoDBMapper.Annotations.DynamoDBIgnore"></a>

Indica a la instancia `DynamoDBMapper` que la propiedad asociada debe pasarse por alto. Al guardar datos en la tabla, `DynamoDBMapper` no guarda esta propiedad en la tabla.

 Se aplica al método getter o al campo de clase de una propiedad sin modelar. Si la anotación se aplica directamente al campo de clase, los métodos getter y setter correspondientes deben declararse en la misma clase. 

## DynamoDBIndexHashKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexHashKey"></a>

Mapea una propiedad de clase a la clave de partición de un índice secundario global. La propiedad debe ser un escalar de tipo String, Number o Binary. La propiedad no puede ser un tipo de colección. 

Use esta anotación si necesita `Query` un índice secundario global. Debe especificar el nombre de índice (`globalSecondaryIndexName`). Si el nombre de la propiedad de clase es distinto de la clave de partición del índice, también deberá especificar el nombre de ese atributo de índice (`attributeName`).

## DynamoDBIndexRangeKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexRangeKey"></a>

Mapea una propiedad de clase a la clave de ordenación de un índice secundario global o un índice secundario local. La propiedad debe ser un escalar de tipo String, Number o Binary. La propiedad no puede ser un tipo de colección. 

Use esta anotación si tiene que utilizar una operación `Query` en un índice secundario local o un índice secundario global y desea refinar los resultados mediante la clave de ordenación del índice. Debe especificar el nombre de índice (`globalSecondaryIndexName` o `localSecondaryIndexName`). Si el nombre de la propiedad de clase es distinto de la clave de ordenación del índice, también deberá especificar el nombre de ese atributo de índice (`attributeName`).

## DynamoDBRangeKey
<a name="DynamoDBMapper.Annotations.DynamoDBRangeKey"></a>

Mapea una propiedad de clase a la clave de ordenación de la tabla. La propiedad debe ser un escalar de tipo String, Number o Binary. No puede ser un tipo de colección. 

Si la clave principal es compuesta (clave de partición y clave de ordenación), puede utilizar esta etiqueta para mapear el campo de clase a la clave de ordenación. Por ejemplo, supongamos que tenemos una tabla `Reply` en la que se almacenan las respuestas de las conversaciones de un foro. Cada conversación puede tener muchas respuestas. La clave principal de esta tabla consta de `ThreadId` y `ReplyDateTime`. `ThreadId` es la clave de partición y `ReplyDateTime` es la de orden. 

En el siguiente código Java se define una clase `Reply` y se mapea a la tabla `Reply`. Se utilizan las etiquetas `@DynamoDBHashKey` y `@DynamoDBRangeKey` para identificar las propiedades de clase mapeadas a la clave principal.

```
@DynamoDBTable(tableName="Reply")
public class Reply {
    private Integer id;
    private String replyDateTime;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }

    @DynamoDBRangeKey(attributeName="ReplyDateTime")
    public String getReplyDateTime() { return replyDateTime; }
    public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; }

   // Additional properties go here.
}
```

## DynamoDBTable
<a name="DynamoDBMapper.Annotations.DynamoDBTable"></a>

Identifica la tabla de destino de DynamoDB. Por ejemplo, en el siguiente código Java se define una clase `Developer` y se mapea a la tabla `People` en DynamoDB. 

```
@DynamoDBTable(tableName="People")
public class Developer { ...}
```

La anotación `@DynamoDBTable` se puede heredar. Cualquier nueva clase que herede de la clase `Developer` también se mapea a la tabla `People`. Por ejemplo, supongamos que hemos creado una clase `Lead` que hereda de la clase `Developer`. Dado que ha mapeado la clase `Developer` a la tabla `People`, los objetos de la clase `Lead` también se almacenan en la misma tabla.

La anotación `@DynamoDBTable` también se puede anular. Cualquier nueva clase que herede de la clase `Developer` de forma predeterminada se mapea a la misma tabla `People`. Sin embargo, puede anular este mapeo predeterminado. Por ejemplo, si crea una clase que hereda de la clase `Developer`, puede mapearla explícitamente a otra tabla agregando la anotación `@DynamoDBTable`, como se muestra en el siguiente ejemplo de código Java.

```
@DynamoDBTable(tableName="Managers")
public class Manager extends Developer { ...}
```

## DynamoDBTypeConverted
<a name="DynamoDBMapper.Annotations.DynamoDBTypeConverted"></a>

Anotación para marcar que una propiedad usa un convertidor de tipos personalizado. Se puede usar una anotación definida por el usuario para pasar propiedades adicionales al convertidor `DynamoDBTypeConverter`. 

 La interfaz `DynamoDBTypeConverter` permite mapear sus propios tipos de datos arbitrarios a un tipo de datos que sea compatible de forma nativa con DynamoDB. Para obtener más información, consulte [Asignación de datos arbitrarios en DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md).

## DynamoDBTyped
<a name="DynamoDBMapper.Annotations.DynamoDBTyped"></a>

Anotación para anular el vínculo de tipo de atributo estándar. Los tipos estándar no requieren la anotación si se les aplica el vínculo de atributo predeterminado para ese tipo. 

## DynamoDBVersionAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBVersionAttribute"></a>

Identifica una propiedad de clase para almacenar un número de versión de bloqueo optimista. `DynamoDBMapper` asigna un número de versión a esta propiedad cuando guarda un elemento nuevo e incrementa su valor cada vez que se actualiza el elemento. Solo se admiten escalares de tipo Number. Para obtener más información sobre los tipos de datos de , consulte [Tipos de datos](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes). Para obtener más información sobre el control de versiones, consulte [DynamoDB y bloqueo positivo con el número de versión](DynamoDBMapper.OptimisticLocking.md).

# Ajustes de configuración opcionales para DynamoDBMapper
<a name="DynamoDBMapper.OptionalConfig"></a>

Al crear una instancia de `DynamoDBMapper`, presenta algunos comportamientos predeterminados que se pueden anular mediante la clase `DynamoDBMapperConfig`. 

En el siguiente fragmento de código se crea una clase `DynamoDBMapper` con ajustes personalizados:

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
        .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER)
        .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
        .withTableNameOverride(null)
        .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
    .build();

DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);
```

Para obtener más información, consulte [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html) en la [Referencia de la API de AWS SDK para Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

Puede usar los argumentos siguientes para una instancia de `DynamoDBMapperConfig`:
+ Un valor de enumeración `DynamoDBMapperConfig.ConsistentReads`:
  + `EVENTUAL`: la instancia de mapeador utiliza una solicitud de lectura consistente final.
  + `CONSISTENT`: la instancia de mapeador utiliza una solicitud de lectura de consistencia alta. Puede usar este ajuste opcional con las operaciones `load`, `query` o `scan` operations. Las lecturas de consistencia alta afectan al rendimiento y a la facturación; consulte la [página detalles del producto](https://aws.amazon.com/dynamodb) de DynamoDB para obtener más información.

  Si no especifica un ajuste de consistencia de lectura para la instancia de mapeador, el valor predeterminado es `EVENTUAL`.
**nota**  
Este valor se aplica en las operaciones `query`, `querypage`, `load`, y `batch load` de DynamoDBMapper.
+ Un valor de enumeración `DynamoDBMapperConfig.PaginationLoadingStrategy`: controla cómo la instancia de mapeador procesa una lista de datos paginados, como los resultados de una operación `query` o `scan`:
  + `LAZY_LOADING`: la instancia de mapeador carga los datos cuando es posible y conserva todos los resultados cargados en la memoria.
  + `EAGER_LOADING`: la instancia de mapeador carga los datos tan pronto como se inicializa la lista.
  + `ITERATION_ONLY`: solo se puede usar un iterador para leer datos en la lista. Durante la iteración, la lista borrará todos los resultados anteriores antes de cargar la página siguiente, para que la lista conserve como máximo una página de resultados cargados en la memoria. Por consiguiente, la lista solamente se puede recorrer en iteración una vez. Esta estrategia se recomienda para administrar elementos de gran tamaño, con el fin de reducir la sobrecarga de la memoria.

  Si no especifica una estrategia de carga de paginación para la instancia de mapeador, el valor predeterminado es `LAZY_LOADING`.
+ Un valor de enumeración `DynamoDBMapperConfig.SaveBehavior`: especifica cómo la instancia de mapeador administrará los atributos durante las operaciones de almacenamiento:
  + `UPDATE`: durante una operación de almacenamiento, se actualizan todos los atributos modelados y los atributos no modelados no sufren cambios. Los tipos numéricos primitivos (byte, int, long) se establecen en 0. Los tipos de objeto se establecen en null. 
  + `CLOBBER`: borra y sustituye los atributos, incluidos los no modelados, durante una operación de almacenamiento. Para ello, se elimina el elemento y se vuelve a crear. También se descartan las restricciones de los campos con versiones.

   Si no especifica el comportamiento al guardar para la instancia de mapeador, el valor predeterminado es `UPDATE`.
**nota**  
Las operaciones transaccionales de DynamoDBMapper no admiten la enumeración `DynamoDBMapperConfig.SaveBehavior`. 
+ Un objeto `DynamoDBMapperConfig.TableNameOverride`: indica a la instancia de mapeador que pase por alto el nombre de tabla especificado por la anotación `DynamoDBTable` de la clase y, en su lugar, use el nombre de tabla alternativo suministrado. Esto resulta útil cuando se particionan los datos en varias tablas en tiempo de ejecución. 

Puede anular el objeto de configuración predeterminado para `DynamoDBMapper` en cada operación, conforme lo necesite.

# DynamoDB y bloqueo positivo con el número de versión
<a name="DynamoDBMapper.OptimisticLocking"></a>

El *bloqueo optimista* es una estrategia para asegurarse de que el elemento del lado del cliente que se va a actualizar (o eliminar) sea el mismo que figura en Amazon DynamoDB. Si utiliza esta estrategia, las escrituras en su base de datos se protegen contra posibles sobrescrituras de otros y viceversa.

Con el bloqueo optimista, cada elemento tiene un atributo que actúa como número de versión. Si recupera un elemento de una tabla, la aplicación registra el número de versión de ese elemento. Puede actualizar el elemento, pero solo si el número de versión del lado del servidor no ha cambiado. Si no hay una coincidencia de versión, significa que alguien más ha modificado el elemento antes que usted. El intento de actualización falla porque tiene una versión obsoleta del elemento. Si esto ocurre, intente recuperar el elemento y actualizarlo. El bloqueo optimista impide que sobrescriba accidentalmente los cambios realizados por otras personas. También impide que otras personas sobrescriban accidentalmente sus cambios.

Si bien puede implementar su propia estrategia de bloqueo positivo, AWS SDK para Java proporciona la anotación `@DynamoDBVersionAttribute`. En la clase de mapeo de la tabla, debe designar una propiedad en la que se almacenará el número de versión y marcarla con esta anotación. Al guardar un objeto, el elemento correspondiente de la tabla de DynamoDB tendrá un atributo en el que se almacenará el número de versión. `DynamoDBMapper` asigna un número de versión la primera vez que se guarda el objeto y aumenta automáticamente este número de versión cada vez que se actualiza el elemento. Las solicitudes de actualización o eliminación solamente se llevan a cabo si la versión del objeto en el lado del cliente coincide con el número de versión del elemento correspondiente en la tabla de DynamoDB.

 `ConditionalCheckFailedException` se lanza si: 
+  Utiliza el bloqueo optimista con `@DynamoDBVersionAttribute` y el valor de versión en el servidor es distinto del valor en el lado del cliente. 
+  Especifique sus propias limitaciones condicionales al guardar los datos utilizando `DynamoDBMapper` con `DynamoDBSaveExpression` y estas limitaciones han fallado. 

**nota**  
Las tablas globales de DynamoDB usan una reconciliación del tipo "prevalece el último escritor" entre las actualizaciones simultáneas. Si usa tablas globales, prevalecerá la política del último escritor. Por tanto, en este caso, la estrategia de bloqueo no funciona según lo previsto.
Las operaciones de escritura transaccional `DynamoDBMapper` no admiten expresiones de anotación y condición `@DynamoDBVersionAttribute` en el mismo objeto. Si un objeto en una escritura transacciones se anota con `@DynamoDBVersionAttribute` y también tiene una expresión de condición, se producirá una SdkClientException.

Por ejemplo, en el siguiente código Java se define una clase `CatalogItem` que tiene varias propiedades. La propiedad `Version` está etiquetada con la anotación `@DynamoDBVersionAttribute`.

**Example**  

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;
    private Long version;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer Id) { this.id = Id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN;}

    @DynamoDBAttribute(attributeName = "Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp;}
    public void setSomeProp(String someProp) {this.someProp = someProp;}

    @DynamoDBVersionAttribute
    public Long getVersion() { return version; }
    public void setVersion(Long version) { this.version = version;}
}
```

Puede aplicar la anotación `@DynamoDBVersionAttribute` a los tipos que admiten valores null; estos están disponibles en las clases encapsuladoras primitivas que proporcionan un tipo que admite valores null, tales como `Long` e `Integer`. 

El bloqueo optimista afecta a los siguientes métodos de `DynamoDBMapper` como se indica a continuación:
+ `save`: para un elemento nuevo, `DynamoDBMapper` asigna un número de versión inicial de 1. Si recupera un elemento, actualiza una o varias de sus propiedades e intenta guardar los cambios, la operación de almacenamiento solamente se lleva a cabo si el número de versión del lado del cliente coincide con el número de versión del lado del servidor. `DynamoDBMapper` incrementa el número de versión automáticamente.
+ `delete`: el método `delete` toma un objeto como parámetro y `DynamoDBMapper` lleva a cabo una comprobación de versión antes de eliminar el elemento. La comprobación de versión se puede deshabilitar si se especifica `DynamoDBMapperConfig.SaveBehavior.CLOBBER` en la solicitud.

  La implementación interna del bloqueo optimista en `DynamoDBMapper` utiliza la compatibilidad con las acciones de actualización condicional y eliminación condicional que DynamoDB proporciona. 
+ `transactionWrite` —
  + `Put`: para un elemento nuevo, `DynamoDBMapper` asigna un número de versión inicial de 1. Si recupera un elemento, actualiza una o varias de sus propiedades e intenta guardar los cambios, la operación put solamente se lleva a cabo si el número de versión del lado del cliente coincide con el número de versión del lado del servidor. `DynamoDBMapper` incrementa el número de versión automáticamente.
  + `Update`: para un elemento nuevo, `DynamoDBMapper` asigna un número de versión inicial de 1. Si recupera un elemento, actualiza una o varias de sus propiedades e intenta guardar los cambios, la operación update solamente se lleva a cabo si el número de versión del lado del cliente coincide con el número de versión del lado del servidor. `DynamoDBMapper` incrementa el número de versión automáticamente.
  + `Delete`: `DynamoDBMapper` realiza una comprobación de versión antes de eliminar el elemento. La operación de eliminación solo se realiza correctamente si coincide el número de versión en el lado del cliente y en el lado del servidor.
  + `ConditionCheck`: la anotación `@DynamoDBVersionAttribute` no es compatible con `ConditionCheck`. Se producirá una excepción SdkClientException cuando un elemento `ConditionCheck` se anote con `@DynamoDBVersionAttribute`. 

## Deshabilitación del bloqueo positivo
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

Para deshabilitar el bloqueo optimista, puede cambiar el valor de enumeración `DynamoDBMapperConfig.SaveBehavior` de `UPDATE` a `CLOBBER`. Para ello, puede crear una instancia de `DynamoDBMapperConfig` que omita la comprobación de versión y usar esta instancia en todas las solicitudes. Para obtener información acerca de `DynamoDBMapperConfig.SaveBehavior` y otros parámetros opcionales de `DynamoDBMapper`, consulte [Ajustes de configuración opcionales para DynamoDBMapper](DynamoDBMapper.OptionalConfig.md). 

También puede establecer el comportamiento de bloqueo para una operación específica. Por ejemplo, en el siguiente fragmento de código Java se usa `DynamoDBMapper` para guardar un elemento de catálogo. Se agrega el parámetro opcional `DynamoDBMapperConfig.SaveBehavior` al método `DynamoDBMapperConfig` para especificar `save`. 

**nota**  
El método transactionWrite method no admite la configuración DynamoDBMapperConfig.SaveBehavior. No se admite la deshabilitación del bloqueo optimista para transactionWrite.

**Example**  

```
DynamoDBMapper mapper = new DynamoDBMapper(client);

// Load a catalog item.
CatalogItem item = mapper.load(CatalogItem.class, 101);
item.setTitle("This is a new title for the item");
...
// Save the item.
mapper.save(item,
    new DynamoDBMapperConfig(
        DynamoDBMapperConfig.SaveBehavior.CLOBBER));
```

# Asignación de datos arbitrarios en DynamoDB
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

Además de los tipos de Java admitidos (consulte [Tipos de datos compatibles con asignador DynamoDBMapper para Java](DynamoDBMapper.DataTypes.md)), puede utilizar tipos de la aplicación para los cuales no exista un mapeo directo a los tipos de Amazon DynamoDB. Para asignar estos tipos, debe proporcionar una implementación que convierta el tipo complejo en un tipo admitido por DynamoDB y viceversa, y anotar el método de acceso al tipo complejo mediante la anotación `@DynamoDBTypeConverted`. El código convertidor transforma los datos al guardar o cargar los objetos. También se usa para todas las operaciones que consumen tipos complejos. Tenga en cuenta que, al comparar datos durante las operaciones de consulta y examen, las comparaciones se realizan respecto a los datos almacenados en DynamoDB.

Por ejemplo, tomemos la siguiente clase `CatalogItem` que define una propiedad, `Dimension`, del tipo `DimensionType`. Esta propiedad almacena las dimensiones del elemento, tales como altura, anchura o espesor. Supongamos que decide almacenar estas dimensiones del elemento en una cadena (por ejemplo, 8,5x11x0,05) en DynamoDB. En el ejemplo siguiente se proporciona el código convertidor que convierte el objeto `DimensionType` en una cadena y una cadena al tipo `DimensionType`.



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

```
public class DynamoDBMapperExample {

    static AmazonDynamoDB client;

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

        // Set the AWS region you want to access.
        Regions usWest2 = Regions.US_WEST_2;
        client = AmazonDynamoDBClientBuilder.standard().withRegion(usWest2).build();

        DimensionType dimType = new DimensionType();
        dimType.setHeight("8.00");
        dimType.setLength("11.0");
        dimType.setThickness("1.0");

        Book book = new Book();
        book.setId(502);
        book.setTitle("Book 502");
        book.setISBN("555-5555555555");
        book.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author2")));
        book.setDimensions(dimType);

        DynamoDBMapper mapper = new DynamoDBMapper(client);
        mapper.save(book);

        Book bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Book info: " + "\n" + bookRetrieved);

        bookRetrieved.getDimensions().setHeight("9.0");
        bookRetrieved.getDimensions().setLength("12.0");
        bookRetrieved.getDimensions().setThickness("2.0");

        mapper.save(bookRetrieved);

        bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Updated book info: " + "\n" + bookRetrieved);
    }

    @DynamoDBTable(tableName = "ProductCatalog")
    public static class Book {
        private int id;
        private String title;
        private String ISBN;
        private Set<String> bookAuthors;
        private DimensionType dimensionType;

        // Partition key
        @DynamoDBHashKey(attributeName = "Id")
        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        @DynamoDBAttribute(attributeName = "Title")
        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        @DynamoDBAttribute(attributeName = "ISBN")
        public String getISBN() {
            return ISBN;
        }

        public void setISBN(String ISBN) {
            this.ISBN = ISBN;
        }

        @DynamoDBAttribute(attributeName = "Authors")
        public Set<String> getBookAuthors() {
            return bookAuthors;
        }

        public void setBookAuthors(Set<String> bookAuthors) {
            this.bookAuthors = bookAuthors;
        }

        @DynamoDBTypeConverted(converter = DimensionTypeConverter.class)
        @DynamoDBAttribute(attributeName = "Dimensions")
        public DimensionType getDimensions() {
            return dimensionType;
        }

        @DynamoDBAttribute(attributeName = "Dimensions")
        public void setDimensions(DimensionType dimensionType) {
            this.dimensionType = dimensionType;
        }

        @Override
        public String toString() {
            return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors + ", dimensionType= "
                    + dimensionType.getHeight() + " X " + dimensionType.getLength() + " X "
                    + dimensionType.getThickness()
                    + ", Id=" + id + ", Title=" + title + "]";
        }
    }

    static public class DimensionType {

        private String length;
        private String height;
        private String thickness;

        public String getLength() {
            return length;
        }

        public void setLength(String length) {
            this.length = length;
        }

        public String getHeight() {
            return height;
        }

        public void setHeight(String height) {
            this.height = height;
        }

        public String getThickness() {
            return thickness;
        }

        public void setThickness(String thickness) {
            this.thickness = thickness;
        }
    }

    // Converts the complex type DimensionType to a string and vice-versa.
    static public class DimensionTypeConverter implements DynamoDBTypeConverter<String, DimensionType> {

        @Override
        public String convert(DimensionType object) {
            DimensionType itemDimensions = (DimensionType) object;
            String dimension = null;
            try {
                if (itemDimensions != null) {
                    dimension = String.format("%s x %s x %s", itemDimensions.getLength(), itemDimensions.getHeight(),
                            itemDimensions.getThickness());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dimension;
        }

        @Override
        public DimensionType unconvert(String s) {

            DimensionType itemDimension = new DimensionType();
            try {
                if (s != null && s.length() != 0) {
                    String[] data = s.split("x");
                    itemDimension.setLength(data[0].trim());
                    itemDimension.setHeight(data[1].trim());
                    itemDimension.setThickness(data[2].trim());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return itemDimension;
        }
    }
}
```

# Ejemplos de DynamoDBMapper
<a name="DynamoDBMapper.Examples"></a>

El AWS SDK proporciona la clase `DynamoDBMapper`, que le permite asignar las clases del cliente a las tablas de DynamoDB. Para usar `DynamoDBMapper`, se define la relación entre los elementos de una tabla de DynamoDB y sus instancias de objetos correspondientes en el código. La clase `DynamoDBMapper` 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.

Para obtener más información sobre cómo usar `DynamoDBMapper`, consulte [DynamoDB Examples Using the AWS SDK for Java ](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html) en *AWS SDK for Java 1.x Developer Guide*. 