

# Interfaces de programação de nível superior para o DynamoDB
<a name="HigherLevelInterfaces"></a>

Os AWS SDKs fornecem aplicações com interfaces de baixo nível para trabalhar com o Amazon DynamoDB. Estes métodos e classes no lado do cliente correspondem diretamente à API de baixo nível do DynamoDB. No entanto, muitos desenvolvedores experimentam uma sensação de desconexão, ou *incompatibilidade de impedância*, quando precisam mapear tipos de dados complexos para itens em uma tabela de banco de dados. Com uma interface de banco de dados de baixo nível, os desenvolvedores precisam escrever métodos para a leitura ou a gravação de dados de objetos em tabelas de banco de dados e vice-versa. A quantidade de código extra necessária para cada combinação de tipo de objeto e tabela de banco de dados pode parecer esmagadora.

Para simplificar o desenvolvimento, os AWS SDKs for Java e .NET fornecem interfaces adicionais com níveis mais altos de abstração. As interfaces de nível superior para o DynamoDB permitem que você defina as relações entre objetos no seu programa e as tabelas de banco de dados que armazenam os dados desses objetos. Depois de definir esse mapeamento, você chama métodos de objeto simples, como `save`, `load` ou `delete`, e as operações de baixo nível do DynamoDB subjacente são invocadas automaticamente em seu nome. Isso permite que você escreva um código centrado em objetos, em vez de um código centrado no banco de dados.

Interfaces de programação de nível superior para o DynamoDB estão disponíveis nos AWS SDKs for Java e .NET.

**Java**
+ [Java 1.x: DynamoDBMapper](DynamoDBMapper.md)
+ [Java 2.x: Cliente Aprimorado do DynamoDB](DynamoDBEnhanced.md)

**.NET**
+ [Trabalhar com o modelo de documento do .NET no DynamoDB](DotNetSDKMidLevel.md)
+ [Trabalhar com o modelo de persistência de objetos do .NET e o DynamoDB](DotNetSDKHighLevel.md)

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

**nota**  
O SDK para Java tem duas versões: 1.x e 2.x. O fim do suporte para a versão 1.x foi [anunciado](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) em 12 de janeiro de 2024. Ele está previsto para 31 de dezembro de 2025. Para novos desenvolvimentos, é altamente recomendável que você use a versão 2.x.

O AWS SDK para Java fornece uma classe `DynamoDBMapper`, permitindo mapear classes no lado do cliente para tabelas do Amazon DynamoDB. Para usar `DynamoDBMapper`, defina a relação entre os itens em uma tabela do DynamoDB e as instâncias de objeto correspondentes no seu código. A classe `DynamoDBMapper` permite que você realize várias operações de criação, leitura, atualização e exclusão (CRUD) em itens e execute consultas e verificações em tabelas.

**Topics**
+ [Classe DynamoDBMapper](DynamoDBMapper.Methods.md)
+ [Tipos de dados compatíveis com DynamoDBMapper para Java](DynamoDBMapper.DataTypes.md)
+ [Anotações Java para DynamoDB](DynamoDBMapper.Annotations.md)
+ [Definições de configuração opcionais para DynamoDBMapper](DynamoDBMapper.OptionalConfig.md)
+ [DynamoDB e bloqueio positivo com número de versão](DynamoDBMapper.OptimisticLocking.md)
+ [Mapear dados arbitrários no DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md)
+ [Exemplos de DynamoDBMapper](DynamoDBMapper.Examples.md)

**nota**  
A classe `DynamoDBMapper` não permite criar, atualizar ou excluir tabelas. Para realizar essas tarefas, use em vez disso a interface do SDK para Java de baixo nível.

O SDK para Java fornece um conjunto de tipos de anotações, para que você possa mapear suas classes em tabelas. Por exemplo, considere uma tabela `ProductCatalog` cujo `Id` seja a chave de partição. 

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

É possível mapear uma classe no seu aplicativo cliente para a tabela `ProductCatalog`, conforme mostrado no código Java a seguir. Este código define um objeto Java antigo simples (POJO) chamado `CatalogItem` que usa anotações para mapear campos de objeto em nomes de atributos do 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; }
}
```

No código anterior, a anotação `@DynamoDBTable` mapeia a classe `CatalogItem` para a tabela `ProductCatalog`. Você pode armazenar instâncias de classes individuais como itens na tabela. Na definição de classe, a anotação `@DynamoDBHashKey` mapeia a propriedade `Id` para a chave primária. 

Por padrão, as propriedades da classe são mapeadas para os atributos com o mesmo nome na tabela. As propriedades `Title` e `ISBN` são mapeadas para os atributos com o mesmo nome na tabela. 

A anotação `@DynamoDBAttribute` é opcional quando o nome do atributo do DynamoDB corresponde ao nome da propriedade declarada na classe. Quando esses nomes são diferentes, use essa anotação com o parâmetro `attributeName` para especificar a qual atributo do DynamoDB essa propriedade corresponde. 

No exemplo anterior, a anotação `@DynamoDBAttribute` é adicionada a cada propriedade para garantir que os nomes de propriedades correspondam exatamente às tabelas criadas em uma etapa anterior e sejam consistentes com os nomes de atributos usados em outros exemplos de código neste guia. 

Sua definição de classe pode ter propriedades que não são mapeadas para atributos na tabela. Para identificar essas propriedades, adicione a anotação `@DynamoDBIgnore`. No exemplo anterior, a propriedade `SomeProp` está marcada com a anotação `@DynamoDBIgnore`. Ao carregar uma instância `CatalogItem` na tabela, sua instância `DynamoDBMapper` não inclui a propriedade `SomeProp`. Além disso, o mapeador não retorna esse atributo quando você recupera um item da tabela. 

Depois de definir sua classe de mapeamento, é possível usar métodos `DynamoDBMapper` para gravar uma instância dessa classe em um item correspondente na tabela `Catalog`. O exemplo de código a seguir demonstra essa 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);
```

O exemplo de código a seguir mostra como recuperar o item e acessar alguns dos seus 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`O oferece uma forma intuitiva e natural de trabalhar com dados do DynamoDB no Java. Ele também fornece uma série de recursos internos, como bloqueio otimista, transações ACID, valores de chave de partição e chave de classificação gerados automaticamente e versionamento de objetos.

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



A classe `DynamoDBMapper` é o ponto de entrada do Amazon DynamoDB. Ela dá acesso a um endpoint do DynamoDB e permite acessar seus dados em várias tabelas. Ela também permite realizar várias operações de criação, leitura, atualização e exclusão (CRUD) em itens e executar consultas e verificações em tabelas. Essa classe fornece os seguintes métodos para trabalhar com o DynamoDB.

Para acessar a documentação Javadoc correspondente, consulte [DynamoDBMapper](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) no *Referência da API do AWS SDK para Java*.

**Topics**
+ [save](#DynamoDBMapper.Methods.save)
+ [balanceamento](#DynamoDBMapper.Methods.load)
+ [excluir](#DynamoDBMapper.Methods.delete)
+ [consultar](#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)
+ [contagem](#DynamoDBMapper.Methods.count)
+ [generateCreateTableRequest](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [createS3Link](#DynamoDBMapper.Methods.createS3Link)
+ [getS3ClientCache](#DynamoDBMapper.Methods.getS3ClientCache)

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

Salva o objeto especificado na tabela. O objeto que você deseja salvar é o único parâmetro necessário para esse método. É possível fornecer parâmetros de configuração opcionais usando o objeto `DynamoDBMapperConfig`. 

Se um item com a mesma chave primária não existir, esse método criará um novo item na tabela. Se existir um item com a mesma chave primária, ele atualizará o item existente. Se a chave de partição e a chave de classificação forem do tipo String e estiverem anotadas com `@DynamoDBAutoGeneratedKey`, elas receberão um identificador universal exclusivo (UUID) aleatório se não forem inicializadas. Campos de versão anotados com `@DynamoDBVersionAttribute` são incrementados em um. Além disso, se um campo de versão for atualizado ou se uma chave for gerada, o objeto transmitido será atualizado como resultado da operação. 

Por padrão, somente atributos correspondentes às propriedades de classe mapeadas são atualizados. Quaisquer atributos existentes em um item não são afetados. No entanto, se você especificar `SaveBehavior.CLOBBER`, poderá forçar o item a ser completamente substituído.

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

Se o versionamento estiver habilitado, as versões dos itens no lado do servidor e no lado do cliente deverão corresponder. No entanto, a versão não precisará corresponder se a opção `SaveBehavior.CLOBBER` for usada. Para obter mais informações sobre versionamento, consulte [DynamoDB e bloqueio positivo com número de versão](DynamoDBMapper.OptimisticLocking.md).

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

Recupera um item de uma tabela. É necessário fornecer a chave primária do item que você deseja recuperar. É possível fornecer parâmetros de configuração opcionais usando o objeto `DynamoDBMapperConfig`. Por exemplo, você pode solicitar opcionalmente leituras altamente consistentes para garantir que esse método recupere apenas os valores de itens mais recentes, como mostra a seguinte instrução Java. 

```
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
    .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT).build();

