

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Conceitos básicos da API do Cliente Aprimorado do DynamoDB
<a name="ddb-en-client-getting-started"></a>

O tutorial a seguir apresenta os fundamentos necessários para trabalhar com a API do Cliente Aprimorado do DynamoDB.

## Adicionar dependências
<a name="ddb-en-client-gs-dep"></a>

Para começar a trabalhar com a API do Cliente Aprimorado do DynamoDB em seu projeto, adicione uma dependência no artefato `dynamodb-enhanced` do Maven. Essa ação será mostrada nos exemplos a seguir. 

------
#### [ Maven ]

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version><VERSION></version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>dynamodb-enhanced</artifactId>
    </dependency>
  </dependencies>
  ...
</project>
```

Faça uma pesquisa no repositório central do Maven para obter a [versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk/bom) e *<VERSION>* substitua por esse valor.

------
#### [ Gradle ]

```
repositories {
    mavenCentral()
}
dependencies {
    implementation(platform("software.amazon.awssdk:bom:<VERSION>"))
    implementation("software.amazon.awssdk:dynamodb-enhanced")
    ...
}
```

Faça uma pesquisa no repositório central do Maven para obter a [versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk/bom) e *<VERSION>* substitua por esse valor.

------

# Gerar um `TableSchema` com base em uma classe de dados
<a name="ddb-en-client-gs-tableschema"></a>

O `[TableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableSchema.html)` permite que o cliente avançado mapeie valores de atributos do DynamoDB de e para suas classes do lado do cliente. Neste tutorial, você aprenderá sobre `TableSchema`s derivados de uma classe de dados estática e gerados a partir de código usando um construtor.

## Usar uma classe de dados anotada
<a name="ddb-en-client-gs-tableschema-anno-bean"></a>

O SDK para Java 2.x inclui um [conjunto de anotações](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html) que você pode usar com uma classe de dados para gerar um `TableSchema` de modo rápido para mapear suas classes usando tabelas.

Comece criando uma classe de dados que esteja em conformidade com a [JavaBean especificação](https://download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf). A especificação exige que uma classe tenha um construtor público sem argumentos e que tenha getters e setters para cada atributo na classe. Inclua uma anotação de classe para indicar que a classe de dados é uma `DynamoDbBean`. Além disso, no mínimo, inclua uma anotação `DynamoDbPartitionKey` no getter ou setter do atributo da chave primária. 

É possível aplicar [anotações no nível de atributo](ddb-en-client-anno-index.md) a getters ou setters, mas não a ambos.

**nota**  
O termo normalmente `property` é usado para um valor encapsulado em um. JavaBean No entanto, no lugar desse termo, este guia usa o termo `attribute`, para ser consistente com a terminologia usada pelo DynamoDB.

A classe `Customer` a seguir mostra as anotações que vinculam a definição da classe à tabela do DynamoDB.

### Classe `Customer`
<a name="ddb-en-client-gs-tableschema-anno-bean-cust"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbBean
public class Customer {

    private String id;
    private String name;
    private String email;
    private Instant regDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }

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

    public String getCustName() { return this.name; }

    public void setCustName(String name) { this.name = name; }

    @DynamoDbSortKey
    public String getEmail() { return this.email; }

    public void setEmail(String email) { this.email = email; }

    public Instant getRegistrationDate() { return this.regDate; }

    public void setRegistrationDate(Instant registrationDate) { this.regDate = registrationDate; }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", email=" + email
                + ", regDate=" + regDate + "]";
    }
}
```

Depois de criar uma classe de dados anotada, use-a para criar o `TableSchema`, como será mostrado no trecho a seguir.

```
static final TableSchema<Customer> customerTableSchema = TableSchema.fromBean(Customer.class);
```

Um `TableSchema` é projetado para ser estático e imutável. Normalmente, você pode instanciá-lo no momento do carregamento da classe.

O método de fábrica estático `TableSchema.fromBean()` inspeciona o bean para gerar o mapeamento entre os atributos da classe de dados (propriedades) e os atributos do DynamoDB.

Para ver um exemplo de como trabalhar com um modelo de dados composto por várias classes de dados, consulte a classe `Person` na seção [Trabalhar com atributos que são beans, mapas, listas e conjuntos](ddb-en-client-adv-features-nested.md).

## Usar um construtor
<a name="ddb-en-client-gs-tableschema-builder"></a>

Você pode ignorar o custo da introspecção do bean se definir o esquema da tabela no código. Se você codificar o esquema, sua classe não precisará seguir os padrões de JavaBean nomenclatura nem precisará ser anotada. O exemplo a seguir usa um construtor e é equivalente ao exemplo de classe `Customer` que usa anotações.

