

# Información general sobre la compatibilidad de los SDK de AWS con DynamoDB
<a name="Programming.SDKOverview"></a>

En el siguiente diagrama se ofrece información general sobre la programación de aplicaciones de Amazon DynamoDB con los SDK de AWS.

![\[Modelo de programación para el uso de DynamoDB con AWS SDK.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. Puede escribir una aplicación utilizando un SDK de AWS para su lenguaje de programación.

1. Cada SDK de AWS proporciona una o varias interfaces de programación para trabajar con DynamoDB. Las interfaces específicas disponibles dependerán de qué lenguaje de programación y SDK de AWS se utilice. Las opciones son:
   + [Interfaces de bajo nivel que funcionan con DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [Interfaces de documento que funcionan con DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [Interfaces de persistencia de objetos que funcionan con DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [Interfaces de alto nivel](HigherLevelInterfaces.md)

1. El SDK de AWS construye solicitudes HTTP(S) para usarlas con el API de bajo nivel de DynamoDB.

1. El SDK de AWS envía la solicitud al punto de enlace de DynamoDB.

1. DynamoDB ejecuta la solicitud. Si la solicitud se realiza correctamente, DynamoDB devuelve un código de respuesta HTTP 200 (OK). Si la solicitud no se puede realizar, DynamoDB devuelve un código de error HTTP y un mensaje de error.

1. El SDK de AWS procesa la respuesta y se la transmite a la aplicación.

Cada uno de los SDK de AWS presta servicios importantes a la aplicación, tales como los siguientes:
+ Formatear las solicitudes HTTP(S) y serializar los parámetros de solicitud.
+ Generar una firma criptográfica de cada solicitud.
+ Reenviar la solicitud a un punto de enlace de DynamoDB y recibir las respuestas de DynamoDB.
+ Extraer los resultados de esas respuestas.
+ Implementar la lógica de reintento básica en caso de errores.

No es necesario escribir código para ninguna de estas tareas.

**nota**  
Para obtener más información sobre los SDK de AWS, incluidas las instrucciones de instalación y la documentación, consulte las [Herramientas para Amazon Web Services](https://aws.amazon.com/tools).

## Compatibilidad del SDK con puntos de conexión basados en cuentas de AWS
<a name="Programming.SDKs.endpoints"></a>

AWS lanzará la compatibilidad con el SDK para puntos de conexión basados en cuentas de AWS para DynamoDB, empezando por el SDK de AWS para Java V1 el 4 de septiembre de 2024. Estos nuevos puntos de conexión ayudan a AWS a garantizar un alto rendimiento y escalabilidad. Los SDK actualizados utilizarán automáticamente los nuevos puntos de conexión, que tienen el formato `https://(account-id).ddb.(region).amazonaws.com`.

Si utiliza una sola instancia de un cliente del SDK para realizar solicitudes a varias cuentas, la aplicación tendrá menos oportunidades de reutilizar las conexiones. AWS recomienda modificar las aplicaciones para conectarse a un menor número de cuentas por instancia de cliente del SDK. Una alternativa es configurar el cliente del SDK para que siga utilizando los puntos de conexión regionales mediante la configuración `ACCOUNT_ID_ENDPOINT_MODE`, tal y como se documenta en la [https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html).

# Interfaces programáticas que funcionan con DynamoDB
<a name="Programming.SDKs.Interfaces"></a>

Cada [SDK de AWS](https://aws.amazon.com/tools) proporciona una o varias interfaces de programación para trabajar con Amazon DynamoDB. Estas interfaces abarcan desde sencillos encapsuladores de bajo nivel de DynamoDB hasta capas de persistencia orientadas a objetos. Las interfaces disponibles varían según el SDK de AWS y el lenguaje de programación que se utilice.

![\[Interfaces de programación disponibles en diferentes AWS SDK para trabajar con DynamoDB.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


En la siguiente sección se resaltan algunas de las interfaces disponibles utilizando el AWS SDK para Java como ejemplo. (No todas las interfaces están disponibles en todos los SDK de AWS.)

**Topics**
+ [Interfaces de bajo nivel que funcionan con DynamoDB](#Programming.SDKs.Interfaces.LowLevel)
+ [Interfaces de documento que funcionan con DynamoDB](#Programming.SDKs.Interfaces.Document)
+ [Interfaces de persistencia de objetos que funcionan con DynamoDB](#Programming.SDKs.Interfaces.Mapper)

## Interfaces de bajo nivel que funcionan con DynamoDB
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

Cada SDK de AWS específico de un lenguaje ofrece una interfaz de bajo nivel para Amazon DynamoDB, con métodos que emulan del modo más parecido posible las solicitudes del API de bajo nivel de DynamoDB.

En algunos casos, es preciso identificar los tipos de datos de los atributos utilizando [Descriptores de tipos de datos](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors); por ejemplo, `S` si es una cadena o `N` si es un número.

**nota**  
Hay interfaz de bajo nivel disponible en el SDK de AWS específico de cada idioma.

En el siguiente programa de Java se utiliza la interfaz de bajo nivel del AWS SDK para Java. 

### Ejemplo de interfaz de bajo nivel
<a name="low-level-example"></a>

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 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 get an item from an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal>

                Where:
                    tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3).\s
                    key - The key used in the Amazon DynamoDB table (for example, Artist).\s
                    keyval - The key value that represents the item to get (for example, Famous Band).
                """;

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

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName);
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        getDynamoDBItem(ddb, tableName, key, keyVal);
        ddb.close();
    }

    public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) {
        HashMap<String, AttributeValue> keyToGet = new HashMap<>();
        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal)
                .build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            // If there is no matching item, GetItem does not return any data.
            Map<String, AttributeValue> returnedItem = ddb.getItem(request).item();
            if (returnedItem.isEmpty())
                System.out.format("No item found with the key %s!\n", key);
            else {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");
                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

## Interfaces de documento que funcionan con DynamoDB
<a name="Programming.SDKs.Interfaces.Document"></a>

Muchos SDK de AWSproporcionan una interfaz de documentos, lo que permite realizar operaciones del plano de datos (crear, leer, actualizar, eliminar) en tablas e índices. Con una interfaz de documentos, no es preciso especificar [Descriptores de tipos de datos](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors). Los tipos de datos quedan implícitos en la propia semántica de los datos. Estos SDK de AWS también proporcionan métodos para convertir fácilmente documentos JSON a los tipos de datos nativos de Amazon DynamoDB y viceversa.

**nota**  
Las interfaces de documento están disponibles en los SDK de AWS para [ Java](https://aws.amazon.com/sdk-for-java), [.NET](https://aws.amazon.com/sdk-for-net), [Node.js](https://aws.amazon.com/sdk-for-node-js) y [JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/).

En el siguiente programa de Java se utiliza la interfaz de documentos del AWS SDK para Java. El programa crea un objeto `Table` que representa la tabla `Music` y, a continuación, solicita que el objeto utilice `GetItem` para recuperar una canción. Después, el programa imprime el año en que se lanzó la canción.

La clase `software.amazon.dynamodb.document.DynamoDB` implementa la interfaz de documentos de DynamoDB. Observe que `DynamoDB` actúa como encapsulador en torno al cliente de bajo nivel (`AmazonDynamoDB`).

### Ejemplo de interfaz de documento
<a name="document-level-example"></a>

```
package com.amazonaws.codesamples.gsg;

import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.document.DynamoDB;
import software.amazon.dynamodb.document.GetItemOutcome;
import software.amazon.dynamodb.document.Table;

public class MusicDocumentDemo {

    public static void main(String[] args) {

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

        Table table = docClient.getTable("Music");
        GetItemOutcome outcome = table.getItemOutcome(
                "Artist", "No One You Know",
                "SongTitle", "Call Me Today");

        int year = outcome.getItem().getInt("Year");
        System.out.println("The song was released in " + year);

    }
}
```

## Interfaces de persistencia de objetos que funcionan con DynamoDB
<a name="Programming.SDKs.Interfaces.Mapper"></a>

Algunos SDK de AWS proporcionan una interfaz de persistencia de objetos en la que no se llevan a cabo directamente operaciones del plano de datos. En lugar de ello, se crean objetos que representan los elementos de las tablas y los índices de Amazon DynamoDB y solamente se interacciona con estos objetos. Esto le permite escribir código orientado a objetos, en lugar de código orientado a bases de datos.

**nota**  
Las interfaces de persistencia de objetos están disponibles en los SDK de AWS para Java y .NET. Para obtener más información, consulte [Interfaces de programación de nivel superior para DynamoDB](HigherLevelInterfaces.md) de DynamoDB.

### Ejemplo de interfaz de persistencia de objetos
<a name="mapper-level-example"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key. Be sure one of the id values is `id101`
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table. These values
 *                        need to be in the form of `YYYY-MM-DDTHH:mm:ssZ`, such as 2022-07-11T00:00:00Z
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedGetItem {
    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        getItem(enhancedClient);
        ddb.close();
    }

    public static String getItem(DynamoDbEnhancedClient enhancedClient) {
        Customer result = null;
        try {
            DynamoDbTable<Customer> table = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key = Key.builder()
                    .partitionValue("id101").sortValue("tred@noserver.com")
                    .build();

            // Get the item by using the key.
            result = table.getItem(
                    (GetItemEnhancedRequest.Builder requestBuilder) -> requestBuilder.key(key));
            System.out.println("******* The description value is " + result.getCustName());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return result.getCustName();
    }
}
```

# Interfaces de programación de nivel superior para DynamoDB
<a name="HigherLevelInterfaces"></a>

Los SDK de AWS proporcionan aplicaciones con interfaces de bajo nivel para trabajar con Amazon DynamoDB. Estas clases y métodos del lado del cliente se corresponden directamente con los API de bajo nivel de DynamoDB. Sin embargo, muchos desarrolladores experimentan una sensación de desconexión, o *discrepancia de impedancia* cuando tienen que mapear tipos de datos complejos a los elementos de una tabla de base de datos. Con una interfaz de bajo nivel de base de datos, los desarrolladores deben escribir métodos para leer o escribir datos de objetos en las tablas de las bases de datos, y viceversa. La cantidad de código adicional necesaria para cada combinación de tipo de objeto y tabla de base de datos puede resultar abrumadora.

Para simplificar el desarrollo, los SDK de AWS para Java y .NET incluyen interfaces adicionales con niveles de abstracción superiores. Las interfaces de nivel superior para DynamoDB permiten definir las relaciones entre los objetos del programa del desarrollador y las tablas de base de datos en las que se almacenan esos datos de objetos. Una vez que se ha definido este mapeo, basta con llamar a métodos de objetos simples, como `save`, `load` o `delete`, y las operaciones de bajo nivel de DynamoDB subyacentes se invocan automáticamente si su intervención. Esto le permite escribir código orientado a objetos, en lugar de código orientado a bases de datos.

Las interfaces de programación de nivel superior para DynamoDB están disponibles en los SDK de AWS para Java y .NET.

**Java**
+ [Java 1.x: DynamoDBMapper](DynamoDBMapper.md)
+ [Java 2.x: cliente mejorado de DynamoDB](DynamoDBEnhanced.md)

**.NET**
+ [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md)
+ [Uso del modelo de persistencia de objetos de .NET y DynamoDB](DotNetSDKHighLevel.md)

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

# Java 2.x: cliente mejorado de DynamoDB
<a name="DynamoDBEnhanced"></a>

El cliente mejorado de DynamoDB es una biblioteca de alto nivel que forma parte de AWS SDK para Java versión 2 (v2). Ofrece una forma sencilla de asignar clases del cliente a tablas de DynamoDB. Puede definir las relaciones entre las tablas y sus correspondientes clases de modelo en el código. Después de definir estas relaciones, puede realizar intuitivamente varias operaciones de creación, lectura, actualización o eliminación (CRUD) en tablas o elementos en DynamoDB.

Para obtener más información sobre cómo puede utilizar el cliente mejorado con DynamoDB, consulte [Uso del cliente mejorado de DynamoDB en AWS SDK para Java versión 2.x ](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html). 

# Uso del modelo de documento de .NET en DynamoDB
<a name="DotNetSDKMidLevel"></a>

El AWS SDK para .NET proporciona clases de modelo de documento que encapsulan algunas de las operaciones de bajo nivel de Amazon DynamoDB y así le ayudan a simplificar la codificación. En el modelo de documento, las clases principales son `Table` y `Document`. La clase `Table` proporciona métodos de operaciones de datos, como `PutItem`, `GetItem` y `DeleteItem`. Además, proporciona los métodos `Query` y `Scan`. La clase `Document` representa un solo elemento de una tabla.

Las clases del modelo de documento citadas están disponibles en el espacio de nombres `Amazon.DynamoDBv2.DocumentModel`.

**nota**  
Las clases del modelo de documento no se pueden usar para crear, actualizar ni eliminar tablas. Sin embargo, el modelo de documento admite la mayoría de las operaciones de datos habituales.

**Topics**
+ [Tipos de datos compatibles](#MidLevelAPILimitations.SupportedTypes)

## Tipos de datos compatibles
<a name="MidLevelAPILimitations.SupportedTypes"></a>

El modelo de documento admite un conjunto de tipos de datos de .NET primitivos y tipos de datos de colecciones. El modelo admite los siguientes tipos de datos primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

En la tabla siguiente se resume el mapeo de los tipos de .NET anteriores a los tipos de DynamoDB.


****  

| Tipo de .NET primitivo | Tipo DynamoDB | 
| --- | --- | 
|  Todos los tipos de números  |  `N` (tipo Number)  | 
|  Todos los tipos de cadenas  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binary)   | 
| bool | N (tipo Number), 0 representa false (falso) y 1 representa true (verdadero). | 
| DateTime | S (tipo String). Los valores DateTime se almacenan como cadenas con formato ISO-8601. | 
| Guid | S (tipo String). | 
| Tipos de recopilación (List, HashSet y array) | BS (tipo Binary Set), SS (tipo String Set) y NS (tipo Number Set) | 

AWS SDK para .NET define tipos para establecer una correspondencia entre tipos booleanos, nulos, listas y mapas de DynamoDB y la API de modelo de documento de .NET:
+ Utilice `DynamoDBBool` para tipo booleano.
+ Utilice `DynamoDBNull` para tipo nulo.
+ Utilice `DynamoDBList` para tipo lista.
+ Utilice `Document` para tipo mapa.

**nota**  
Se admiten valores binarios vacíos.
Se admite la lectura de valores de cadena vacíos. Los valores de atributo de cadena vacíos se admiten dentro de los valores de atributo del tipo de conjunto de cadenas mientras se escribe en DynamoDB. Los valores de atributo de cadena vacíos del tipo de cadena y los valores de cadena vacíos contenidos en el tipo lista o mapa se eliminan de las solicitudes de escritura

# Uso del modelo de persistencia de objetos de .NET y DynamoDB
<a name="DotNetSDKHighLevel"></a>

El AWS SDK para .NET proporciona un modelo de persistencia de objetos que le permite mapear las clases en el cliente a una tabla de Amazon DynamoDB. A continuación, cada instancia de objeto se mapea a un elemento en las tablas correspondientes. Para guardar los objetos del lado del cliente en las tablas, el modelo de persistencia de objetos proporciona la clase `DynamoDBContext`, un punto de entrada a DynamoDB. Esta categoría le ofrece una conexión a DynamoDB y le permite obtener acceso a tablas, realizar diversas operaciones CRUD y ejecutar consultas.

El modelo de persistencia de objetos proporciona un conjunto de atributos para mapear las clases del lado del cliente a tablas, y las propiedades/campos a atributos de tabla.

**nota**  
El modelo de persistencia de objetos no proporciona una API para crear, actualizar o eliminar tablas. Solo ofrece operaciones de datos. Puede usar la API de bajo nivel AWS SDK para .NET para crear, actualizar y eliminar tablas.

En el ejemplo siguiente se muestra cómo funciona el modelo de persistencia de objetos. Comienza con la tabla `ProductCatalog`. Su clave principal es `Id`.

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

Suponga que tiene una clase `Book` con las propiedades `Title`, `ISBN` y `Authors`. Puede mapear la clase `Book` a la tabla `ProductCatalog` agregando los atributos definidos por el modelo de persistencia de objetos, como se muestra en el siguiente ejemplo de código C\$1.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]
    public int Id { get; set; }

    public string Title { get; set; }
    public int ISBN { get; set; }

    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }

    [DynamoDBIgnore]
    public string CoverPage { get; set; }
  }
```

En el ejemplo anterior, el atributo `DynamoDBTable` mapea la clase `Book` a la tabla `ProductCatalog`.

El modelo de persistencia de objetos admite el mapeo tanto explícito como predeterminado entre las propiedades de clase y los atributos de tabla.
+ **Mapeo explícito**: para mapear una propiedad a una clave principal, debe usar los atributos `DynamoDBHashKey` y `DynamoDBRangeKey` del modelo de persistencia de objetos. Además, en el caso de los atributos sin clave principal, si un nombre de propiedad de la clase y el atributo de tabla correspondiente al que desea mapearlo no son iguales, debe definir el mapeo agregando explícitamente el atributo `DynamoDBProperty`.

  En el ejemplo anterior, la propiedad `Id` se mapea a la clave principal con el mismo nombre y la propiedad `BookAuthors` se mapea al atributo `Authors` de la tabla `ProductCatalog`.
+ **Mapeo predeterminado**: de forma predeterminada, el modelo de persistencia de objetos mapea las propiedades de clase a los atributos con el mismo nombre de la tabla.

  En el ejemplo anterior, las propiedades `Title` e `ISBN` se mapean a los atributos del mismo nombre de la tabla `ProductCatalog`.

No tiene que mapear cada propiedad de clase. Puede identificar estas propiedades agregando el atributo `DynamoDBIgnore`. Al guardar una instancia de `Book` en la tabla, `DynamoDBContext` no incluye la propiedad `CoverPage`. Tampoco se devolverá esta propiedad cuando se recupere la instancia del libro.

Puede mapear propiedades de tipos primitivos de .NET, como int o string. También puede mapear cualquier tipo de datos arbitrarios, siempre y cuando proporcione un convertidor adecuado para mapear los datos arbitrarios a uno de los tipos de DynamoDB. Para obtener más información sobre cómo mapear tipos arbitrarios, consulte [Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md).

El modelo de persistencia de objetos admite el bloqueo optimista. Durante una operación de actualización, esto garantiza que se disponga de la última copia del elemento que se va a actualizar. Para obtener más información, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

Para obtener más información, consulte los siguientes temas.

**Topics**
+ [Tipos de datos compatibles](#DotNetDynamoDBContext.SupportedTypes)
+ [Atributos de DynamoDB del modelo de persistencia de objetos de .NET](DeclarativeTagsList.md)
+ [Clase DynamoDBContext del modelo de persistencia de objetos de .NET](DotNetDynamoDBContext.md)
+ [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md)
+ [Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md)

## Tipos de datos compatibles
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

El modelo de persistencia de objetos admite un conjunto de tipos de datos, colecciones y tipos de datos arbitrarios de .NET primitivos. El modelo admite los siguientes tipos de datos primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

El modelo de persistencia de objetos también admite los tipos de colección de .NET. `DynamoDBContext` puede convertir tipos de colección concretos y objetos CLR estándar (POCO, por sus siglas en inglés) simples.

En la tabla siguiente se resume el mapeo de los tipos de .NET anteriores a los tipos de DynamoDB.


****  

| Tipo de .NET primitivo | Tipo DynamoDB | 
| --- | --- | 
|  Todos los tipos de números  |  `N` (tipo Number)  | 
|  Todos los tipos de cadenas  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binary)   | 
| bool | N (tipo Number), 0 representa false (falso) y 1 representa true (verdadero). | 
| Tipos de colección | BS (tipo Binary Set), SS (tipo String Set) y NS (tipo Number Set) | 
| DateTime | S (tipo String). Los valores DateTime se almacenan como cadenas con formato ISO-8601. | 

El modelo de persistencia de objetos también admite los tipos de datos arbitrarios. Sin embargo, debe proporcionar el código de convertidor para mapear los tipos complejos a los tipos de DynamoDB.

**nota**  
Se admiten valores binarios vacíos.
Se admite la lectura de valores de cadena vacíos. Los valores de atributo de cadena vacíos se admiten dentro de los valores de atributo del tipo de conjunto de cadenas mientras se escribe en DynamoDB. Los valores de atributo de cadena vacíos del tipo de cadena y los valores de cadena vacíos contenidos en el tipo lista o mapa se eliminan de las solicitudes de escritura

# Atributos de DynamoDB del modelo de persistencia de objetos de .NET
<a name="DeclarativeTagsList"></a>

En esta sección se describen los atributos que ofrece el modelo de persistencia de objetos para que pueda mapear las clases y propiedades a tablas y atributos de DynamoDB.

**nota**  
En los atributos siguientes, solo son obligatorios `DynamoDBTable` y `DynamoDBHashKey`.

## DynamoDBGlobalSecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

Mapea una propiedad de clase a la clave de partición de un índice secundario global. Use este atributo si necesita `Query` un índice secundario global.

## DynamoDBGlobalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

Mapea una propiedad de clase a la clave de ordenación de un índice secundario global. Use este atributo si tiene que utilizar una operación `Query` en un índice secundario global y desea refinar los resultados mediante la clave de ordenación del índice.

## DynamoDBHashKey
<a name="w2aac17b9c21c23c37c11"></a>

Mapea una propiedad de clase a la clave de partición de la clave principal de la tabla. Los atributos de clave principal no pueden ser un tipo de colección.

En los siguientes ejemplos de código C\$1 se mapea la clase `Book` a la tabla `ProductCatalog` y la propiedad `Id` a la clave de partición de la clave principal de la tabla.

```
[DynamoDBTable("ProductCatalog")]
public class Book 
{
    [DynamoDBHashKey]
    public int Id { get; set; }

    // Additional properties go here.
}
```

## DynamoDBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

Indica que la propiedad asociada debe pasarse por alto. Si no desea guardar ninguna de las propiedades de clase, puede agregar este atributo para indicar a `DynamoDBContext` que no incluya esta propiedad cuando guarde objetos en la tabla.

## DynamoDBLocalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

Mapea una propiedad de clase a la clave de ordenación de un índice secundario local. Use este atributo si tiene que utilizar una operación `Query` en un índice secundario local y desea refinar los resultados mediante la clave de ordenación del índice.

## DynamoDBProperty
<a name="w2aac17b9c21c23c37c17"></a>

Mapea una propiedad de clase a un atributo de tabla. Si la propiedad de clase se mapea al atributo de tabla con el mismo nombre, no es preciso especificarlo. Sin embargo, si los nombres no son iguales, puede utilizar esta etiqueta para realizar el mapeo. En la siguiente instrucción de C\$1, `DynamoDBProperty` mapea la propiedad `BookAuthors` al atributo `Authors` de la tabla. 

```
[DynamoDBProperty("Authors")]
public List<string> BookAuthors { get; set; }
```

`DynamoDBContext` utiliza esta información de mapeo para crear el atributo `Authors` al guardar datos de objetos en la tabla correspondiente.

## DynamoDBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

Especifica un nombre alternativo para una propiedad de clase. Esto resulta útil si va a escribir un convertidor personalizado para mapear datos arbitrarios a una tabla de DynamoDB cuando el nombre de una propiedad de clase sea distinto del nombre del atributo de tabla.

## DynamoDBRangeKey
<a name="w2aac17b9c21c23c37c21"></a>

Mapea una propiedad de clase a la clave de ordenación de la clave principal de la tabla. Si la tabla tiene una clave principal compuesta (clave de partición y clave de ordenación), entonces debe especificar ambos atributos, `DynamoDBHashKey` y `DynamoDBRangeKey`, en el mapeo de clase.

Por ejemplo, en el ejemplo de tabla `Reply`, la clave principal consta de la clave de partición `Id` y de la clave de ordenación `Replenishment`. En el siguiente ejemplo de código C\$1 se mapea la clase `Reply` a la tabla `Reply`. La definición de clase también indica que dos de sus propiedades se mapean a la clave principal.

```
[DynamoDBTable("Reply")]
public class Reply 
{
   [DynamoDBHashKey]
   public int ThreadId { get; set; }
   [DynamoDBRangeKey]
   public string Replenishment { get; set; }
   
   // Additional properties go here.
}
```

## DynamoDBTable
<a name="w2aac17b9c21c23c37c23"></a>

Identifica la tabla de destino de DynamoDB a la que se mapea la clase. Por ejemplo, en el siguiente ejemplo de código C\$1 se mapea la clase `Developer` a la tabla `People` de DynamoDB.

```
[DynamoDBTable("People")]
public class Developer { ...}
```

Este atributo se puede heredar o anular.
+ El atributo `DynamoDBTable` se puede heredar. En el ejemplo anterior, si agrega una nueva clase, `Lead`, que hereda de la clase `Developer`, también se mapea a la tabla `People`. Ambos objetos, `Developer` y `Lead`, se almacenan en la tabla `People`.
+ El atributo `DynamoDBTable` también se puede anular. En el siguiente ejemplo de código C\$1, la clase `Manager` hereda de la clase `Developer`. Sin embargo, la adición explícita del atributo `DynamoDBTable` mapea la clase a otra tabla (`Managers`).

  ```
  [DynamoDBTable("Managers")]
  public class Manager : Developer { ...}
  ```

 Puede agregar el parámetro opcional, `LowerCamelCaseProperties`, para solicitar que DynamoDB cambie a minúscula la primera letra del nombre de la propiedad cuando almacene los objetos en una tabla, como se muestra en el siguiente fragmento de código C\$1.

```
[DynamoDBTable("People", LowerCamelCaseProperties=true)]
public class Developer 
{
    string DeveloperName;
    ...
}
```

Al guardar instancias de la clase `Developer`, `DynamoDBContext` guarda la propiedad `DeveloperName` como `developerName`.

## DynamoDBVersion
<a name="w2aac17b9c21c23c37c25"></a>

Identifica una propiedad de clase para almacenar el número de versión del elemento. Para obtener más información sobre el control de versiones, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

# Clase DynamoDBContext del modelo de persistencia de objetos de .NET
<a name="DotNetDynamoDBContext"></a>

La clase `DynamoDBContext` es el punto de entrada de la base de datos de Amazon DynamoDB. Proporciona conexión con DynamoDB y le permite acceder a los datos de diversas tablas, realizar distintas operaciones CRUD y ejecutar consultas. La clase `DynamoDBContext` proporciona los métodos siguientes.

**Topics**
+ [CreateMultiTableBatchGet](#w2aac17b9c21c23c39b7)
+ [CreateMultiTableBatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Eliminar](#w2aac17b9c21c23c39c15)
+ [Dispose](#w2aac17b9c21c23c39c17)
+ [ExecuteBatchGet](#w2aac17b9c21c23c39c19)
+ [ExecuteBatchWrite](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [GetTargetTable](#w2aac17b9c21c23c39c29)
+ [Cargar](#w2aac17b9c21c23c39c31)
+ [Consultar](#w2aac17b9c21c23c39c33)
+ [Save](#w2aac17b9c21c23c39c35)
+ [Examen](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Especificación de parámetros opcionales para DynamoDBContext](#OptionalConfigParams)

## CreateMultiTableBatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Crea un objeto `MultiTableBatchGet`, que consta de varios objetos `BatchGet` individuales. Cada uno de estos objetos `BatchGet` se puede usar para recuperar elementos de una sola tabla de DynamoDB.

Para recuperar elementos de una o varias tablas, utilice el método `ExecuteBatchGet` y pase el objeto `MultiTableBatchGet` como parámetro.

## CreateMultiTableBatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Crea un objeto `MultiTableBatchWrite`, que consta de varios objetos `BatchWrite` individuales. Cada uno de estos objetos `BatchWrite` se puede usar para escribir o eliminar elementos de una sola tabla de DynamoDB.

Para escribir en una o varias tablas, utilice el método `ExecuteBatchWrite` y pase el objeto `MultiTableBatchWrite` como parámetro.

## CreateBatchGet
<a name="w2aac17b9c21c23c39c11"></a>

Crea un objeto `BatchGet` que puede usar para recuperar varios elementos de una tabla. 

## CreateBatchWrite
<a name="w2aac17b9c21c23c39c13"></a>

Crea un objeto `BatchWrite` que puede usar para colocar o eliminar varios elementos en una tabla. 

## Eliminar
<a name="w2aac17b9c21c23c39c15"></a>

Elimina un elemento de la tabla. El método requiere la clave principal del elemento que se desea eliminar. Como parámetro de este método, puede proporcionar el valor de la clave principal o un objeto del lado del cliente que contenga un valor de clave .
+ Si especifica un objeto del lado del cliente como parámetro y ha habilitado el bloqueo optimista, la eliminación se llevará a cabo correctamente solo si las versiones del lado del cliente y del lado del servidor del objeto coinciden.
+ Si especifica únicamente el valor de clave principal como parámetro, la eliminación se llevará a cabo correctamente tanto si ha habilitado bloqueo optimista como si no.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `DeleteAsync` en su lugar.

## Dispose
<a name="w2aac17b9c21c23c39c17"></a>

Elimina todos los recursos administrados y no administrados.

## ExecuteBatchGet
<a name="w2aac17b9c21c23c39c19"></a>

Lee datos en una o varias tablas y procesa todos los objetos `BatchGet` de un objeto `MultiTableBatchGet`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ExecuteBatchGetAsync` en su lugar.

## ExecuteBatchWrite
<a name="w2aac17b9c21c23c39c21"></a>

Escribe o elimina datos en una o varias tablas y procesa todos los objetos `BatchWrite` de un objeto `MultiTableBatchWrite`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ExecuteBatchWriteAsync` en su lugar.

## FromDocument
<a name="w2aac17b9c21c23c39c23"></a>

Dada una instancia de un objeto `Document`, el método `FromDocument` devuelve una instancia de una clase del lado del cliente.

Esto resulta útil si desea utilizar las clases del modelo de documento junto con el modelo de persistencia de objetos para realizar operaciones con datos. Para obtener más información sobre las clases del modelo de documentos que se proporcionan en AWS SDK para .NET, consulte [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md).

Supongamos que tiene un objeto `Document` denominado `doc` que contiene una representación de un elemento `Forum`. (Para saber cómo construir este objeto, consulte la descripción del método `ToDocument` más adelante en este tema). Puede utilizar `FromDocument` para recuperar el elemento `Forum` del `Document` como se muestra en el siguiente ejemplo de código C\$1.

**Example**  

```
forum101 = context.FromDocument<Forum>(101);
```

**nota**  
Si el objeto `Document` implementa la interfaz `IEnumerable`, puede usar el método `FromDocuments` en su lugar. Esto le permitirá recorrer en iteración todas las instancias de la clase contenidas en `Document`.

## FromQuery
<a name="w2aac17b9c21c23c39c25"></a>

Ejecuta una operación `Query` con los parámetros de la consulta definidos en un objeto `QueryOperationConfig`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `FromQueryAsync` en su lugar.

## FromScan
<a name="w2aac17b9c21c23c39c27"></a>

Ejecuta una operación `Scan` con los parámetros del análisis definidos en un objeto `ScanOperationConfig`.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `FromScanAsync` en su lugar.

## GetTargetTable
<a name="w2aac17b9c21c23c39c29"></a>

Recupera la tabla de destino del tipo especificado. Esto resulta útil si va a escribir un convertidor personalizado para mapear datos arbitrarios a una tabla de DynamoDB y tiene que determinar qué tabla está asociada con un tipo de datos personalizado.

## Cargar
<a name="w2aac17b9c21c23c39c31"></a>

Recupera un elemento de una tabla. El método requiere solo la clave principal del elemento que se desea recuperar. 

De forma predeterminada, DynamoDB devuelve el elemento con valores que presentan consistencia final. Para obtener más información sobre el modelo de consistencia final, consulte [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).

El método `Load` o `LoadAsync` llama a la operación [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), que requiere que especifique la clave principal de la tabla. Como `GetItem` omite el parámetro `IndexName`, no puede cargar un elemento con la partición o la clave de clasificación de un índice. Por lo tanto, debe utilizar la clave principal de la tabla para cargar un elemento.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `LoadAsync` en su lugar. Para ver un ejemplo del uso del método `LoadAsync` para realizar operaciones CRUD de alto nivel en una tabla de DynamoDB, consulte el siguiente ejemplo.

```
    /// <summary>
    /// Shows how to perform high-level CRUD operations on an Amazon DynamoDB
    /// table.
    /// </summary>
    public class HighLevelItemCrud
    {
        public static async Task Main()
        {
            var client = new AmazonDynamoDBClient();
            DynamoDBContext context = new DynamoDBContext(client);
            await PerformCRUDOperations(context);
        }

        public static async Task PerformCRUDOperations(IDynamoDBContext context)
        {
            int bookId = 1001; // Some unique value.
            Book myBook = new Book
            {
                Id = bookId,
                Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
                Isbn = "111-1111111001",
                BookAuthors = new List<string> { "Author 1", "Author 2" },
            };

            // Save the book to the ProductCatalog table.
            await context.SaveAsync(myBook);

            // Retrieve the book from the ProductCatalog table.
            Book bookRetrieved = await context.LoadAsync<Book>(bookId);

            // Update some properties.
            bookRetrieved.Isbn = "222-2222221001";

            // Update existing authors list with the following values.
            bookRetrieved.BookAuthors = new List<string> { " Author 1", "Author x" };
            await context.SaveAsync(bookRetrieved);

            // Retrieve the updated book. This time, add the optional
            // ConsistentRead parameter using DynamoDBContextConfig object.
            await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            // Delete the book.
            await context.DeleteAsync<Book>(bookId);

            // Try to retrieve deleted book. It should return null.
            Book deletedBook = await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            if (deletedBook == null)
            {
                Console.WriteLine("Book is deleted");
            }
        }
    }
```

## Consultar
<a name="w2aac17b9c21c23c39c33"></a>

Consulta una tabla basándose en los parámetros de consulta que haya proporcionado.

Solo se puede consultar una tabla si cuenta con una clave principal compuesta (una clave de partición y una clave de ordenación). Al realizar la consulta, debe especificar una clave de partición y una condición que se aplica a la clave de ordenación.

Supongamos que tenemos una clase `Reply` del lado del cliente mapeada a la tabla `Reply` de DynamoDB. En el siguiente ejemplo de código C\$1 se consulta la tabla `Reply` para buscar las respuestas de las conversaciones de un foro publicadas en los últimos 15 días. La tabla `Reply` tiene una clave principal cuya clave de partición es `Id` y cuya clave de ordenación es `ReplyDateTime`.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

string replyId = "DynamoDB#DynamoDB Thread 1"; //Partition key
DateTime twoWeeksAgoDate = DateTime.UtcNow.Subtract(new TimeSpan(14, 0, 0, 0)); // Date to compare.
IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate);
```

Devuelve una colección de objetos `Reply`. 

El método `Query` devuelve una colección `IEnumerable` 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, solo tiene que recorrer en iteración el `IEnumerable`.

Si la tabla tiene una clave principal simple (clave de partición), no puede usar el método `Query`. En su lugar, puede usar el método `Load` y proporcionar la clave de partición para recuperar el elemento.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `QueryAsync` en su lugar.

## Save
<a name="w2aac17b9c21c23c39c35"></a>

Guarda el objeto especificado en la tabla. Si la clave principal especificada en el objeto de entrada no existe en la tabla, el método agrega un nuevo elemento a la tabla. Si la clave principal sí está presente, el método actualiza el elemento.

Si ha configurado el bloqueo optimista, la actualización solo se llevará a cabo correctamente si las versiones del elemento del lado del cliente y del lado del servidor coinciden. Para obtener más información, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

**nota**  
Para ejecutar esta operación en segundo plano, use el método `SaveAsync` en su lugar.

## Examen
<a name="w2aac17b9c21c23c39c37"></a>

Realiza un examen de toda la tabla. 

Puede filtrar el resultado del examen especificando una condición de examen. La condición se puede evaluar según cualesquiera atributos de la tabla. Supongamos que tenemos una clase `Book` del lado del cliente mapeada a la tabla `ProductCatalog` de DynamoDB. En el siguiente ejemplo de código C\$1 se examina la tabla y se devuelven solamente aquellos elementos de libro cuyo precio es menor que 0.

**Example**  

```
IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>(
                    new ScanCondition("Price", ScanOperator.LessThan, price),
                    new ScanCondition("ProductCategory", ScanOperator.Equal, "Book")
      );
```

El método `Scan` devuelve una colección `IEnumerable` 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, solo tiene que recorrer en iteración la colección `IEnumerable`.

Por motivos de desempeño, debe consultar las tablas y evitar examinarlas.

**nota**  
Para ejecutar esta operación en segundo plano, use el método `ScanAsync` en su lugar.

## ToDocument
<a name="w2aac17b9c21c23c39c39"></a>

Devuelve una instancia de la clase `Document` del modelo de documento de la instancia de clase. 

Esto resulta útil si desea utilizar las clases del modelo de documento junto con el modelo de persistencia de objetos para realizar operaciones con datos. Para obtener más información sobre las clases del modelo de documentos que se proporcionan en AWS SDK para .NET, consulte [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md). 

Supongamos que tenemos una clase del lado del cliente mapeada al ejemplo de tabla `Forum`. Puede usar una `DynamoDBContext` para obtener un elemento, como un objeto `Document`, de la tabla `Forum`, como se muestra en el siguiente ejemplo de código C\$1.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

Forum forum101 = context.Load<Forum>(101); // Retrieve a forum by primary key.
Document doc = context.ToDocument<Forum>(forum101);
```

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

Cuando se utiliza el modelo de persistencia de objetos, es posible especificar los siguientes parámetros opcionales para la clase `DynamoDBContext`.
+ **`ConsistentRead`**: cuando se recuperan datos utilizando las operaciones `Load`, `Query` o `Scan`, es posible agregar este parámetro si se desea para solicitar los valores más recientes de los datos.
+ **`IgnoreNullValues`**: este parámetro informa a `DynamoDBContext` de que debe pasar por alto los valores null de los atributos durante una operación `Save`. Si este parámetro es false (o, si no se ha establecido), entonces un valor null se interpretará como una instrucción de eliminar el atributo de que se trate. 
+ **`SkipVersionCheck`**: este parámetro informa a `DynamoDBContext` de que no debe comparar las versiones al guardar o eliminar un elemento. Para obtener más información sobre el control de versiones, consulte [Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix`—** antepone una cadena determinada a los nombres de todas las tablas. Si este parámetro es null (o si no se ha establecido), no se utilizará ningún prefijo.
+ `DynamoDBEntryConversion`: especifica el esquema de conversión que utiliza el cliente. Puede establecer este parámetro en la versión V1 o V2. V1 es la versión predeterminada.

  En función de la versión que establezca, el comportamiento de este parámetro cambia. Por ejemplo:
  + En V1, el tipo de datos `bool` se convierte al tipo numérico `N`, donde 0 representa falso y 1 representa verdadero. En V2, `bool` se convierte en `BOOL`.
  + En V2, las listas y las matrices no se agrupan con los HashSets. Las listas y las matrices de números, tipos basados en cadenas y tipos basados en binarios se convierten al tipo `L` (Lista), que se puede enviar vacío para actualizar una lista. A diferencia de V1, en la que no se envía una lista vacía por cable.

    En V1, los tipos de recopilaciones, como List, HashSet y matrices, se tratan de la misma manera. La lista, el HashSet y la matriz de números se convierten al tipo `NS` (conjunto de números). 

  El siguiente ejemplo establece la versión del esquema de conversión en V2, lo que cambia el comportamiento de conversión entre los tipos .NET y los tipos de datos de DynamoDB.

  ```
  var config = new DynamoDBContextConfig
  {
      Conversion = DynamoDBEntryConversion.V2
  };
  var contextV2 = new DynamoDBContext(client, config);
  ```

En los siguientes fragmentos de código C\$1 se crea un nuevo `DynamoDBContext` especificando dos de los parámetros opcionales anteriores, `ConsistentRead` y `SkipVersionCheck`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context =
       new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true});
```

`DynamoDBContext` incluye estos parámetros opcionales con cada solicitud que se envía utilizando este contexto. 

En lugar de establecer estos parámetros en el nivel de `DynamoDBContext`, puede especificarlos para las operaciones individuales que ejecute utilizando `DynamoDBContext`, como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo se carga un elemento de libro concreto. El método `Load` de `DynamoDBContext` especifica los parámetros opcionales `ConsistentRead` y `SkipVersionCheck`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context = new DynamoDBContext(client);
Book bookItem = context.Load<Book>(productId,new DynamoDBContextConfig{ ConsistentRead = true, SkipVersionCheck = true });
```

En este caso, `DynamoDBContext` incluye estos parámetros solo cuando se envía la solicitud `Get`.

# Bloqueo positivo mediante DynamoDB y el modelo de persistencia de objetos de AWS SDK para .NET
<a name="DynamoDBContext.VersionSupport"></a>

La compatibilidad del modelo de persistencia de objetos con el bloqueo optimista garantiza que la versión del elemento en la aplicación sea la misma que en el lado del servidor antes de actualizar o eliminar el elemento. Supongamos que recupera un elemento para actualizarlo. Sin embargo, antes de que se devuelvan las actualizaciones, otra aplicación actualiza el mismo elemento. Ahora, su aplicación tiene una copia anticuada del elemento. Sin el bloqueo optimista, cualquier actualización que lleve a cabo sobrescribirá la actualización efectuada por la otra aplicación. 

La característica de bloqueo optimista del modelo de persistencia de objetos proporciona la etiqueta `DynamoDBVersion`, que se puede usar para habilitar el bloqueo optimista. Para utilizar esta característica, se agrega una propiedad a la clase para almacenar el número de versión. Agregue el atributo `DynamoDBVersion` a la propiedad. La primera vez que se guarda el objeto, `DynamoDBContext` asigna un número de versión e incrementa este valor cada vez que se actualiza el elemento. 

Su solicitud de actualización o eliminación solamente se llevará 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 el lado del servidor. Si su aplicación contiene una copia anticuada, debe obtener la versión más reciente del servidor para poder actualizar o eliminar el elemento en cuestión.

En el siguiente ejemplo de código C\$1 se define una clase `Book` con atributos de persistencia de objetos que la mapean a la tabla `ProductCatalog`. La propiedad `VersionNumber` de la clase asociada con el atributo `DynamoDBVersion` almacena el valor del número de versión.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]   //Partition key
    public int Id { get; set; }
    [DynamoDBProperty]
    public string Title { get; set; }
    [DynamoDBProperty]
    public string ISBN { get; set; }
    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }
    [DynamoDBVersion]
    public int? VersionNumber { get; set; }
  }
```

**nota**  
Puede aplicar el atributo `DynamoDBVersion` solamente a un tipo numérico primitivo que pueda contener valores null (por ejemplo, `int?`). 

El bloqueo optimista afecta a las operaciones de `DynamoDBContext` como se indica a continuación:
+ Para un elemento nuevo, `DynamoDBContext` asigna el número de versión inicial 0. 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. `DynamoDBContext` aumenta el número de versión. No es necesario establecer el número de versión.
+ El método `Delete` proporciona sobrecargas que pueden tomar un valor de clave principal o un objeto como parámetro, como se muestra en el siguiente ejemplo de código C\$1.  
**Example**  

  ```
  DynamoDBContext context = new DynamoDBContext(client);
  ...
  // Load a book.
  Book book = context.Load<ProductCatalog>(111);
  // Do other operations.
  // Delete 1 - Pass in the book object.
  context.Delete<ProductCatalog>(book);
  
  // Delete 2 - Pass in the Id (primary key)
  context.Delete<ProductCatalog>(222);
  ```

  Si proporciona un objeto como parámetro, la eliminación solamente se llevará a cabo si la versión del objeto coincide con el número de versión del elemento correspondiente en el lado del servidor. Sin embargo, si proporciona un valor de clave principal como parámetro, `DynamoDBContext` no detectará los números de versión y eliminará el elemento sin comprobar la versión. 

  Tenga en cuenta que la implementación interna del bloqueo optimista en el código del modelo de persistencia de objetos utiliza las acciones de actualización condicional y eliminación condicional del API de DynamoDB.

## Deshabilitación del bloqueo positivo
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Para deshabilitar el bloqueo optimista, se usa la propiedad de configuración `SkipVersionCheck`. Puede establecer esta propiedad al crear `DynamoDBContext`. En este caso, el bloqueo optimista está deshabilitado para todas las solicitudes que se realicen utilizando el contexto. Para obtener más información, consulte [Especificación de parámetros opcionales para DynamoDBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

En lugar de establecer la propiedad para todo el contexto, puede deshabilitar el bloqueo optimista para una operación específica, tal y como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo de código se utiliza el contexto para eliminar un elemento de libro. El método `Delete` establece la propiedad `SkipVersionCheck` opcional en true, con lo que deshabilita la comprobación de versiones.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);
// Load a book.
Book book = context.Load<ProductCatalog>(111);
...
// Delete the book.
context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true });
```

# Mapeo de datos arbitrarios con DynamoDB mediante el modelo de persistencia de objetos de AWS SDK para .NET
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Además de los tipos de .NET admitidos (consulte [Tipos de datos compatibles](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), puede utilizar tipos de la aplicación para los cuales no exista un mapeo directo a los tipos de Amazon DynamoDB. El modelo de persistencia de objetos es compatible con el almacenamiento de datos de tipos arbitrarios, siempre y cuando se proporcione el convertidor requerido para convertir los datos del tipo arbitrario al tipo de DynamoDB y viceversa. El código del convertidor transforma los datos tanto al guardar como al cargar los objetos.

Puede crear cualquier tipo en el lado del cliente. Sin embargo, los datos almacenados en las tablas serán de uno de los tipos de DynamoDB. Además, durante las consultas y los exámenes, las comparaciones se harán respecto a los datos almacenados en DynamoDB.

En el siguiente ejemplo de código C\$1 se define una clase `Book` con las propiedades `Id`, `Title`, `ISBN` y `Dimension`. La propiedad `Dimension` es del tipo `DimensionType`, que describe las propiedades `Height`, `Width` y `Thickness`. En el ejemplo de código se proporcionan los métodos de convertidor `ToEntry` y `FromEntry` para convertir los datos entre el tipo `DimensionType` y el tipo String de DynamoDB. Por ejemplo, al,x guardar una instancia `Book`, el convertidor crea una cadena `Dimension` de libro tal como “8,5x11x0,05”. Cuando recupera un libro, convierte la cadena a una instancia `DimensionType`.

En el ejemplo se mapea el tipo `Book` a la tabla `ProductCatalog`. Guarda un ejemplo de instancia de `Book`, la recupera, actualiza sus dimensiones y vuelve a guardar `Book` una vez actualizado.



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

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class HighLevelMappingArbitraryData
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                DynamoDBContext context = new DynamoDBContext(client);

                // 1. Create a book.
                DimensionType myBookDimensions = new DimensionType()
                {
                    Length = 8M,
                    Height = 11M,
                    Thickness = 0.5M
                };

                Book myBook = new Book
                {
                    Id = 501,
                    Title = "AWS SDK for .NET Object Persistence Model Handling Arbitrary Data",
                    ISBN = "999-9999999999",
                    BookAuthors = new List<string> { "Author 1", "Author 2" },
                    Dimensions = myBookDimensions
                };

                context.Save(myBook);

                // 2. Retrieve the book.
                Book bookRetrieved = context.Load<Book>(501);

                // 3. Update property (book dimensions).
                bookRetrieved.Dimensions.Height += 1;
                bookRetrieved.Dimensions.Length += 1;
                bookRetrieved.Dimensions.Thickness += 0.2M;
                // Update the book.
                context.Save(bookRetrieved);

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }
    }
    [DynamoDBTable("ProductCatalog")]
    public class Book
    {
        [DynamoDBHashKey] //Partition key
        public int Id
        {
            get; set;
        }
        [DynamoDBProperty]
        public string Title
        {
            get; set;
        }
        [DynamoDBProperty]
        public string ISBN
        {
            get; set;
        }
        // Multi-valued (set type) attribute.
        [DynamoDBProperty("Authors")]
        public List<string> BookAuthors
        {
            get; set;
        }
        // Arbitrary type, with a converter to map it to DynamoDB type.
        [DynamoDBProperty(typeof(DimensionTypeConverter))]
        public DimensionType Dimensions
        {
            get; set;
        }
    }

    public class DimensionType
    {
        public decimal Length
        {
            get; set;
        }
        public decimal Height
        {
            get; set;
        }
        public decimal Thickness
        {
            get; set;
        }
    }

    // Converts the complex type DimensionType to string and vice-versa.
    public class DimensionTypeConverter : IPropertyConverter
    {
        public DynamoDBEntry ToEntry(object value)
        {
            DimensionType bookDimensions = value as DimensionType;
            if (bookDimensions == null) throw new ArgumentOutOfRangeException();

            string data = string.Format("{1}{0}{2}{0}{3}", " x ",
                            bookDimensions.Length, bookDimensions.Height, bookDimensions.Thickness);

            DynamoDBEntry entry = new Primitive
            {
                Value = data
            };
            return entry;
        }

        public object FromEntry(DynamoDBEntry entry)
        {
            Primitive primitive = entry as Primitive;
            if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value))
                throw new ArgumentOutOfRangeException();

            string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
            if (data.Length != 3) throw new ArgumentOutOfRangeException();

            DimensionType complexData = new DimensionType
            {
                Length = Convert.ToDecimal(data[0]),
                Height = Convert.ToDecimal(data[1]),
                Thickness = Convert.ToDecimal(data[2])
            };
            return complexData;
        }
    }
}
```

# Cómo ejecutar los ejemplos de código de esta guía para desarrolladores
<a name="CodeSamples"></a>

Los SDK de AWS proporcionan un amplio soporte para Amazon DynamoDB en los siguientes lenguajes:
+ [ Java](https://aws.amazon.com/sdk-for-java)
+ [JavaScript en el navegador](https://aws.amazon.com/sdk-for-browser)
+ [.NET](https://aws.amazon.com/sdk-for-net)
+ [Node.js](https://aws.amazon.com/sdk-for-node-js)
+ [PHP](https://aws.amazon.com/sdk-for-php)
+ [Python](https://aws.amazon.com/sdk-for-python)
+ [Ruby](https://aws.amazon.com/sdk-for-ruby)
+ [C\$1\$1](https://aws.amazon.com/sdk-for-cpp)
+ [Go](https://aws.amazon.com/sdk-for-go)
+ [Android](https://aws.amazon.com/mobile/sdk/)
+ [iOS](https://aws.amazon.com/mobile/sdk/)

Los ejemplos de código de esta guía para desarrolladores ofrecen una cobertura más exhaustiva de las operaciones de DynamoDB en los siguientes lenguajes de programación:
+ [Ejemplos de código Java](CodeSamples.Java.md)
+ [Ejemplos de código .NET](CodeSamples.DotNet.md)

Antes de comenzar con este ejercicio, es preciso crear una cuenta de AWS, obtener la clave de acceso y la clave secreta, y configurar la AWS Command Line Interface (AWS CLI) en el ordenador. Para obtener más información, consulte [Configuración de DynamoDB (servicio web)](SettingUp.DynamoWebService.md).

**nota**  
Si va a utilizar la versión descargable de DynamoDB, debe utilizar la AWS CLI para crear las tablas y los ejemplos de datos. Asimismo, debe especificar el parámetro `--endpoint-url` en cada comando de la AWS CLI. Para obtener más información, consulte [Configuración del punto de conexión local](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint).

# Creación de tablas y carga de datos para ejemplos de código en DynamoDB
<a name="SampleData"></a>

Consulte a continuación los conceptos básicos sobre la creación de tablas en DynamoDB, la carga de un conjunto de datos de ejemplo, la consulta de los datos y su actualización.
+ [Paso 1: crear una tabla en DynamoDB](getting-started-step-1.md)
+ [Paso 2: escribir datos en una tabla de DynamoDB](getting-started-step-2.md)
+ [Paso 3: leer datos de una tabla de DynamoDB](getting-started-step-3.md)
+ [Paso 4: actualizar los datos de una tabla de DynamoDB](getting-started-step-4.md)

# Ejemplos de código Java
<a name="CodeSamples.Java"></a>

**Topics**
+ [Java: configuración de las credenciales de AWS](#CodeSamples.Java.Credentials)
+ [Java: configuración de la región y del punto de conexión de AWS](#CodeSamples.Java.RegionAndEndpoint)

Esta Guía para desarrolladores contiene fragmentos de código Java y programas listos para ejecutarlos. Encontrará estos ejemplos de código en las secciones siguientes:
+ [Uso de elementos y atributos en DynamoDB](WorkingWithItems.md)
+ [Uso de tablas y datos en DynamoDB](WorkingWithTables.md)
+ [Consulta de tablas en DynamoDB](Query.md)
+ [Análisis de tablas en DynamoDB](Scan.md)
+ [Mejora del acceso con índices secundarios en DynamoDB](SecondaryIndexes.md)
+ [Java 1.x: DynamoDBMapper](DynamoDBMapper.md)
+ [Captura de datos de cambios para DynamoDB Streams](Streams.md)

Puede comenzar rápidamente a trabajar con Eclipse y [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/). Además de un IDE completo, obtendrá AWS SDK para Java con actualizaciones automáticas y plantillas preconfiguradas para crear aplicaciones de AWS.

**Para ejecutar los ejemplos de código Java (con Eclipse)**

1. Descargue e instale el IDE de [Eclipse](http://www.eclipse.org).

1. Descargue e instale el [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/).

1. Inicie Eclipse y, en el menú **Eclipse**, elija **File (Archivo)**, **New (Nuevo)** y después **Other (Otro)**.

1. En **Seleccionar un asistente**, elija **AWS**, **Proyecto de Java de AWS** y, después, **Siguiente**.

1. En **Crear una instancia de Java de AWS**, haga lo siguiente:

   1. En **Nombre del proyecto**, introduzca un nombre para el proyecto.

   1. En **Select Account (Seleccionar cuenta)**, elija su perfil de credenciales en la lista.

      Si es la primera vez que utiliza [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/), elija **Configurar cuentas de AWS** para configurar las credenciales de AWS.

1. Elija **Finish (Finalizar)** para crear el proyecto.

1. En el menú **Eclipse**, elija **File (Archivo)**, **New (Nuevo)** y después **Class (Clase)**.

1. En **Java Class (Clase Java)**, introduzca un nombre para la clase en **Name (Nombre)** (use el mismo nombre que en el ejemplo de código que desea ejecutar) y, a continuación, elija **Finish (Finalizar)** para crear la clase.

1. Copie el ejemplo de código de la página de documentación en el editor de Eclipse.

1. Para ejecutar el código, elija **Run (Ejecutar)** en el menú Eclipse.

El SDK para Java proporciona clientes seguros para subprocesos con el fin de trabajar con DynamoDB. Como práctica recomendada, sus aplicaciones deben crear un cliente y reutilizar el cliente entre subprocesos.

Para obtener más información, consulte la [AWS SDK para Java](https://aws.amazon.com/sdk-for-java).

**nota**  
Los ejemplos de código de esta guía se han diseñado para utilizarlos con la última versión del AWS SDK para Java.  
Si utiliza AWS Toolkit for Eclipse, puede configurar las actualizaciones automáticas para el SDK para Java. Para hacer esto en Eclipse, vaya a **Preferences (Preferencias)** y elija **AWS Toolkit**, **AWS SDK para Java**, **Download new SDKs automatically (Descargar nuevos SDK automáticamente)**.

## Java: configuración de las credenciales de AWS
<a name="CodeSamples.Java.Credentials"></a>

El SDK para Java requiere que proporcione las credenciales de AWS a su aplicación en tiempo de ejecución. En los ejemplos de código de esta guía se supone que se usa un archivo de credenciales de AWS, tal como se describe en [Configuración de las credenciales de AWS](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html) en la *Guía para desarrolladores de AWS SDK para Java*.

A continuación se muestra un ejemplo de archivo de credenciales de AWS denominado `~/.aws/credentials`, donde el carácter de tilde (`~`) representa su directorio de inicio.

```
[default]
aws_access_key_id = AWS access key ID goes here
aws_secret_access_key = Secret key goes here
```

## Java: configuración de la región y del punto de conexión de AWS
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

De forma predeterminada, los ejemplos de código acceden a DynamoDB en la región EE. UU. Oeste (Oregón). Puede cambiar la región modificando las propiedades de `AmazonDynamoDB`.

En el siguiente ejemplo de código se crea una nueva instancia de `AmazonDynamoDB`.

```
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import com.amazonaws.regions.Regions;
...
// This client will default to US West (Oregon)
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.build();
```

Puede usar el método `withRegion` para ejecutar el código en DynamoDB en cualquier región donde se encuentre disponible. Para obtener una lista completa, consulte [Regiones de AWS y puntos de conexión](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) en la *Referencia general de Amazon Web Services*.

Si desea ejecutar los ejemplos de código en DynamoDB localmente en su ordenador, configure el punto de enlace como se indica a continuación.

### AWSSDK de V1
<a name="CodeSamples.Java.RegionAndEndpoint.V1"></a>

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
```

### AWSSDK de V2
<a name="CodeSamples.Java.RegionAndEndpoint.V2"></a>

```
DynamoDbClient client = DynamoDbClient.builder()
    .endpointOverride(URI.create("http://localhost:8000"))
    // The region is meaningless for local DynamoDb but required for client builder validation
    .region(Region.US_EAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(
    AwsBasicCredentials.create("dummy-key", "dummy-secret")))
    .build();
```

# Ejemplos de código .NET
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [.NET: configuración de las credenciales de AWS](#CodeSamples.DotNet.Credentials)
+ [.NET: configuración de la región y del punto de conexión de AWS](#CodeSamples.DotNet.RegionAndEndpoint)

Esta guía contiene fragmentos de código .NET y programas listos para ejecutarlos. Encontrará estos ejemplos de código en las secciones siguientes:
+ [Uso de elementos y atributos en DynamoDB](WorkingWithItems.md)
+ [Uso de tablas y datos en DynamoDB](WorkingWithTables.md)
+ [Consulta de tablas en DynamoDB](Query.md)
+ [Análisis de tablas en DynamoDB](Scan.md)
+ [Mejora del acceso con índices secundarios en DynamoDB](SecondaryIndexes.md)
+ [Uso del modelo de documento de .NET en DynamoDB](DotNetSDKMidLevel.md)
+ [Uso del modelo de persistencia de objetos de .NET y DynamoDB](DotNetSDKHighLevel.md)
+ [Captura de datos de cambios para DynamoDB Streams](Streams.md)

Puede comenzar rápidamente a trabajar utilizando AWS SDK para .NET con Toolkit for Visual Studio.

**Para ejecutar los ejemplos de código .NET (mediante Visual Studio)**

1. Descargue e instale [Microsoft Visual Studio](https://www.visualstudio.com).

1. (Opcional) Descargue e instale [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/).

1. Configure sus credenciales de AWS. Configure un perfil de credenciales en su archivo de credenciales de AWS compartido (`~/.aws/credentials`). Para obtener más información, consulte [Configuración de credenciales de AWS](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) en la *Guía para desarrolladores de AWS SDK para .NET*.

1. Inicie Visual Studio. Elija **File (Archivo)**, **New (Nuevo)**, **Project (Proyecto)**.

1. Busque la **Aplicación de consola**, seleccione la plantilla de C\$1 destinada a .NET y, a continuación, elija **Siguiente**. Configure el nombre y la ubicación del proyecto y, a continuación, seleccione **Crear**.

1. Agregue el paquete AWS SDK para DynamoDB NuGet al proyecto:

   1. En el Explorador de soluciones, abra el menú contextual (haga clic con el botón derecho) del proyecto y elija **Administrar paquetes NuGet**.

   1. En Administrador de paquetes NuGet, elija **Examinar**.

   1. En el cuadro de búsqueda, introduzca **AWSSDK.DynamoDBv2** y espere a que se lleve a cabo la búsqueda.

   1. Elija **AWSSDK.DynamoDBv2** y después elija **Install (Instalar)**.

1. En el proyecto de Visual Studio, abra `Program.cs`. Sustituya el contenido por el código de ejemplo de la página de documentación que desee ejecutar.

1. Para ejecutar el código, elija **Iniciar** en la barra de herramientas de Visual Studio.

SDK para .NET proporciona clientes seguros para subprocesos con el fin de trabajar con DynamoDB. Como práctica recomendada, sus aplicaciones deben crear un cliente y reutilizar el cliente entre subprocesos.

Para obtener más información, consulte [AWS SDK para .NET](https://aws.amazon.com/sdk-for-net).

**nota**  
Los ejemplos de código de esta guía se han diseñado para utilizarlos con la última versión del AWS SDK para .NET.

## .NET: configuración de las credenciales de AWS
<a name="CodeSamples.DotNet.Credentials"></a>

SDK para .NET requiere que proporcione las credenciales de AWS a su aplicación en tiempo de ejecución. En los ejemplos de código de esta guía se supone que se usa el SDK Store para administrar el archivo de credenciales de AWS, tal como se describe en [Uso del SDK Store](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store) en la *Guía para desarrolladores de AWS SDK para .NET*.

Toolkit for Visual Studio admite varios conjuntos de credenciales de cualquier cantidad de cuentas. Cada conjunto se conoce como *perfil*. Visual Studio agrega entradas al archivo `App.config` del proyecto, para que la aplicación encuentre las credenciales de AWS en tiempo de ejecución.

En el siguiente ejemplo se muestra el archivo `App.config` predeterminado que se genera al crear un nuevo proyecto con Toolkit for Visual Studio.

```
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
    <add key="AWSProfileName" value="default"/>
    <add key="AWSRegion" value="us-west-2" />
 </appSettings>
</configuration>
```

En tiempo de ejecución, el programa usa el conjunto `default` de credenciales de AWS, según lo especificado en la entrada `AWSProfileName`. Las credenciales de AWS en sí se conservan en SDK Store, cifradas. Toolkit for Visual Studio proporciona una interfaz gráfica de usuario para administrar las credenciales, todo ello desde Visual Studio. Para obtener más información, consulte [Especificación de credenciales](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds) en la *Guía del usuario de AWS Toolkit for Visual Studio*.

**nota**  
De forma predeterminada, los ejemplos de código acceden a DynamoDB en la región EE. UU. Oeste (Oregón). Puede cambiar la región modificando la entrada `AWSRegion` en el archivo App.config. Puede establecer `AWSRegion` en cualquier región donde DynamoDB esté disponible. Para obtener una lista completa, consulte [Regiones de AWS y puntos de conexión](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) en la *Referencia general de Amazon Web Services*.

## .NET: configuración de la región y del punto de conexión de AWS
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

De forma predeterminada, los ejemplos de código acceden a DynamoDB en la región EE. UU. Oeste (Oregón). Puede cambiar la región modificando la entrada `AWSRegion` en el archivo `App.config`. O bien puede cambiar la región modificando las propiedades de `AmazonDynamoDBClient`.

En el siguiente ejemplo de código se crea una nueva instancia de `AmazonDynamoDBClient`. El cliente se modifica de tal forma que el código se ejecute en DynamoDB en otra región.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// This client will access the US East 1 region.
clientConfig.RegionEndpoint = RegionEndpoint.USEast1;
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

Para obtener una lista completa de las regiones, consulte [Regiones de AWS y puntos de conexión](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) en la *Referencia general de Amazon Web Services*.

Si desea ejecutar los ejemplos de código en DynamoDB localmente en su ordenador, configure el punto de enlace como se indica a continuación.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// Set the endpoint URL
clientConfig.ServiceURL = "http://localhost:8000";
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

# API de bajo nivel de DynamoDB
<a name="Programming.LowLevelAPI"></a>

La *API de bajo nivel* de Amazon DynamoDB es la interfaz de nivel de protocolo de DynamoDB. En este nivel, cada solicitud HTTP(S) debe tener el formato correcto y llevar una firma digital válida.

Los SDK de AWS construyen las solicitudes a la API de bajo nivel de DynamoDB automáticamente y procesan las respuestas de DynamoDB. Esto le permite centrarse en la lógica de la aplicación, en lugar de en los detalles de bajo nivel. Sin embargo, le resultará útil conocer algunos conceptos básicos del funcionamiento de la API de bajo nivel de DynamoDB.

Para obtener más información sobre la API de DynamoDB de bajo nivel, consulte[Referencia de la API de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**nota**  
DynamoDB Streams tiene su propio API de bajo nivel, que es independiente de la de DynamoDB y totalmente compatible con los SDK de AWS.  
Para obtener más información, consulte [Captura de datos de cambios para DynamoDB Streams](Streams.md). Para la API de DynamoDB Streams de bajo nivel, consulte la. [Referencia de la API de Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html).

La API de bajo nivel de DynamoDB utiliza la notación de objetos de JavaScript (JSON, JavaScript Object Notation) como formato de protocolo de conexión. JSON presenta los datos de forma jerárquica para transmitir simultáneamente sus valores y su estructura. Los pares de nombre-valor se definen con el formato `name:value`. La jerarquía de datos se define mediante llaves anidadas de pares de nombre-valor.

DynamoDB usa JSON como protocolo de transporte únicamente, no como formato de almacenamiento. Los SDK de AWS usan JSON para enviar datos a DynamoDB y DynamoDB responde con JSON. DynamoDB no almacena datos de forma persistente en formato JSON.

**nota**  
Para obtener más información acerca de JSON, consulte [Introducing JSON](http://json.org) en el sitio web `JSON.org`.

**Topics**
+ [Formato de solicitudes](#Programming.LowLevelAPI.RequestFormat)
+ [Formato de respuesta](#Programming.LowLevelAPI.ResponseFormat)
+ [Descriptores de tipos de datos](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [Datos numéricos](#Programming.LowLevelAPI.Numbers)
+ [Datos binarios](#Programming.LowLevelAPI.Binary)

![\[La API de bajo nivel de DynamoDB y la forma en que los AWS SDK gestionan las solicitudes y respuestas de protocolos.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## Formato de solicitudes
<a name="Programming.LowLevelAPI.RequestFormat"></a>

La API de bajo nivel de DynamoDB acepta solicitudes `POST` de HTTP(S) como información de entrada. Los SDK de AWS construyen estas solicitudes automáticamente.

Supongamos que dispone de una tabla denominada `Pets`, con un esquema de claves que consta de `AnimalType` (clave de partición) y `Name` (clave de ordenación). Ambos atributos son de tipo `string`. Para recuperar un elemento de `Pets`, el SDK de AWS construye la siguiente solicitud.

```
POST / HTTP/1.1
Host: dynamodb.<region>.<domain>;
Accept-Encoding: identity
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.0
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature>
X-Amz-Date: <Date> 
X-Amz-Target: DynamoDB_20120810.GetItem

{
    "TableName": "Pets",
    "Key": {
        "AnimalType": {"S": "Dog"},
        "Name": {"S": "Fido"}
    }
}
```

Tenga en cuenta lo siguiente en relación con esta solicitud:
+ El encabezado `Authorization` contiene la información necesaria para que DynamoDB autentique la solicitud. Para obtener más información, consulte [Firma de solicitudes de API AWS](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) y [Proceso de firma de Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) en la *Referencia general de Amazon Web Services*.
+ El encabezado `X-Amz-Target` contiene el nombre de una operación de DynamoDB, `GetItem`. Además, va acompañada de la versión del API de bajo nivel, en este caso, . `20120810`.)
+ La carga (cuerpo) de la solicitud contiene los parámetros de la operación, en formato JSON. En la operación `GetItem`, los parámetros son `TableName` y `Key`.

## Formato de respuesta
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

Una vez que recibe la solicitud, DynamoDB la procesa y devuelve una respuesta. Para la solicitud mostrada anteriormente, la carga de la respuesta HTTP(S) contiene los resultados de la operación, como se muestra en el siguiente ejemplo.

```
HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{
    "Item": {
        "Age": {"N": "8"},
        "Colors": {
            "L": [
                {"S": "White"},
                {"S": "Brown"},
                {"S": "Black"}
            ]
        },
        "Name": {"S": "Fido"},
        "Vaccinations": {
            "M": {
                "Rabies": {
                    "L": [
                        {"S": "2009-03-17"},
                        {"S": "2011-09-21"},
                        {"S": "2014-07-08"}
                    ]
                },
                "Distemper": {"S": "2015-10-13"}
            }
        },
        "Breed": {"S": "Beagle"},
        "AnimalType": {"S": "Dog"}
    }
}
```

En este momento, el SDK de AWS devuelve los datos de respuesta a la aplicación para continuar procesándolos.

**nota**  
Si DynamoDB no puede procesar una solicitud, devuelve un código de error HTTP y un mensaje. El SDK de AWS los propaga a su aplicación, en forma de excepciones. Para obtener más información, consulte [Control de errores con DynamoDB](Programming.Errors.md).

## Descriptores de tipos de datos
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

El protocolo de la API de bajo nivel de DynamoDB requiere que cada atributo vaya acompañado de un descriptor del tipo de datos. Los *descriptores de tipos de datos* son tokens que indican a DynamoDB cómo interpretar cada atributo.

En las secciones [Formato de solicitudes](#Programming.LowLevelAPI.RequestFormat) y [Formato de respuesta](#Programming.LowLevelAPI.ResponseFormat) encontrará ejemplos de cómo se usan los descriptores de tipos de datos. En la solicitud `GetItem` se especifica `S` para los atributos del esquema de claves de `Pets` (`AnimalType` y `Name`), que son de tipo `string`. La respuesta `GetItem` contiene un elemento *Pets* con atributos de tipo `string` (`S`), `number` (`N`), `map` (`M`) y `list` (`L`).

A continuación se muestra una lista completa de descriptores de tipos de datos de DynamoDB:
+ **`S`** – cadena
+ **`N`** – número
+ **`B`** – Binary
+ **`BOOL`** – booleano
+ **`NULL`** – Null
+ **`M`** – mapa
+ **`L`** – List
+ **`SS`** – String Set
+ **`NS`** – Number Set
+ **`BS`** – Binary Set

En la tabla siguiente, se muestra el formato JSON de cada descriptor de tipo de datos. Tenga en cuenta que los números se representan como cadenas para preservar la precisión, mientras que los valores booleanos y nulos utilizan sus tipos JSON nativos.


| Descriptor | Formato JSON | Notas | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | El valor es una cadena JSON. | 
| N | \$1"N": "123.45"\$1 | El valor es una cadena, no un número JSON. Esto preserva la precisión en todos los idiomas. | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | El valor es una cadena codificada en base64. | 
| BOOL | \$1"BOOL": true\$1 | El valor es un booleano JSON (true o false), no una cadena. | 
| NULL | \$1"NULL": true\$1 | El valor es el booleano JSON true para indicar nulo. | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | El valor es un objeto JSON de pares nombre-valor de un atributo. | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | El valor es una matriz JSON de valores de atributos. | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | El valor es una matriz JSON de cadenas. | 
| NS | \$1"NS": ["1", "2.5"]\$1 | El valor es una matriz JSON de cadenas de números. | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | El valor es una matriz JSON de cadenas codificadas en base64. | 

**nota**  
 Para obtener descripciones detalladas de los tipos de datos de DynamoDB, consulte [Tipos de datos](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes).

## Datos numéricos
<a name="Programming.LowLevelAPI.Numbers"></a>

Los distintos lenguajes de programación ofrecen diferentes niveles de compatibilidad con JSON. En algunos casos, es posible que prefiera usar una biblioteca de terceros para validar y analizar los documentos JSON.

Algunas bibliotecas de terceros se basan en el tipo Number de JSON y proporcionan sus propios tipos, tales como `int`, `long` o `double`. Sin embargo, el tipo de datos Number nativo de DynamoDB no se mapea exactamente a estos otros tipos de datos, por lo que estas diferencias entre los tipos pueden provocar conflictos. Además, muchas bibliotecas JSON no controlan los valores numéricos con una precisión fija y deducen automáticamente que el tipo de datos de las secuencias que contienen una coma decimal es double.

Para resolver estos problemas, DynamoDB proporciona un único tipo numérico sin pérdida de datos. Para evitar conversiones implícitas no deseadas a un valor de tipo double, DynamoDB utiliza cadenas para efectuar la transferencia de datos de valores numéricos. Este enfoque proporciona flexibilidad para actualizar los valores de los atributos y, al mismo tiempo, mantener una semántica de ordenación adecuada; por ejemplo, colocar los valores "01", "2" y "03" en la secuencia correcta.

Si la precisión del número es importante para la aplicación, debe convertir los valores numéricos en cadenas antes de pasárselos a DynamoDB.

## Datos binarios
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB es compatible con los atributos binarios. Sin embargo, JSON no presenta compatibilidad nativa con la codificación de datos binarios. Para enviar datos binarios en una solicitud, es preciso codificarlos en formato base64. Al recibir la solicitud, DynamoDB decodifica los datos base64 para que vuelvan a ser binarios. 

El esquema de codificación base64 que se utiliza en DynamoDB se describe en [RFC 4648](http://tools.ietf.org/html/rfc4648) en el sitio web de IETF (Internet Engineering Task Force).