CatalogItem item = mapper.load(CatalogItem.class, item.getId(), config);
```

Por padrão, o DynamoDB retorna o item que possui valores finais consistentes. Para obter informações sobre o modelo de consistência eventual do DynamoDB, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

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

Exclui um item da tabela. Você deve transmitir uma instância do objeto da classe mapeada. 

Se o versionamento estiver habilitado, as versões dos itens no lado do servidor e no lado do cliente deverão corresponder. No entanto, a versão não precisará corresponder se a opção `SaveBehavior.CLOBBER` for usada. Para obter mais informações sobre versionamento, consulte [DynamoDB e bloqueio positivo com número de versão](DynamoDBMapper.OptimisticLocking.md). 

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

Consulta uma tabela ou um índice secundário.

Vamos supor que você tenha uma tabela, `Reply`, que armazena as respostas de tópicos de fórum. Cada assunto de tópico pode ter 0 ou mais respostas. A chave primária da tabela `Reply` consiste nos campos `Id` e `ReplyDateTime`, em que `Id` é a chave de partição e `ReplyDateTime` é a chave de classificação da chave primária.

```
Reply ( Id, ReplyDateTime, ... )
```

Vamos supor que você tenha criado um mapeamento entre uma classe `Reply` e a tabela `Reply` correspondente no DynamoDB. O código Java a seguir usa `DynamoDBMapper` para localizar todas as respostas nas últimas duas semanas para um assunto de tópico específico.

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

A consulta retorna uma coleção de objetos `Reply`. 

Por padrão, o método `query` retorna uma coleção de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, faça uma iteração na coleção `latestReplies`. 

Observe que chamar o método `size()` na coleção carregará todos os resultados para fornecer uma contagem precisa. Isso pode fazer com que uma grande quantidade de throughput provisionado seja consumida, e em uma tabela muito grande pode até esgotar toda a memória na JVM.

Para consultar um índice, você deve primeiro modelá-lo como uma classe de mapeador. Suponha que a tabela `Reply` tenha um índice global secundário chamado *PostedBy-Message-Index*. A chave de partição para esse índice é `PostedBy`, e a chave de classificação é `Message`. A definição de classe para um item no índice seria semelhante ao seguinte.

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

A anotação `@DynamoDBTable` indica que esse índice está associado à tabela `Reply`. A anotação `@DynamoDBIndexHashKey` representa a chave de partição (*PostedBy*) do índice, enquanto `@DynamoDBIndexRangeKey` representa a chave de classificação (*Message*) do índice.

Agora, você pode usar `DynamoDBMapper` para consultar o índice, recuperando um subconjunto das mensagens que foram postadas por um usuário específico. Você não precisará especificar o nome do índice se não tiver mapeamentos conflitantes entre tabelas e índices e se os mapeamentos já tiverem sido feitos no mapeador. O mapeador vai inferir com base na chave primária e na chave de classificação. O código a seguir consulta um índice secundário global. Como um índice secundário global oferece suporte para leituras finais consistentes, mas não para leituras altamente consistentes, é necessário especificar `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);
```

A consulta retorna uma coleção de objetos `PostedByMessage`.

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

Consulta uma tabela ou um índice secundário e retorna uma única página de resultados correspondentes. Como acontece com o método `query`, você deve especificar um valor de chave de partição e um filtro de consulta que seja aplicado ao atributo de chave de classificação. No entanto, `queryPage` retorna somente a primeira "página" de dados, ou seja, a quantidade de dados que caberá em 1 MB 

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

Verifica uma tabela ou um índice secundário inteiro. Você tem a opção de especificar uma `FilterExpression` para filtrar o conjunto de resultados.

Vamos supor que você tenha uma tabela, `Reply`, que armazena as respostas de tópicos de fórum. Cada assunto de tópico pode ter 0 ou mais respostas. A chave primária da tabela `Reply` consiste nos campos `Id` e `ReplyDateTime`, em que `Id` é a chave de partição e `ReplyDateTime` é a chave de classificação da chave primária.

```
Reply ( Id, ReplyDateTime, ... )
```

Se você mapeou uma classe Java para a tabela `Reply`, será possível usar `DynamoDBMapper` para verificar essa tabela. Por exemplo, o código Java a seguir verifica a tabela `Reply` inteira, retornando somente as respostas de um determinado ano.

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

Por padrão, o método `scan` retorna uma coleção de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, faça uma iteração na coleção `replies`.

Observe que chamar o método `size()` na coleção carregará todos os resultados para fornecer uma contagem precisa. Isso pode fazer com que uma grande quantidade de throughput provisionado seja consumida, e em uma tabela muito grande pode até esgotar toda a memória na JVM.

Para verificar um índice, você deve primeiro modelá-lo como uma classe de mapeador. Suponha que a tabela `Reply` tenha um índice global secundário chamado `PostedBy-Message-Index`. A chave de partição para esse índice é `PostedBy`, e a chave de classificação é `Message`. Uma classe de mapeador para esse índice é mostrada na seção [consultar](#DynamoDBMapper.Methods.query). Ela usa as anotações `@DynamoDBIndexHashKey` e `@DynamoDBIndexRangeKey` para especificar a chave de classificação e a chave de partição do índice.

O código de exemplo a seguir verifica `PostedBy-Message-Index`. Ele não usa um filtro de verificação e, portanto, todos os itens no índice são retornados para você.

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

Verifica uma tabela ou um índice secundário e retorna uma única página de resultados correspondentes. Como com o método `scan`, você pode especificar opcionalmente um `FilterExpression` para filtrar o conjunto de resultados. No entanto, `scanPage` retorna somente a primeira “página” de dados, ou seja, a quantidade de dados que cabe em 1 MB.

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

Realiza uma verificação paralela de uma tabela ou de um índice secundário inteiro. Você especifica um número de segmentos lógicos para a tabela, juntamente com uma expressão de verificação para filtrar os resultados. O `parallelScan` divide a tarefa de verificação entre vários operadores, um para cada segmento lógico. Por sua vez, esses operadores processam os dados em paralelo e retornam os resultados.

O exemplo de código Java a seguir realiza uma verificação paralela na tabela `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>

Salva os objetos em uma ou mais tabelas usando uma ou mais chamadas para o método `AmazonDynamoDB.batchWriteItem`. Esse método não fornece garantias de transação.

O código Java a seguir salva dois itens (livros) na tabela `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 vários itens de uma ou mais tabelas usando suas chaves primárias.

O seguinte código Java recupera dois itens de duas tabelas diferentes.

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

Exclui objetos de uma ou mais tabelas usando uma ou mais chamadas para o método `AmazonDynamoDB.batchWriteItem`. Esse método não fornece garantias de transação. 

O código Java a seguir exclui dois itens (livros) na tabela `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>

Salva e exclui objetos em/de uma ou mais tabelas usando uma ou mais chamadas para o método `AmazonDynamoDB.batchWriteItem`. Esse método não oferece garantias de transação ou suporte para versionamento (inserções ou exclusões condicionais).

O código Java a seguir grava um novo item na tabela `Forum`, grava um novo item na tabela `Thread` e exclui um item da tabela `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>

Salva e exclui objetos em/de uma ou mais tabelas usando uma chamada para o método `AmazonDynamoDB.transactWriteItems`. 

Para obter uma lista de exceções específicas de transação, consulte [Erros TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors). 

Para obter mais informações sobre transações do DynamoDB e as garantias de ACID (atomicidade, consistência, isolamento e durabilidade) fornecidas, consulte [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

**nota**  
 Esse método não é compatível com o seguinte:  
[DynamoDBMapperConfig.SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html).

O código Java a seguir grava um novo item em cada uma das tabelas `Forum` e `Thread`, de forma transacional.

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

Carrega objetos de uma ou mais tabelas usando uma chamada para o método `AmazonDynamoDB.transactGetItems`. 

Para obter uma lista de exceções específicas de transação, consulte [Erros TransactGetItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors). 

Para obter mais informações sobre transações do DynamoDB e as garantias de ACID (atomicidade, consistência, isolamento e durabilidade) fornecidas, consulte [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

O código Java a seguir carrega um item de cada uma das tabelas `Forum` e `Thread`, de forma transacional.

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

## contagem
<a name="DynamoDBMapper.Methods.count"></a>

Avalia a expressão de verificação especificada e retorna a contagem de itens correspondentes. Dados de itens não são retornados.

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

Analisa uma classe POJO que representa um tabela do DynamoDB e retorna um `CreateTableRequest` para essa tabela.

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

Cria um link para um objeto no Amazon S3. Você deve especificar um nome de bucket e um nome de chave que identifique exclusivamente o objeto no bucket.

Para usar `createS3Link`, a sua classe de mapeador deve definir métodos getter e setter. O exemplo de código a seguir ilustra isso, adicionando um novo atributo e métodos getter/setter à classe `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;
    }