```
static final TableSchema<Customer> customerTableSchema =
                TableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(Customer::getId)
                                .setter(Customer::setId)
                                .tags(StaticAttributeTags.primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("email")
                                .getter(Customer::getEmail)
                                .setter(Customer::setEmail)
                                .tags(StaticAttributeTags.primarySortKey()))
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getCustName)
                                .setter(Customer::setCustName))
                        .addAttribute(Instant.class, a -> a.name("registrationDate")
                                .getter(Customer::getRegistrationDate)
                                .setter(Customer::setRegistrationDate))
                        .build();
```

# Criar um cliente aprimorado e uma `DynamoDbTable`
<a name="ddb-en-client-getting-started-dynamodbTable"></a>

## Criar um cliente aprimorado
<a name="ddb-en-client-getting-started-dynamodbTable-eclient"></a>

A [DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html)classe, ou sua contraparte assíncrona, [DynamoDbEnhancedAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedAsyncClient.html), é o ponto de entrada para trabalhar com a API do DynamoDB Enhanced Client.

O cliente aprimorado exige um `[DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)` padrão para realizar operações. A API oferece duas maneiras de criar uma instância `DynamoDbEnhancedClient`. A primeira opção, mostrada no trecho a seguir, cria um `DynamoDbClient` padrão com configurações padrão retiradas das definições de configuração.

```
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();
```

Se quiser configurar o cliente padrão subjacente, você poderá fornecê-lo ao método construtor do cliente aprimorado, conforme mostrado no trecho a seguir.

```
// Configure an instance of the standard DynamoDbClient.
DynamoDbClient standardClient = DynamoDbClient.builder()
    .region(Region.US_EAST_1)
    .credentialsProvider(ProfileCredentialsProvider.create())
    .build();

// Use the configured standard client with the enhanced client.
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
    .dynamoDbClient(standardClient)
    .build();
```

## Criar uma instância `DynamoDbTable`
<a name="ddb-en-client-getting-started-dynamodbTable-table"></a>

Pense em uma [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html) como a representação do lado do cliente de uma tabela do DynamoDB que usa a funcionalidade de mapeamento fornecida por um `TableSchema`. A classe `DynamoDbTable` fornece métodos para operações CRUD que permitem que você interaja com uma única tabela do DynamoDB.

`DynamoDbTable<T>` é uma classe genérica que usa um argumento de tipo único, seja uma classe personalizada ou `EnhancedDocument`, ao trabalhar com itens do tipo documento. Esse tipo de argumento estabelece a relação entre a classe que você usa e a tabela única do DynamoDB.

Use o método de fábrica `table()` do `DynamoDbEnhancedClient` para criar uma instância `DynamoDbTable` conforme será mostrado no trecho a seguir.

```
static final DynamoDbTable<Customer> customerTable = 
        enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

Instâncias `DynamoDbTable` são candidatas a singletons porque são imutáveis e podem ser usadas em toda a sua aplicação.

O código agora tem uma representação na memória de uma tabela do DynamoDB que pode funcionar com instâncias `Customer`. A tabela do DynamoDB pode ou não existir. Se a tabela chamada `Customer` já existir, você poderá começar a realizar operações CRUD nela. Se ela não existir, use a instância `DynamoDbTable` para criar a tabela conforme será discutido na próxima seção.

# Criar uma tabela do DynamoDB se for necessário
<a name="ddb-en-client-gs-ddbtable"></a>

Depois de criar uma instância `DynamoDbTable`, use-a para realizar uma criação *única* de uma tabela no DynamoDB.

## Exemplo de código para criar tabela
<a name="ddb-en-client-gs-ddbtable-createex"></a>

O exemplo a seguir cria uma tabela do DynamoDB com base na classe de dados `Customer`. 

Este exemplo cria uma tabela do DynamoDB com o nome `Customer`, que é idêntico ao nome da classe, mas o nome da tabela pode ser diferente. Seja qual for o nome da tabela, você deverá usar esse nome em aplicativos adicionais para trabalhar com a tabela. Forneça esse nome ao método `table()` sempre que criar outro objeto de `DynamoDbTable` para trabalhar com a tabela subjacente do DynamoDB.

O parâmetro Java lambda, `builder`, passado para o método `createTable`, permite que você [personalize a tabela](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/CreateTableEnhancedRequest.Builder.html). Neste exemplo, o [throughput provisionado](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual) está configurado. Se você quiser usar as configurações padrão ao criar uma tabela, ignore o construtor, conforme mostrado no trecho a seguir.

```
customerTable.createTable();
```

Quando as configurações padrão são usadas, os valores para o throughput provisionado não são definidos. Em vez disso, o modo de faturamento da tabela é definido como [sob demanda](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand).

O exemplo também usa um `[DynamoDbWaiter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/waiters/DynamoDbWaiter.html)` antes de tentar imprimir o nome da tabela recebida na resposta. A criação de uma tabela leva algum tempo. Portanto, usar um waiter significa que você não precisa escrever uma lógica que pesquise no DynamoDB para ver se a tabela existe antes de usá-la.

### Importações
<a name="ddb-en-client-gs-ddbtable-imports"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.core.internal.waiters.ResponseOrException;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.CreateTableEnhancedRequest;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter;
```