...
}
```

O código Java a seguir define um novo item a ser gravado na tabela `Product`. O item inclui um link para uma imagem do produto. Os dados da imagem são carregados no 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);
```

A classe `S3Link` fornece muitos outros métodos para manipular objetos no Amazon S3. Para obter mais informações, consulte os [Javadocs para `S3Link`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html).

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

Retorna o `S3ClientCache` subjacente para acessar o Amazon S3. Um `S3ClientCache` é um Mapa inteligente para objetos `AmazonS3Client`. Se você tem vários clientes, um `S3ClientCache` pode ajudá-lo a manter esses clientes organizados por região da AWS e pode criar novos clientes do Amazon S3 sob demanda.

# Tipos de dados compatíveis com DynamoDBMapper para Java
<a name="DynamoDBMapper.DataTypes"></a>

Esta seção descreve os tipos de dados arbitrários, as coleções e os tipos de dados Java primitivos com aceitos no Amazon DynamoDB. 

O Amazon DynamoDB oferece suporte aos seguintes tipos de dados Java primitivos e classes wrapper primitivas. 
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (como a string de precisão em milissegundos [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601), modificada para UTC)
+ `Calendar` (como a string de precisão em milissegundos [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601), modificada para UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**nota**  
Para obter mais informações sobre as regras de nomenclatura do DynamoDB e os vários tipos de dados compatíveis, consulte [Tipos de dados compatíveis e regras de nomenclatura no Amazon DynamoDB](HowItWorks.NamingRulesDataTypes.md). 
O DynamoDBMapper oferece suporte a valores Binary vazios.
Valores String vazios são compatíveis com o AWS SDK for Java 2.x.  
No AWS SDK para Java 1.x, o DynamoDBMapper oferece suporte à leitura de valores de atributos String vazios. No entanto, ele não gravará valores de atributos String vazios porque esses atributos são descartados da solicitação.

O DynamoDB oferece suporte aos tipos de coleção 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) e [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html). A tabela a seguir resume como esses tipos Java são mapeados nos tipos do DynamoDB.


****  

| Tipo Java | Tipo do DynamoDB | 
| --- | --- | 
|  Todos os tipos de número  |  `N` (tipo Número)  | 
|  Strings  |  `S` (tipo String)   | 
|  Booleano  |  `BOOL` (tipo booliano), 0 ou 1.  | 
|  ByteBuffer  |  `B` (tipo Binário)  | 
|  Data  |  `S` (tipo String). Os valores de Date são armazenados como strings formatadas em ISO-8601.  | 
| Tipos de coleção [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) |  Tipo `SS` (conjunto de strings), tipo `NS` (conjunto de números) e tipo `BS` (conjunto de binários).  | 

 A interface `DynamoDBTypeConverter` permite que você mapeie seus próprios tipos de dados arbitrários em um tipo de dados com suporte nativo do DynamoDB. Para obter mais informações, consulte [Mapear dados arbitrários no DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md). 

# Anotações Java para DynamoDB
<a name="DynamoDBMapper.Annotations"></a>

Esta seção descreve as anotações que estão disponíveis para mapear suas classes e propriedades em tabelas e atributos no Amazon DynamoDB.

Para conhecer a documentação Javadoc correspondente, consulte [Resumo de tipos de anotação](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html) na [Referência da API do AWS SDK para Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

**nota**  
Nas seguintes anotações, apenas `DynamoDBTable` e `DynamoDBHashKey` são necessários. 

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

Mapeia uma propriedade para um atributo de tabela. Por padrão, cada propriedade de classe é mapeada para um atributo de item com o mesmo nome. No entanto, se os nomes não forem os mesmos, você poderá usar essa anotação para mapear uma propriedade para o atributo. No seguinte trecho de código Java, `DynamoDBAttribute` mapeia a propriedade `BookAuthors` para o nome de atributo `Authors` na tabela.

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

O `DynamoDBMapper` usa `Authors` como o nome do atributo ao salvar o objeto na tabela. 

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

Marca uma propriedade de chave de partição ou de chave de classificação como sendo gerada automaticamente. `DynamoDBMapper` gera um [UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html) aleatório ao salvar esses atributos. Apenas propriedades String podem ser marcadas como chaves geradas automaticamente. 

O exemplo a seguir demonstra o uso de chaves geradas automaticamente.

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

Gera automaticamente um carimbo de data/hora.

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

Opcionalmente, a estratégia de geração automática pode ser definida fornecendo um atributo de estratégia. O padrão é `ALWAYS`.

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

Indica que uma classe pode ser serializada como um documento do Amazon DynamoDB.

Por exemplo, vamos supor que você queria mapear um documento JSON em um atributo do DynamoDB do tipo Map (`M`). O exemplo de código a seguir define um item que contém um atributo aninhado (Pictures) do 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; }

     }
}
```

É possível salvar um novo item `ProductCatalog`, com `Pictures`, conforme mostrado no exemplo a seguir.

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

O item de `ProductCatalog` resultante seria semelhante ao seguinte (no 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>

Mapeia uma propriedade de classe para a chave de partição da tabela. A propriedade deve ser uma string escalar, número ou tipos binários. A propriedade não pode ser um tipo de coleção. 

Vamos supor que você tenha uma tabela, `ProductCatalog`, com `Id` como chave primária. O código Java a seguir define uma classe `CatalogItem` e mapeia sua propriedade `Id` para a chave primária da tabela `ProductCatalog` usando a tag `@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 à instância de `DynamoDBMapper` que a propriedade associada deve ser ignorada. Quando salvar dados na tabela, o `DynamoDBMapper` não salva essa propriedade na tabela.

 Aplicado ao método getter ou ao campo de classe de uma propriedade não modelada. Se a anotação for aplicada diretamente ao campo de classe, o getter e o setter correspondentes deverão ser declarados na mesma classe. 

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

Mapeia uma propriedade de classe na chave de partição de um índice secundário global. A propriedade deve ser uma string escalar, número ou tipos binários. A propriedade não pode ser um tipo de coleção. 

Use essa anotação se você precisa realizar uma `Query` em um índice secundário global. É necessário especificar o nome de índice (`globalSecondaryIndexName`). Se o nome da propriedade da classe for diferente da chave de partição do índice, também será necessário especificar o nome desse atributo de índice (`attributeName`).

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

Mapeia uma propriedade de classe na chave de classificação de um índice secundário global ou índice secundário local. A propriedade deve ser uma string escalar, número ou tipos binários. A propriedade não pode ser um tipo de coleção. 

Use essa anotação se você precisa realizar uma `Query` em um índice secundário local ou índice secundário global e deseja refinar seus resultados usando a chave de classificação do índice. É necessário especificar o nome de índice (`globalSecondaryIndexName` ou `localSecondaryIndexName`). Se o nome da propriedade da classe for diferente da chave de classificação do índice, você também deve especificar o nome desse atributo de índice (`attributeName`).

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

Mapeia uma propriedade de classe para a chave de classificação da tabela. A propriedade deve ser uma string escalar, número ou tipos binários. Não pode ser um tipo de coleção. 

Se a chave primária for composta (chave de partição e chave de classificação), você poderá usar essa tag para mapear seu campo de classe para a chave de classificação. Por exemplo, vamos supor que você tenha uma tabela `Reply` que armazena respostas para tópicos de fórum. Cada tópico pode ter muitas respostas. Portanto, a chave primária dessa tabela é tanto `ThreadId` quanto `ReplyDateTime`. `ThreadId` é a chave de partição, e `ReplyDateTime` é a chave de classificação. 

O código Java a seguir define uma classe `Reply` e a mapeia para a tabela `Reply`. Ele usa ambas as tags `@DynamoDBHashKey` e `@DynamoDBRangeKey` para identificar propriedades de classes que são mapeadas para a chave primária.

```
@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 a tabela de destino no DynamoDB. Por exemplo, o seguinte código Java define uma classe `Developer` e a mapeia na tabela `People` no DynamoDB. 

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

A anotação `@DynamoDBTable` pode ser herdada. Qualquer nova classe que herde da classe `Developer` também é mapeada para a tabela `People`. Por exemplo, suponha que você crie uma classe `Lead` que herde da classe `Developer`. Como você mapeou a classe `Developer` para a tabela `People`, e os objetos de classe `Lead` também são armazenados na mesma tabela.

Também é possível substituir `@DynamoDBTable`. Qualquer nova classe que herde da classe `Developer` por padrão é mapeada para a mesma tabela `People`. No entanto, você pode substituir esse mapeamento padrão. Por exemplo, se você criar uma classe que herda da classe `Developer`, será possível mapeá-la explicitamente para outra tabela adicionando a anotação `@DynamoDBTable`, conforme mostrado no seguinte exemplo de código Java.

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

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

Uma anotação para marcar uma propriedade como usando um conversor de tipo personalizado. Pode ser anotada em uma anotação definida pelo usuário para transmitir propriedades adicionais a `DynamoDBTypeConverter`. 

 A interface `DynamoDBTypeConverter` permite que você mapeie seus próprios tipos de dados arbitrários em um tipo de dados com suporte nativo do DynamoDB. Para obter mais informações, consulte [Mapear dados arbitrários no DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md).

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

Uma anotação para substituir a associação de tipo de atributo padrão. Tipos padrão não exigem a anotação se estiverem aplicando a associação de atributo padrão para esse tipo. 

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

Identifica uma propriedade de classe para armazenar um número de versão de bloqueio otimista. `DynamoDBMapper` atribui um número de versão a essa propriedade ao salvar um novo item e o incrementa cada vez que você atualizar o item. Apenas há suporte para tipos de números escalares. Para obter informações sobre tipos de dados, consulte [Tipos de dados](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes). Para obter mais informações sobre versionamento, consulte [DynamoDB e bloqueio positivo com número de versão](DynamoDBMapper.OptimisticLocking.md).

# Definições de configuração opcionais para DynamoDBMapper
<a name="DynamoDBMapper.OptionalConfig"></a>

Quando você cria uma instância de `DynamoDBMapper`, ela tem certos comportamentos padrão que podem ser substituídos com o uso da classe `DynamoDBMapperConfig`. 

O seguinte trecho de código cria um `DynamoDBMapper` com configurações personalizadas:

```
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 obter mais informações, 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) na [Referência da API do AWS SDK para Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

Como alternativa, você pode usar os seguintes argumentos para uma instância de `DynamoDBMapperConfig`:
+ Um valor de enumeração `DynamoDBMapperConfig.ConsistentReads`:
  + `EVENTUAL`: a instância de mapeador usa uma solicitação de leitura eventualmente consistente.
  + `CONSISTENT`: a instância do mapeador usa uma solicitação de leitura fortemente consistente. É possível usar essa configuração opcional com operações `load`, `query` ou `scan`. Leituras altamente consistentes têm implicações sobre a performance e a cobrança. Consulte a [página de detalhes do produto](https://aws.amazon.com/dynamodb) do DynamoDB para obter mais informações.

  Se você não especificar uma configuração de consistência de leitura para sua instância de mapeador, o padrão será `EVENTUAL`.
**nota**  
Esse valor é aplicado em operações `query`, `querypage`, `load` e `batch load` do DynamoDBMapper.
+ Um valor de enumeração `DynamoDBMapperConfig.PaginationLoadingStrategy`: controla como a instância de mapeador processa uma lista paginada de dados, como os resultados de um `query` ou `scan`:
  + `LAZY_LOADING`: a instância do mapeador carrega dados quando possível e mantém todos os resultados carregados na memória.
  + `EAGER_LOADING`: a instância de mapeador carrega os dados assim que a lista é inicializada.
  + `ITERATION_ONLY`: você só pode usar um iterador para ler da lista. Durante a iteração, a lista limpará todos os resultados anteriores antes de carregar a próxima página e, portanto, ela manterá no máximo uma página dos resultados carregados na memória. Isso também significa que a lista só pode ser iterada uma vez. Essa estratégia é recomendada ao lidar com itens grandes, a fim de reduzir a sobrecarga de memória.

  Se você não especificar uma estratégia de carregamento de paginação para a sua instância de mapeador, o padrão será `LAZY_LOADING`.
+ Um valor de enumeração `DynamoDBMapperConfig.SaveBehavior`: especifica como a instância de mapeador deve lidar com atributos durante operações de salvamento:
  + `UPDATE`: durante uma operação de gravação, todos os atributos modelados são atualizados, enquanto os atributos não modelados não são afetados. Tipos de números primitivos (byte, int, long) são definidos como 0. Tipos de objetos são definidos como nulos. 
  + `CLOBBER`: limpa e substitui todos os atributos, incluindo os não modelados, durante uma operação de gravação. Isso é feito excluindo-se o item e o recriando. Restrições de campo com versionamento também são desconsideradas.

   Se você não especificar o comportamento de salvamento para sua instância de mapeador, o padrão será `UPDATE`.
**nota**  
As operações transacionais do DynamoDBMapper não são compatíveis com a enumeração do `DynamoDBMapperConfig.SaveBehavior`. 
+ Um objeto `DynamoDBMapperConfig.TableNameOverride` instrui a instância do mapeador a ignorar o nome de tabela especificado pela anotação `DynamoDBTable` de uma classe e, em vez disso, usar um nome de tabela diferente que você fornece. Isso é útil ao particionar dados em várias tabelas no tempo de execução. 

Você pode substituir o objeto de configuração padrão para `DynamoDBMapper` por operação, conforme necessário.

# DynamoDB e bloqueio positivo com número de versão
<a name="DynamoDBMapper.OptimisticLocking"></a>

O *bloqueio positivo * é uma estratégia para garantir que o item no lado do cliente que você está atualizando (ou excluindo) seja o mesmo que o item no Amazon DynamoDB. Se você usar essa estratégia, suas gravações de banco de dados serão protegidas contra substituição pelas gravações de outros e vice-versa.

Com o bloqueio positivo, cada item tem um atributo que serve como um número de versão. Se você recuperar um item de uma tabela, o aplicativo registrará o número da versão desse item. Você poderá atualizar o item somente se o número de versão no lado do servidor não tiver sido alterado. Se há uma incompatibilidade de versão, isso significa que alguém modificou o item antes de você. A tentativa de atualização falha, porque você tem uma versão obsoleta do item. Se isso acontecer, basta tentar novamente ao recuperar o item e tentar atualizá-lo. O bloqueio positivo impede que você substitua acidentalmente as alterações que foram feitas por outros. Também impede que outros substituam acidentalmente suas alterações.

Embora seja possível implementar a própria estratégia de bloqueio positivo, o AWS SDK para Java oferece a anotação `@DynamoDBVersionAttribute`. Na classe de mapeamento da sua tabela, você designa uma propriedade para armazenar o número da versão e a marca usando essa anotação. Quando um objeto é salvo, o item correspondente na tabela do DynamoDB terá um atributo que armazena o número da versão. O `DynamoDBMapper` atribui um número de versão quando você salvar o objeto pela primeira vez e incrementa automaticamente o número da versão sempre que você atualiza o item. Suas solicitações de atualização ou exclusão só serão bem-sucedidas se a versão do objeto no lado do cliente corresponder ao número de versão correspondente do item na tabela do DynamoDB.

 `ConditionalCheckFailedException` será lançada se: 
+  Você usar bloqueio positivo com `@DynamoDBVersionAttribute` e o valor de versão no servidor for diferente do valor no lado do cliente. 
+  Você especificar suas próprias restrições condicionais ao salvar dados usando `DynamoDBMapper` com `DynamoDBSaveExpression` e ocorrer falha nessas restrições. 

**nota**  
As tabelas globais do DynamoDB usam uma reconciliação “último gravador ganha” entre as atualizações simultâneas. Se você usa tabelas globais, a política de último gravador ganha. Portanto, neste caso, a estratégia de bloqueio não funciona como esperado.
As operações de gravação transacional `DynamoDBMapper` não são compatíveis com expressões de condição e anotação `@DynamoDBVersionAttribute` no mesmo objeto. Se um objeto em uma gravação transacional for anotado com `@DynamoDBVersionAttribute` e também tiver uma expressão de condição, a SdkClientException será lançada.

Por exemplo, o código Java a seguir define uma classe `CatalogItem` que tem várias propriedades. A propriedade `Version` está marcada com a anotação `@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;}
}
```

Você pode aplicar a anotação `@DynamoDBVersionAttribute` a tipos anuláveis fornecidos pelas classes wrapper primitivas que fornecem um tipo que permite valor nulo, como `Long` e `Integer`. 

O bloqueio positivo tem o seguinte impacto sobre estes métodos `DynamoDBMapper`:
+ `save`: para um novo item, `DynamoDBMapper` atribui um número de versão inicial 1. Se você recuperar um item, atualizar uma ou mais das suas propriedades e tentar salvar as alterações, a operação de salvamento será bem-sucedida somente se o número de versão no lado do cliente e no lado do servidor corresponderem. A classe `DynamoDBMapper` incrementa o número de versão automaticamente.
+ `delete`: o método `delete` usa um objeto como parâmetro, e `DynamoDBMapper` realiza uma verificação de versão antes de excluir o item. A verificação da versão pode ser desabilitada se `DynamoDBMapperConfig.SaveBehavior.CLOBBER` for especificado na solicitação.

  A implementação interna do bloqueio positivo em `DynamoDBMapper` usa o suporte a atualizações e exclusões condicionais fornecido pelo DynamoDB. 
+ `transactionWrite` —
  + `Put`: para um novo item, `DynamoDBMapper` atribui um número de versão inicial 1. Se você recuperar um item, atualizar uma ou mais das suas propriedades e tentar salvar as alterações, a operação Put será bem-sucedida somente se o número de versão no lado do cliente e no lado do servidor corresponder. A classe `DynamoDBMapper` incrementa o número de versão automaticamente.
  + `Update`: para um novo item, `DynamoDBMapper` atribui um número de versão inicial 1. Se você recuperar um item, atualizar uma ou mais das suas propriedades e tentar salvar as alterações, a operação Update será bem-sucedida somente se o número de versão no lado do cliente e no lado do servidor corresponder. A classe `DynamoDBMapper` incrementa o número de versão automaticamente.
  + `Delete`: o `DynamoDBMapper` realiza uma verificação de versão antes de excluir o item. A operação Delete só será bem-sucedida se o número de versão no lado do cliente e no lado do servidor corresponder.
  + `ConditionCheck`: a anotação `@DynamoDBVersionAttribute` não é compatível com operações `ConditionCheck`. Uma SdkClientException será lançada quando um item `ConditionCheck` for anotado com `@DynamoDBVersionAttribute`. 

## Desabilitar o bloqueio positivo
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

Para desabilitar o bloqueio positivo, você pode alterar o valor de enumeração `DynamoDBMapperConfig.SaveBehavior` de `UPDATE` para `CLOBBER`. Você pode fazer isso criando uma instância de `DynamoDBMapperConfig` que ignora a verificação de versão e usando essa instância para todas as suas solicitações. Para obter informações sobre `DynamoDBMapperConfig.SaveBehavior` e outros parâmetros `DynamoDBMapper` opcionais, consulte [Definições de configuração opcionais para DynamoDBMapper](DynamoDBMapper.OptionalConfig.md). 

Você também pode definir um comportamento de bloqueio somente para uma operação específica. Por exemplo, o seguinte trecho de código Java usa `DynamoDBMapper` para salvar um item de catálogo. Ele especifica `DynamoDBMapperConfig.SaveBehavior` adicionando o parâmetro `DynamoDBMapperConfig` opcional ao método `save`. 

**nota**  
O método transactionWrite não oferece suporte à configuração DynamoDBMapperConfig.SaveBehavior. A desabilitação do bloqueio positivo para transactionWrite é incompatível.

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

# Mapear dados arbitrários no DynamoDB
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

Além dos tipos de Java compatíveis (consulte [Tipos de dados compatíveis com DynamoDBMapper para Java](DynamoDBMapper.DataTypes.md)), é possível usar tipos em sua aplicação para os quais não há um mapeamento direto para os tipos do Amazon DynamoDB. Para mapear esses tipos, é necessário fornecer uma implementação que converta o tipo complexo em um tipo compatível com o DynamoDB e vice-versa, e anotar o método de acesso de tipos complexos usando a anotação `@DynamoDBTypeConverted`. O código de conversor transforma os dados quando os objetos são salvos ou carregados. Ele também é usado para todas as operações que consomem tipos complexos. Observe que, ao comparar dados durante operações de consulta e verificação, as comparações são feitas com os dados armazenados no DynamoDB.

Por exemplo, considere a seguinte classe `CatalogItem`, que define uma propriedade, `Dimension`, que é de `DimensionType`. Essa propriedade armazena as dimensões de itens, como altura, largura e espessura. Suponha que você decida armazenar essas dimensões de itens como uma string (como 8.5x11x.05) no DynamoDB. O exemplo a seguir fornece o código de conversor que converte o objeto `DimensionType` em uma string e uma string em `DimensionType`.



**nota**  
Este exemplo de código pressupõe que você já carregou dados no DynamoDB para sua conta seguindo as instruções na seção [Criar tabelas e carregar dados para exemplos de código no DynamoDB](SampleData.md).  
Para obter instruções passo a passo sobre como executar o exemplo a seguir, consulte [Exemplos 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;
        }
    }
}
```

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

O AWS SDK para Java fornece uma classe `DynamoDBMapper`, permitindo mapear classes do lado do cliente para tabelas do DynamoDB. Para usar `DynamoDBMapper`, defina a relação entre os itens em uma tabela do DynamoDB e as instâncias de objeto correspondentes no seu código. A classe `DynamoDBMapper` permite que você realize várias operações de criação, leitura, atualização e exclusão (CRUD) em itens e execute consultas e verificações em tabelas.

Para saber mais sobre como 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) (Exemplos do DynamoDB usando o SDK para Java) no *Guia do desenvolvedor do AWS SDK para Java 1.x*. 

# Java 2.x: Cliente Aprimorado do DynamoDB
<a name="DynamoDBEnhanced"></a>

O Cliente Aprimorado do DynamoDB é uma biblioteca de alto nível que faz parte do AWS SDK para Java versão 2 (v2). Ele oferece uma maneira simples de mapear classes do lado do cliente para tabelas do DynamoDB. Basta definir as relações entre as tabelas e suas classes de modelo correspondentes no seu código. Depois que você definir essas relações, poderá executar intuitivamente várias operações de criação, leitura, atualização ou exclusão (CRUD) em tabelas ou itens do DynamoDB.

Para obter mais informações sobre como você pode usar o cliente aprimorado com o DynamoDB, consulte [Usar o Cliente Aprimorado do DynamoDB no AWS SDK para Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html). 

# Trabalhar com o modelo de documento do .NET no DynamoDB
<a name="DotNetSDKMidLevel"></a>

O AWS SDK para .NET fornece classes do modelo de documento para empacotar algumas das operações de baixo nível do Amazon DynamoDB, simplificando ainda mais sua codificação. No modelo de documento, as classes primárias são `Table` e `Document`. A classe `Table` fornece métodos de operação de dados, como `PutItem`, `GetItem` e `DeleteItem`. Ela também fornece os métodos `Query` e `Scan`. A classe `Document` representa um único item em uma tabela.

As classes do modelo de documento anteriores estão disponíveis no namespace `Amazon.DynamoDBv2.DocumentModel`.

**nota**  
Não é possível usar as classes do modelo de documento para criar, atualizar e excluir tabelas. Por outro lado, o modelo de documento oferece suporte à maioria das operações de dados comuns.

**Topics**
+ [Tipos de dados compatíveis](#MidLevelAPILimitations.SupportedTypes)

## Tipos de dados compatíveis
<a name="MidLevelAPILimitations.SupportedTypes"></a>

O modelo de documento oferece suporte a um conjunto de tipos de dados .NET primitivos e tipos de dados de coleções. O modelo é compatível com os seguintes tipos de dados primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

A tabela a seguir resume o mapeamento dos tipos .NET anteriores nos tipos do DynamoDB.


****  

| Tipo primitivo .NET | Tipo do DynamoDB | 
| --- | --- | 
|  Todos os tipos de número  |  `N` (tipo Número)  | 
|  Todos os tipos de string  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binário)   | 
| bool | N (tipo numérico), 0 representa false 1 representa true. | 
| DateTime | S (tipo String). Os valores de DateTime são armazenados como strings formatadas em ISO-8601. | 
| Guid | S (tipo String). | 
| Tipos de coleção (List, HashSet e array) | Tipo BS (conjunto binário), tipo SS (conjunto de strings) e tipo NS (conjunto de números) | 

O AWS SDK para .NET define tipos para mapear os tipos Boolean, Null, List e Map do DynamoDB na API do modelo de documento do .NET:
+ Use `DynamoDBBool` para o tipo booliano.
+ Use `DynamoDBNull` para o tipo nulo.
+ Use `DynamoDBList` para o tipo lista.
+ Use `Document` para o tipo mapa.

**nota**  
Valores binários vazios são compatíveis.
A leitura de valores string vazios é compatível. Os valores de atributos string vazios são compatíveis nos valores de atributos do tipo de conjunto string durante a gravação no DynamoDB. Os valores de atributos string vazios do tipo string e os valores string vazios contidos no tipo Lista ou Mapa são descartados das solicitações de gravação

# Trabalhar com o modelo de persistência de objetos do .NET e o DynamoDB
<a name="DotNetSDKHighLevel"></a>

O AWS SDK para .NET fornece um modelo de persistência de objetos que permite mapear classes do cliente em tabelas do Amazon DynamoDB. Em seguida, cada instância de objeto é mapeada para um item nas tabelas correspondentes. Para salvar objetos no lado do cliente nas tabelas, o modelo de persistência de objetos fornece a classe `DynamoDBContext`, um ponto de entrada para o DynamoDB. Esta classe fornece uma conexão ao DynamoDB e permite que você acesse tabelas, execute várias operações CRUD e realize consultas.

O modelo de persistência de objetos fornece um conjunto de atributos para mapear classes no lado do cliente para tabelas e propriedades/campos para atributos de tabela.

**nota**  
O modelo de persistência de objetos não fornece uma API para criar, atualizar ou excluir tabelas. Ele fornece apenas operações de dados. É possível usar somente a API de baixo nível do AWS SDK para .NET para criar, atualizar e excluir tabelas.

O exemplo a seguir mostra como o modelo de persistência de objetos funciona. Ele começa com a tabela `ProductCatalog`. `Id` é a chave primária.

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

Suponha que você tenha uma classe `Book` com propriedades `Title`, `ISBN` e `Authors`. É possível mapear a classe `Book` na tabela `ProductCatalog` adicionando os atributos definidos pelo modelo de persistência de objetos, conforme mostrado no trecho de código C\$1 a seguir.

**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; }
  }
```