### Código
<a name="ddb-en-client-gs-ddbtable-code"></a>

```
 public static void createCustomerTable(DynamoDbTable<Customer> customerTable, DynamoDbClient standardClient) {
     // Create the DynamoDB table using the 'customerTable' DynamoDbTable instance.
     customerTable.createTable(builder -> builder
             .provisionedThroughput(b -> b
                     .readCapacityUnits(10L)
                     .writeCapacityUnits(10L)
                     .build())
     );
     // The DynamoDbClient instance (named 'standardClient') passed to the builder for the DynamoDbWaiter is the same instance
     // that was passed to the builder of the DynamoDbEnhancedClient instance that we created previously.
     // By using the same instance, it ensures that the same Region that was configured on the standard DynamoDbClient 
     // instance is used for other service clients that accept a DynamoDbClient during construction.
     try (DynamoDbWaiter waiter = DynamoDbWaiter.builder().client(standardClient).build()) { // DynamoDbWaiter is Autocloseable
         ResponseOrException<DescribeTableResponse> response = waiter
                 .waitUntilTableExists(builder -> builder.tableName("Customer").build())
                 .matched();
         DescribeTableResponse tableDescription = response.response().orElseThrow(
                 () -> new RuntimeException("Customer table was not created."));
         // The actual error can be inspected in response.exception()
         logger.info("Customer table was created.");
     }
 }
```

**nota**  
Os nomes dos atributos de uma tabela do DynamoDB começam com uma letra minúscula quando a tabela é gerada a partir de uma classe de dados. Se você quiser que o nome do atributo da tabela comece com uma letra maiúscula, use a [anotação `@DynamoDbAttribute(NAME)`](ddb-en-client-adv-features-inex-attr.md) e forneça o nome desejado como parâmetro.

# Executar operações
<a name="ddb-en-client-gs-use"></a>

Depois que a tabela for criada, use a instância `DynamoDbTable` para realizar operações na tabela do DynamoDB. 

No exemplo a seguir, um singleton `DynamoDbTable<Customer>` é passado como parâmetro junto com uma instância de [classe de dados `Customer`](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) para adicionar um novo item à tabela.

```
    public static void putItemExample(DynamoDbTable<Customer> customerTable, Customer customer){
        logger.info(customer.toString());
        customerTable.putItem(customer);
    }
```

## Objeto `Customer`
<a name="perform_ops_create_customer_instatnce"></a>

```
        Customer customer = new Customer();
        customer.setId("1");
        customer.setCustName("Customer Name");
        customer.setEmail("customer@example.com");
        customer.setRegistrationDate(Instant.parse("2023-07-03T10:15:30.00Z"));
```

Antes de enviar o objeto `customer` para o DynamoDB, registre a saída do método `toString()` do objeto para compará-la com o que é enviado pelo cliente aprimorado.

```
Customer [id=1, name=Customer Name, email=customer@example.com, regDate=2023-07-03T10:15:30Z]
```

O registro em log em nível de conexão mostra a carga útil da solicitação gerada. O cliente aprimorado gerou a representação de nível baixo da classe de dados. O atributo `regDate`, que é um tipo `Instant` em Java, é representado como uma cadeia de caracteres do DynamoDB.

```
{
  "TableName": "Customer",
  "Item": {
    "registrationDate": {
      "S": "2023-07-03T10:15:30Z"
    },
    "id": {
      "S": "1"
    },
    "custName": {
      "S": "Customer Name"
    },
    "email": {
      "S": "customer@example.com"
    }
  }
}
```

# Trabalhar com uma tabela existente
<a name="ddb-en-client-gs-existingtable"></a>

A seção anterior mostrou como criar uma tabela do DynamoDB começando com uma classe de dados Java. Se você já tiver uma tabela existente e quiser usar os atributos do cliente aprimorado, poderá criar uma classe de dados Java para trabalhar com a tabela. Você precisa examinar a tabela do DynamoDB e adicionar as anotações necessárias à classe de dados. 

Antes de trabalhar com uma tabela existente, chame o método `DynamoDbEnhanced.table()`. Isso foi feito no exemplo anterior com a seguinte instrução:

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

Depois que a instância `DynamoDbTable` for retornada, você poderá começar a trabalhar imediatamente com a tabela subjacente. Você não precisa recriar a tabela chamando o método `DynamoDbTable.createTable()`.

O exemplo a seguir demonstra isso recuperando imediatamente uma instância `Customer` da tabela do DynamoDB.

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
// The Customer table exists already and has an item with a primary key value of "1" and a sort key value of "customer@example.com".
customerTable.getItem(
        Key.builder().
                partitionValue("1").
                sortValue("customer@example.com").build());
```

**Importante**  
O nome da tabela usado no método `table()` deve corresponder ao nome da tabela existente do DynamoDB.