No exemplo anterior, o atributo `DynamoDBTable` mapeia a classe `Book` na tabela `ProductCatalog`.

O modelo de persistência objeto oferece suporte a tipos de mapeamento explícito e padrão entre propriedades de classe e atributos de tabela.
+ **Mapeamento explícito**: para mapear uma propriedade em uma chave primária, você deve usar os atributos `DynamoDBHashKey` e `DynamoDBRangeKey` do modelo de persistência de objetos. Além disso, para os atributos de chave não primárias, se um nome de propriedade na sua classe e o atributo de tabela correspondente ao qual você deseja mapear não forem os mesmos, será necessário definir o mapeamento adicionando explicitamente o atributo `DynamoDBProperty`.

  No exemplo anterior, a propriedade `Id` é mapeada na chave primária com o mesmo nome, e a propriedade `BookAuthors` é mapeada no atributo `Authors` na tabela `ProductCatalog`.
+ **Mapeamento padrão — **por padrão, o modelo de persistência objeto mapeia as propriedades da classe para os atributos com o mesmo nome na tabela.

  No exemplo anterior, as propriedades `Title` e `ISBN` são mapeadas nos atributos com o mesmo nome na tabela `ProductCatalog`.

Não é necessário mapear cada propriedade de classe. Identifique essas propriedades adicionando o atributo `DynamoDBIgnore`. Quando você salva uma instância de `Book` na tabela, `DynamoDBContext` não inclui a propriedade `CoverPage`. Ele também não retorna essa propriedade quando você recupera a instância de livro.

É possível mapear propriedades de tipos primitivos do .NET, como int e string. Também é possível mapear qualquer tipo de dados arbitrário, desde que você forneça um conversor apropriado para mapear os dados arbitrários em um do tipos do DynamoDB. Para saber mais sobre o mapeamento de tipos arbitrários, consulte [Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md).

O modelo de persistência objetos oferece suporte a bloqueio otimista. Durante uma operação de atualização, isso garante que você tenha a cópia mais recente do item que está prestes a atualizar. Para obter mais informações, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

Para obter mais informações, consulte os tópicos abaixo:

**Topics**
+ [Tipos de dados compatíveis](#DotNetDynamoDBContext.SupportedTypes)
+ [Atributos do DynamoDB do modelo de persistência de objetos do .NET](DeclarativeTagsList.md)
+ [Classe DynamoDBContext do modelo de persistência de objetos do .NET](DotNetDynamoDBContext.md)
+ [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md)
+ [Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.ArbitraryDataMapping.md)

## Tipos de dados compatíveis
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

O modelo de persistência de objetos oferece suporte a um conjunto de tipos de dados primitivos do .NET, coleções e tipos de dados arbitrários. O modelo é compatível com os seguintes tipos de dados primitivos. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

O modelo de persistência de objetos também oferece suporte aos tipos de coleção .NET. `DynamoDBContext` é capaz de converter tipos de coleção concretos e objetos CLR básicos (POCOs).

A tabela a seguir resume o mapeamento dos tipos .NET anteriores nos tipos do DynamoDB.


****  

| Tipo primitivo .NET | Tipo do DynamoDB | 
| --- | --- | 
|  Todos os tipos de número  |  `N` (tipo Número)  | 
|  Todos os tipos de string  |  `S` (tipo String)   | 
|  MemoryStream, byte[]  |  `B` (tipo Binário)   | 
| bool | N (tipo numérico), 0 representa false 1 representa true. | 
| Tipos de coleção | Tipo BS (conjunto binário), tipo SS (conjunto de strings) e tipo NS (conjunto de números) | 
| DateTime | S (tipo String). Os valores de DateTime são armazenados como strings formatadas em ISO-8601. | 

O modelo de persistência de objetos também oferece suporte a tipos de dados arbitrários. No entanto, você deve fornecer o código de conversor para mapear os tipos complexos em tipos do DynamoDB.

**nota**  
Valores binários vazios são compatíveis.
A leitura de valores string vazios é compatível. Os valores de atributos string vazios são compatíveis nos valores de atributos do tipo de conjunto string durante a gravação no DynamoDB. Os valores de atributos string vazios do tipo string e os valores string vazios contidos no tipo Lista ou Mapa são descartados das solicitações de gravação

# Atributos do DynamoDB do modelo de persistência de objetos do .NET
<a name="DeclarativeTagsList"></a>

Esta seção descreve os atributos oferecidos pelo modelo de persistência objetos para que você possa mapear suas classes e propriedades em tabelas e atributos do DynamoDB.

**nota**  
Nos seguintes atributos, apenas `DynamoDBTable` e `DynamoDBHashKey` são necessários.

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

Mapeia uma propriedade de classe na chave de partição de um índice secundário global. Use esse atributo se você precisa realizar uma `Query` em um índice secundário global.

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

Mapeia uma propriedade de classe na chave de classificação de um índice secundário global. Use esse atributo se você precisa realizar uma operação `Query` em um índice secundário global e deseja refinar seus resultados usando a chave de classificação de índice.

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

Mapeia uma propriedade de classe para a chave de partição da chave primária da tabela. Os atributos de chave primária não podem ser um tipo de coleção.

Os seguintes exemplos de código C\$1 mapeiam a classe `Book` na tabela `ProductCatalog` e a propriedade `Id` na chave de partição da chave primária da tabela.

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

    // Additional properties go here.
}
```

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

Indica que a propriedade associada deve ser ignorada. Se não desejar salvar nenhuma das suas propriedades de classe, você poderá adicionar esse atributo para instruir `DynamoDBContext` a não incluir essa propriedade ao salvar objetos na tabela.

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

Mapeia uma propriedade de classe na chave de classificação de um índice secundário local. Use esse atributo se você precisa realizar uma operação `Query` em um índice secundário local e deseja refinar seus resultados usando a chave de classificação de índice.

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

Mapeia uma propriedade de classe em um atributo de tabela. Se a propriedade de classe for mapeada em um atributo de tabela com o mesmo nome, não será necessário especificar esse atributo. No entanto, se os nomes não forem iguais, você poderá usar essa tag para fornecer o mapeamento. Na instrução C\$1 a seguir, `DynamoDBProperty` mapeia a propriedade `BookAuthors` no atributo `Authors` na tabela. 

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

`DynamoDBContext` usa essas informações de mapeamento para criar o atributo `Authors` ao salvar dados de objetos na tabela correspondente.

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

Especifica um nome alternativo para uma propriedade de classe. Isso é útil quando você está escrevendo um conversor personalizado para o mapeamento de dados arbitrários em uma tabela do DynamoDB na qual o nome de uma propriedade de classe é diferente de um atributo da tabela.

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

Mapeia uma propriedade de classe na chave de classificação da chave primária da tabela. Se a tabela tiver uma chave primária composta (chave de partição e chave de classificação), você deverá especificar os atributos `DynamoDBHashKey` e `DynamoDBRangeKey` no seu mapeamento de classes.

Por exemplo, a tabela de exemplo `Reply` tem uma chave primária composta pela chave de partição `Id` e pela chave de classificação `Replenishment`. O exemplo de código C\$1 a seguir mapeia a classe `Reply` na tabela `Reply`. A definição de classe também indica que duas de suas propriedades são mapeadas para a chave primária.

```
[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 a tabela de destino do DynamoDB na qual a classe é mapeada. Por exemplo, o exemplo de código C\$1 a seguir mapeia a classe `Developer` na tabela `People` no DynamoDB.

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

Esse atributo pode ser herdado ou substituído.
+ O atributo `DynamoDBTable` pode ser herdado. No exemplo anterior, se você adicionar uma nova classe, `Lead`, que herda da classe `Developer`, ela também será mapeada na tabela `People`. Ambos os objetos `Developer` e `Lead` são armazenados na tabela `People`.
+ O atributo `DynamoDBTable` também pode ser sobrescrito. No exemplo de código C\$1 a seguir, a classe `Manager` herda da classe `Developer`. No entanto, a adição explícita do atributo `DynamoDBTable` mapeia a classe em outra tabela (`Managers`).

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

 É possível adicionar o parâmetro opcional, `LowerCamelCaseProperties`, para solicitar que o DynamoDB coloque em minúscula a primeira letra do nome da propriedade ao armazenar os objetos em uma tabela, conforme mostrado no exemplo de código C\$1 a seguir.

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

Ao salvar as instâncias da classe `Developer`, `DynamoDBContext` salva a propriedade `DeveloperName` como `developerName`.

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

Identifica uma propriedade de classe para armazenar o número de versão do item. Para obter mais informações sobre versionamento, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

# Classe DynamoDBContext do modelo de persistência de objetos do .NET
<a name="DotNetDynamoDBContext"></a>

A classe `DynamoDBContext` é o ponto de entrada para do banco de dados do Amazon DynamoDB. Ela fornece uma conexão com o DynamoDB e permite que você acesse seus dados em várias tabelas, realize várias operações CRUD e execute consultas. A classe `DynamoDBContext` fornece os seguintes métodos:

**Topics**
+ [Create​MultiTable​BatchGet](#w2aac17b9c21c23c39b7)
+ [Create​MultiTable​BatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Excluir](#w2aac17b9c21c23c39c15)
+ [Descartar](#w2aac17b9c21c23c39c17)
+ [Execute​Batch​Get](#w2aac17b9c21c23c39c19)
+ [Execute​Batch​Write](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [Get​Target​Table](#w2aac17b9c21c23c39c29)
+ [Carregar](#w2aac17b9c21c23c39c31)
+ [Consulta](#w2aac17b9c21c23c39c33)
+ [Save (Salvar)](#w2aac17b9c21c23c39c35)
+ [Verificar](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Especificar parâmetros opcionais para DynamoDBContext](#OptionalConfigParams)

## Create​MultiTable​BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Cria um objeto `MultiTableBatchGet` formado por vários objetos `BatchGet` individuais. Cada um desses objetos `BatchGet` pode ser usado para recuperar itens de uma única tabela do DynamoDB.

Para recuperar os itens das tabelas, use o método `ExecuteBatchGet`, passando o objeto `MultiTableBatchGet` como um parâmetro.

## Create​MultiTable​BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Cria um objeto `MultiTableBatchWrite` formado por vários objetos `BatchWrite` individuais. Cada um desses objetos `BatchWrite` pode ser usado para gravar ou excluir itens em uma única tabela do DynamoDB.

Para gravar nas tabelas, use o método `ExecuteBatchWrite`, passando o objeto `MultiTableBatchWrite` como um parâmetro.

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

Cria um objeto `BatchGet` que você pode usar para recuperar vários itens de uma tabela. 

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

Cria um objeto `BatchWrite` que você pode usar para inserir vários itens em uma tabela ou para excluir vários itens de uma tabela. 

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

Exclui um item da tabela. O método requer a chave primária do item que você deseja excluir. É possível fornecer o valor da chave primária ou um objeto no lado do cliente que contém um valor de chave primária como um parâmetro para esse método.
+ Se você especificar um objeto no lado do cliente como um parâmetro e tiver habilitado o bloqueio otimista, a exclusão apenas será bem-sucedida se as versões no lado do cliente e no lado do servidor desse objeto corresponderem.
+ Se você especificar somente o valor da chave primária como parâmetro, a exclusão será bem-sucedida, independentemente de você ter habilitado ou não o bloqueio otimista.

**nota**  
Para realizar essa operação em segundo plano, use o método `DeleteAsync` em vez disso.

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

Descarta todos os recursos gerenciados e não gerenciados.

## Execute​Batch​Get
<a name="w2aac17b9c21c23c39c19"></a>

Lê dados de uma ou mais tabelas, processando todos os objetos `BatchGet` em um `MultiTableBatchGet`.

**nota**  
Para realizar essa operação em segundo plano, use o método `ExecuteBatchGetAsync` em vez disso.

## Execute​Batch​Write
<a name="w2aac17b9c21c23c39c21"></a>

Grava ou exclui dados em uma ou mais tabelas, processando todos os objetos `BatchWrite` em um `MultiTableBatchWrite`.

**nota**  
Para realizar essa operação em segundo plano, use o método `ExecuteBatchWriteAsync` em vez disso.

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

Considerando uma instância de `Document`, o método `FromDocument` retorna uma instância de uma classe no lado do cliente.

Isso será útil se você quiser usar as classes de modelo de documento junto com o modelo de persistência de objetos para realizar qualquer operação de dados. Para obter mais informações sobre as classes do modelo de documento fornecidas pelo AWS SDK para .NET, consulte [Trabalhar com o modelo de documento do .NET no DynamoDB](DotNetSDKMidLevel.md).

Suponha que você tenha um objeto `Document` denominado `doc` que contém uma representação de um item `Forum`. (Para ver como construir esse objeto, consulte a descrição do método `ToDocument` mais adiante neste tópico.) Você pode usar `FromDocument` para recuperar o item `Forum` de `Document`, conforme mostrado no exemplo de código C\$1 a seguir.

**Example**  

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

**nota**  
Se o objeto `Document` implementar a interface `IEnumerable`, você poderá usar o método `FromDocuments` em vez disso. Isso permite uma iteração sobre todas as instâncias da classe em `Document`.

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

Executa uma operação `Query`, com os parâmetros de consulta definidos em um objeto `QueryOperationConfig`.

**nota**  
Para realizar essa operação em segundo plano, use o método `FromQueryAsync` em vez disso.

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

Executa uma operação `Scan`, com os parâmetros de verificação definidos em um objeto `ScanOperationConfig`.

**nota**  
Para realizar essa operação em segundo plano, use o método `FromScanAsync` em vez disso.

## Get​Target​Table
<a name="w2aac17b9c21c23c39c29"></a>

Recupera a tabela de destino para o tipo especificado. Isso é útil quando você está escrevendo um conversor personalizado para o mapeamento de dados arbitrários para uma tabela do DynamoDB e precisa determinar qual tabela está associada a um tipo de dados personalizado.

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

Recupera um item de uma tabela. O método requer somente a chave primária do item que você deseja recuperar. 

Por padrão, o DynamoDB retorna o item com valores finais consistentes. Para obter informações sobre o modelo final consistente, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

O método `Load` ou `LoadAsync` chama a operação [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), que exige que você especifique a chave primária para a tabela. Como `GetItem` ignora o parâmetro `IndexName`, você não pode carregar um item usando a partição ou a chave de classificação de um índice. Portanto, é necessário usar a chave primária da tabela para carregar um item.

**nota**  
Para realizar essa operação em segundo plano, use o método `LoadAsync` em vez disso. Para ver um exemplo do uso do método `LoadAsync` para realizar operações CRUD de alto nível em uma tabela do DynamoDB, consulte o exemplo a seguir.

```
    /// <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");
            }
        }
    }
```

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

Consulta uma tabela com base em parâmetros de consulta que você fornece.

Você poderá consultar uma tabela somente se ela tiver uma chave primária composta (chave de partição e chave de classificação). Ao consultar, você deve especificar uma chave de partição e uma condição que se aplique à chave de classificação.

Suponha que você tenha uma classe `Reply` no lado do cliente mapeada na tabela `Reply` no DynamoDB. O exemplo de código C\$1 a seguir consulta a tabela `Reply` para encontrar respostas de tópicos de fórum postadas nos últimos 15 dias. A tabela `Reply` tem uma chave primária com a chave de partição `Id` e a chave de classificação `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);
```

Isso retorna uma coleção de objetos `Reply`. 

Por padrão, o método `Query` retorna uma coleção `IEnumerable` de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, você só precisa fazer uma iteração na coleção `IEnumerable`.

Se a sua tabela tiver uma chave primária simples (chave de partição), você não poderá usar o método `Query`. Em vez disso, poderá usar o método `Load` e fornecer a chave de partição para recuperar o item.

**nota**  
Para realizar essa operação em segundo plano, use o método `QueryAsync` em vez disso.

## Save (Salvar)
<a name="w2aac17b9c21c23c39c35"></a>

Salva o objeto especificado na tabela. Se a chave primária especificada no objeto de entrada não existir na tabela, o método adicionará um novo item à tabela. Se a chave primária existir, o método atualizará o item existente.

Se você tiver o bloqueio otimista configurado, a atualização será bem-sucedida apenas se as versões do item no lado do cliente e no lado do servidor corresponderem. Para obter mais informações, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).

**nota**  
Para realizar essa operação em segundo plano, use o método `SaveAsync` em vez disso.

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

Realiza uma verificação de tabela inteira. 

Você pode filtrar o resultado da verificação especificando uma condição de verificação. A condição pode ser avaliada em qualquer atributo da tabela. Suponha que você tenha uma classe `Book` no lado do cliente mapeada na tabela `ProductCatalog` no DynamoDB. O exemplo de código C\$1 a seguir verifica a tabela e retorna apenas os itens de livro com preços inferiores a 0.

**Example**  

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

Por padrão, o método `Scan` retorna uma coleção `IEnumerable` de "carregamento preguiçoso". Ele inicialmente retorna apenas uma página de resultados e, em seguida, faz uma chamada de serviço para a próxima página, se necessário. Para obter todos os itens correspondentes, basta fazer uma iteração na coleção `IEnumerable`.

Por motivos de performance, você deve consultar suas tabelas e evitar uma verificação de tabela.

**nota**  
Para realizar essa operação em segundo plano, use o método `ScanAsync` em vez disso.

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

Retorna uma instância da classe de modelo de documento `Document` da sua instância de classe. 

Isso será útil se você quiser usar as classes de modelo de documento junto com o modelo de persistência de objetos para realizar qualquer operação de dados. Para obter mais informações sobre as classes do modelo de documento fornecidas pelo AWS SDK para .NET, consulte [Trabalhar com o modelo de documento do .NET no DynamoDB](DotNetSDKMidLevel.md). 

Suponha que você tenha uma classe de cliente mapeada na tabela de exemplo `Forum`. É possível usar um `DynamoDBContext` para obter um item, como um objeto `Document` da tabela `Forum`, conforme mostrado no exemplo de código C\$1 a seguir.

**Example**  

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

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

## Especificar parâmetros opcionais para DynamoDBContext
<a name="OptionalConfigParams"></a>

Ao usar o modelo de persistência de objeto, você pode especificar os seguintes parâmetros opcionais para `DynamoDBContext`.
+ **`ConsistentRead`**: ao recuperar dados usando as operações `Load`, `Query` ou `Scan`, você pode opcionalmente adicionar esse parâmetro para solicitar os valores mais recentes dos dados.
+ **`IgnoreNullValues`**: esse parâmetro instrui `DynamoDBContext` a ignorar valores nulos em atributos durante uma operação `Save`. Se esse parâmetro for false (ou se não estiver definido), um valor nulo será interpretado como uma diretiva para excluir o atributo específico. 
+ **`SkipVersionCheck`**: esse parâmetro instrui o `DynamoDBContext` a não comparar versões ao salvar ou excluir um item. Para obter mais informações sobre versionamento, consulte [Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix`—** prefixa todos os nomes de tabelas com uma string específica. Se esse parâmetro for nulo (ou se não estiver definido), nenhum prefixo será usado.
+ `DynamoDBEntryConversion`: especifica o esquema de conversão usado pelo cliente. Você pode definir esse parâmetro para a versão V1 ou V2. A versão padrão é V1.

  O comportamento desse parâmetro pode mudar com base na versão definida. Por exemplo:
  + Na V1, o tipo de dados `bool` é convertido no tipo numérico `N`, em que 0 representa falso e 1 representa verdadeiro. Na V2, `bool` é convertido em `BOOL`.
  + Na V2, listas e matrizes não são agrupadas com HashSets. Listas e matrizes de números, tipos baseados em strings e tipos baseados em binários são convertidos no tipo `L` (Lista), que pode ser enviado vazio para atualizar uma lista. Isso é diferente da V1, em que uma lista vazia não é enviada pela rede.

    Na V1, os tipos de coleção, como lista, HashSet e matrizes, são tratados da mesma forma. Lista, HashSet e matriz de números são convertidos no tipo `NS` (conjunto de números). 

  O exemplo a seguir define a versão do esquema de conversão como V2, o que altera o comportamento de conversão entre os tipos .NET e os tipos de dados do DynamoDB.

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

O exemplo de código C\$1 a seguir cria um `DynamoDBContext` especificando dois dos parâmetros opcionais anteriores, `ConsistentRead` e `SkipVersionCheck`.

**Example**  

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

`DynamoDBContext` inclui esses parâmetros opcionais com cada solicitação enviada usando esse contexto. 

Em vez de definir esses parâmetros no nível de `DynamoDBContext`, é possível especificá-los para operações individuais que você executa usando `DynamoDBContext`, conforme mostrado no exemplo de código C\$1 a seguir. O exemplo carrega um item de livro específico. O método `Load` de `DynamoDBContext` especifica os parâmetros `ConsistentRead` e `SkipVersionCheck` opcionais.

**Example**  

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

Nesse caso, `DynamoDBContext` inclui esses parâmetros somente ao enviar a solicitação `Get`.

# Bloqueio positivo usando o DynamoDB e o modelo de persistência de objetos do AWS SDK para .NET
<a name="DynamoDBContext.VersionSupport"></a>

O suporte para bloqueio otimista no modelo de persistência de objetos garante que a versão do item para a sua aplicação seja igual à versão do item no lado do servidor antes que esse item seja atualizado ou excluído. Suponha que você recupere um item para atualização. No entanto, antes de você retornar suas atualizações, outra aplicação atualiza o mesmo item. Agora, a aplicação tem uma cópia obsoleta do item. Sem o bloqueio otimista, qualquer atualização que você realizar substituirá a atualização feita pelo outro aplicativo. 

O recurso de bloqueio otimista do modelo de persistência de objetos fornece a tag `DynamoDBVersion` que você pode usar para habilitar o bloqueio otimista. Para usar esse recurso, adicione uma propriedade à sua classe para armazenar o número de versão. Você adiciona o atributo `DynamoDBVersion` à propriedade. Quando o objeto for salvo pela primeira vez, `DynamoDBContext` atribuirá um número de versão e incrementará esse valor cada vez que você atualizar o item. 

Sua solicitação de atualização ou exclusão só será bem-sucedida se a versão do objeto no lado do cliente corresponder ao número de versão correspondente do item no lado do servidor. Se a sua aplicação tiver uma cópia obsoleta, ela deverá obter a versão mais recente do servidor antes de poder atualizar ou excluir o item.

O exemplo de código C\$1 a seguir define uma classe `Book` com atributos de persistência de objetos mapeando-a na tabela `ProductCatalog`. A propriedade `VersionNumber` na classe decorada com o atributo `DynamoDBVersion` armazena o valor do número de versão.

**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**  
Você pode aplicar o atributo `DynamoDBVersion` apenas a um tipo primitivo numérico anulável (como `int?`). 

O bloqueio otimista tem o seguinte impacto sobre operações `DynamoDBContext`:
+ Para um novo item, `DynamoDBContext` atribui o número de versão inicial 0. Se você recuperar um item existente, atualizar uma ou mais das suas propriedades e tentar salvar as alterações, a operação de salvamento será bem-sucedida somente se o número de versão no lado do cliente e no lado do servidor corresponderem. `DynamoDBContext` incrementa o número de versão. Você não precisa definir o número de versão.
+ O método `Delete` fornece sobrecargas que podem usar um valor de chave primária ou um objeto como parâmetro, conforme mostrado no exemplo de código C\$1 a seguir.  
**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);
  ```

  Se você fornecer um objeto como parâmetro, a exclusão apenas será bem-sucedida se a versão do objeto corresponder à versão de item no lado do servidor correspondente. No entanto, se você fornecer um valor de chave primária como parâmetro, `DynamoDBContext` desconhecerá qualquer número de versão e excluirá o item sem fazer a verificação de versão. 

  Observe que a implementação interna do bloqueio otimista no código do modelo de persistência de objetos usa as ações de API de atualização condicional e exclusão condicional no DynamoDB.

## Desabilitar o bloqueio positivo
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Para desabilitar o bloqueio otimista, use a propriedade de configuração `SkipVersionCheck`. Você pode definir essa propriedade ao criar . `DynamoDBContext`. Nesse caso, o bloqueio otimista está desabilitado para solicitações feitas usando o contexto. Para obter mais informações, consulte [Especificar parâmetros opcionais para DynamoDBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

Em vez de definir a propriedade no nível do contexto, você pode desabilitar o bloqueio otimista para uma operação específica, conforme mostrado no exemplo de código C\$1 a seguir. O exemplo de código usa o contexto para excluir um item de livro. O método `Delete` define a propriedade `SkipVersionCheck` opcional como true, desabilitando a verificação de versão.

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

# Mapear dados arbitrários com o DynamoDB usando o modelo de persistência de objetos do AWS SDK para .NET
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Além dos tipos de .NET compatíveis (consulte [Tipos de dados compatíveis](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), é possível usar tipos em sua aplicação para os quais não há um mapeamento direto para os tipos do Amazon DynamoDB. O modelo de persistência de objetos oferece suporte ao armazenamento de dados de tipos arbitrários, desde que você forneça o conversor para converter dados do tipo arbitrário no tipo do DynamoDB e vice-versa. O código de conversor transforma os dados durante os processos de salvar e carregar os objetos.

É possível criar qualquer tipo no lado do cliente. No entanto, os dados armazenados nas tabelas são um dos tipos do DynamoDB e, durante a consulta e a verificação, qualquer comparação de dados feita baseia-se nos dados armazenados no DynamoDB.

O exemplo de código C\$1 a seguir define uma classe `Book` com as propriedades `Id`, `Title`, `ISBN` e `Dimension`. A propriedade `Dimension` é do `DimensionType`, que descreve as propriedades `Height`, `Width` e `Thickness`. O código de exemplo fornece os métodos de conversor `ToEntry` e `FromEntry` para converter dados entre o `DimensionType` e os tipos de string do DynamoDB. Por exemplo, ao salvar uma instância `Book`, o conversor cria uma string `Dimension` de livro como “8.5x11x.05". Quando você recupera um livro, ele converte a string em uma instância `DimensionType`.

O exemplo mapeia o tipo `Book` na tabela `ProductCatalog`. Ele salva uma instância `Book` de exemplo, recupera essa instância, atualiza suas dimensões e salva novamente o `Book` atualizado.



Para obter instruções passo a passo sobre como testar o exemplo a seguir, consulte [Exemplos 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;
        }
    }
}
```