

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Scopri le basi dell'API DynamoDB Enhanced Client
<a name="ddb-en-client-use"></a>

[Questo argomento illustra le funzionalità di base dell'API DynamoDB Enhanced Client e la confronta con l'API client DynamoDB standard.](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html)

Se non conosci l'API DynamoDB Enhanced Client, ti consigliamo di seguire il tutorial [introduttivo per familiarizzare con le](ddb-en-client-getting-started.md) classi fondamentali.

## Elementi DynamoDB in Java
<a name="ddb-en-client-use-usecase"></a>

Le tabelle DynamoDB memorizzano gli elementi. A seconda del caso d'uso, gli elementi sul lato Java possono assumere la forma di dati strutturati staticamente o di strutture create dinamicamente. 

Se il tuo caso d'uso richiede elementi con un set coerente di attributi, usa [classi annotate](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean) o usa un [builder](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-builder) per generare i tipi statici appropriati. `TableSchema` 

In alternativa, se devi archiviare elementi costituiti da strutture diverse, crea un. `DocumentTableSchema` `DocumentTableSchema`fa parte dell'[API Enhanced Document](ddb-en-client-doc-api.md) e richiede solo una chiave primaria tipizzata staticamente e funziona con le `EnhancedDocument` istanze per contenere gli elementi di dati. [L'API Enhanced Document è trattata in un altro argomento.](ddb-en-client-doc-api.md)

## Tipi di attributi per le classi del modello di dati
<a name="ddb-en-client-use-types"></a>

Sebbene DynamoDB [supporti un numero limitato di tipi di attributi rispetto al rich type system di](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) Java, l'API DynamoDB Enhanced Client fornisce meccanismi per convertire i membri di una classe Java da e verso i tipi di attributi DynamoDB.

I tipi di attributi (proprietà) delle classi di dati Java devono essere tipi di oggetti, non primitivi. Ad esempio, utilizzate `Long` sempre tipi di dati `Integer` oggetto, non `long` e `int` primitivi.

[Per impostazione predefinita, l'API DynamoDB Enhanced Client supporta convertitori di attributi per un gran numero di tipi, [come Integer[,](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) String](https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html) e Instant. [BigDecimal](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/BigDecimalAttributeConverter.html)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/InstantAsStringAttributeConverter.html) L'elenco viene visualizzato nelle [classi di implementazione note](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) dell'interfaccia. AttributeConverter L'elenco include molti tipi e raccolte come mappe, elenchi e set.

Per memorizzare i dati per un tipo di attributo che non è supportato di default o non è conforme alla JavaBean convenzione, puoi scrivere un'`AttributeConverter`implementazione personalizzata per eseguire la conversione. Vedi la sezione sulla conversione degli attributi per un [esempio](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example).

Per memorizzare i dati per un tipo di attributo la cui classe è conforme alla specifica Java beans (o una [classe di dati immutabile](ddb-en-client-use-immut.md)), puoi adottare due approcci. 
+ Se avete accesso al file sorgente, potete annotare la classe con `@DynamoDbBean` (o). `@DynamoDbImmutable` La sezione che illustra gli attributi annidati mostra [esempi](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-anno) di utilizzo di classi annotate.
+ Se non hai accesso al file sorgente della classe di JavaBean dati per l'attributo (o non vuoi annotare il file sorgente di una classe a cui hai accesso), puoi usare l'approccio builder. Questo crea uno schema tabellare senza definire le chiavi. Quindi, puoi annidare questo schema di tabella all'interno di un altro schema di tabella per eseguire la mappatura. La sezione degli attributi nidificati contiene un [esempio](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-builder) che mostra l'uso di schemi nidificati.

### Valori nulli
<a name="ddb-en-client-use-types-nulls"></a>

Quando si utilizza il `putItem` metodo, il client avanzato non include gli attributi con valori nulli di un oggetto dati mappato nella richiesta a DynamoDB.

Il comportamento predefinito dell'SDK per `updateItem` le richieste rimuove gli attributi dall'elemento in DynamoDB che sono impostati su null nell'oggetto inviato nel metodo. `updateItem` Se intendi aggiornare alcuni valori degli attributi e mantenere invariati gli altri, hai due opzioni.
+ Recuperate l'elemento (utilizzando`getItem`) prima di apportare modifiche ai valori. Utilizzando questo approccio, l'SDK invia tutti i valori vecchi e aggiornati a DynamoDB.
+ Usa `[IgnoreNullsMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/IgnoreNullsMode.html).SCALAR_ONLY` o `IgnoreNullsMode.MAPS_ONLY` quando crei la richiesta per aggiornare l'elemento. Entrambe le modalità ignorano le proprietà con valori nulli nell'oggetto che rappresentano gli attributi scalari in DynamoDB. L'[Aggiorna gli elementi che contengono tipi complessi](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-updates)argomento di questa guida contiene ulteriori informazioni sui `IgnoreNullsMode` valori e su come lavorare con tipi complessi.

L'esempio seguente illustra `ignoreNullsMode()` il `updateItem()` metodo.

```
    public static void updateItemNullsExample() {
        Customer customer = new Customer();
        customer.setCustName("CustomerName");
        customer.setEmail("email");
        customer.setId("1");
        customer.setRegistrationDate(Instant.now());

        logger.info("Original customer: {}", customer);

        // Put item with values for all attributes.
        try {
            customerAsyncDynamoDbTable.putItem(customer).join();
        } catch (RuntimeException rte) {
            logger.error("A exception occurred during putItem: {}", rte.getCause().getMessage(), rte);
            return;
        }

        // Create a Customer instance with the same 'id' and 'email' values, but a different 'name' value.
        // Do not set the 'registrationDate' attribute.
        Customer customerForUpdate = new Customer();
        customerForUpdate.setCustName("NewName");
        customerForUpdate.setEmail("email");
        customerForUpdate.setId("1");

        // Update item without setting the 'registrationDate' property and set IgnoreNullsMode to SCALAR_ONLY.
        try {
            Customer updatedWithNullsIgnored = customerAsyncDynamoDbTable.updateItem(b -> b
                            .item(customerForUpdate)
                            .ignoreNullsMode(IgnoreNullsMode.SCALAR_ONLY))
                    .join();
            logger.info("Customer updated with nulls ignored: {}", updatedWithNullsIgnored.toString());
        } catch (RuntimeException rte) {
            logger.error("An exception occurred during updateItem: {}", rte.getCause().getMessage(), rte);
            return;
        }

        // Update item without setting the registrationDate attribute and not setting ignoreNulls to true.
        try {
            Customer updatedWithNullsUsed = customerAsyncDynamoDbTable.updateItem(customerForUpdate)
                    .join();
            logger.info("Customer updated with nulls used: {}", updatedWithNullsUsed.toString());
        } catch (RuntimeException rte) {
            logger.error("An exception occurred during updateItem: {}", rte.getCause().getMessage(), rte);
        }
    }


// Logged lines. 
Original customer: Customer [id=1, name=CustomerName, email=email, regDate=2024-10-11T14:12:30.222858Z]
Customer updated with nulls ignored: Customer [id=1, name=NewName, email=email, regDate=2024-10-11T14:12:30.222858Z]
Customer updated with nulls used: Customer [id=1, name=NewName, email=email, regDate=null]
```

## Metodi di base di DynamoDB Enhanced Client
<a name="ddb-en-client-use-basic-ops"></a>

I metodi di base del client avanzato si associano alle operazioni del servizio DynamoDB da cui prendono il nome. Gli esempi seguenti mostrano la variante più semplice di ciascun metodo. È possibile personalizzare ogni metodo passando un oggetto di richiesta avanzato. Gli oggetti di richiesta avanzati offrono la maggior parte delle funzionalità disponibili nel client DynamoDB standard. Sono completamente documentati nell'API Reference. AWS SDK for Java 2.x 

L'esempio utilizza quanto [Classe `Customer`](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) mostrato in precedenza.

```
// CreateTable
customerTable.createTable();

// GetItem
Customer customer = customerTable.getItem(Key.builder().partitionValue("a123").build());

// UpdateItem
Customer updatedCustomer = customerTable.updateItem(customer);

// PutItem
customerTable.putItem(customer);

// DeleteItem
Customer deletedCustomer = customerTable.deleteItem(Key.builder().partitionValue("a123").sortValue(456).build());

// Query
PageIterable<Customer> customers = customerTable.query(keyEqualTo(k -> k.partitionValue("a123")));

// Scan
PageIterable<Customer> customers = customerTable.scan();

// BatchGetItem
BatchGetResultPageIterable batchResults = 
    enhancedClient.batchGetItem(r -> r.addReadBatch(ReadBatch.builder(Customer.class)
                                      .mappedTableResource(customerTable)
                                      .addGetItem(key1)
                                      .addGetItem(key2)
                                      .addGetItem(key3)
                                      .build()));

// BatchWriteItem
batchResults = enhancedClient.batchWriteItem(r -> r.addWriteBatch(WriteBatch.builder(Customer.class)
                                                   .mappedTableResource(customerTable)
                                                   .addPutItem(customer)
                                                   .addDeleteItem(key1)
                                                   .addDeleteItem(key1)
                                                   .build()));

// TransactGetItems
transactResults = enhancedClient.transactGetItems(r -> r.addGetItem(customerTable, key1)
                                                        .addGetItem(customerTable, key2));

// TransactWriteItems
enhancedClient.transactWriteItems(r -> r.addConditionCheck(customerTable, 
                                                           i -> i.key(orderKey)
                                                                 .conditionExpression(conditionExpression))
                                        .addUpdateItem(customerTable, customer)
                                        .addDeleteItem(customerTable, key));
```

## Confronta DynamoDB Enhanced Client con il client DynamoDB standard
<a name="ddb-en-client-use-compare"></a>

[Entrambi i APIs client DynamoDB, standard [e](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/package-summary.html) avanzato, consentono di lavorare con le tabelle DynamoDB per eseguire operazioni CRUD (creazione, lettura, aggiornamento ed eliminazione) a livello di dati.](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html) La differenza tra i client sta nel modo in cui ciò viene realizzato. APIs Utilizzando il client standard, si lavora direttamente con attributi di dati di basso livello. L'API client avanzata utilizza classi Java familiari e si collega all'API di basso livello dietro le quinte.

Sebbene entrambi i client APIs supportino operazioni a livello di dati, il client DynamoDB standard supporta anche operazioni a livello di risorsa. Le operazioni a livello di risorsa gestiscono il database, come la creazione di backup, l'elenco delle tabelle e l'aggiornamento delle tabelle. L'API client avanzata supporta un numero selezionato di operazioni a livello di risorsa come la creazione, la descrizione e l'eliminazione di tabelle.

Per illustrare i diversi approcci utilizzati dai due client APIs, i seguenti esempi di codice mostrano la creazione della stessa `ProductCatalog` tabella utilizzando il client standard e il client avanzato.

### Confronto: crea una tabella utilizzando il client DynamoDB standard
<a name="ddb-en-client-use-compare-cs1"></a>

```
DependencyFactory.dynamoDbClient().createTable(builder -> builder
        .tableName(TABLE_NAME)
        .attributeDefinitions(
                b -> b.attributeName("id").attributeType(ScalarAttributeType.N),
                b -> b.attributeName("title").attributeType(ScalarAttributeType.S),
                b -> b.attributeName("isbn").attributeType(ScalarAttributeType.S)
        )
        .keySchema(
                builder1 -> builder1.attributeName("id").keyType(KeyType.HASH),
                builder2 -> builder2.attributeName("title").keyType(KeyType.RANGE)
        )
        .globalSecondaryIndexes(builder3 -> builder3
                        .indexName("products_by_isbn")
                        .keySchema(builder2 -> builder2
                                .attributeName("isbn").keyType(KeyType.HASH))
                        .projection(builder2 -> builder2
                                .projectionType(ProjectionType.INCLUDE)
                                .nonKeyAttributes("price", "authors"))
                        .provisionedThroughput(builder4 -> builder4
                                .writeCapacityUnits(5L).readCapacityUnits(5L))
        )
        .provisionedThroughput(builder1 -> builder1
                .readCapacityUnits(5L).writeCapacityUnits(5L))
);
```

### Confronta: crea una tabella utilizzando il DynamoDB Enhanced Client
<a name="ddb-en-client-use-compare-cs2"></a>

```
DynamoDbEnhancedClient enhancedClient = DependencyFactory.enhancedClient();
productCatalog = enhancedClient.table(TABLE_NAME, TableSchema.fromImmutableClass(ProductCatalog.class));
productCatalog.createTable(b -> b
        .provisionedThroughput(b1 -> b1.readCapacityUnits(5L).writeCapacityUnits(5L))
        .globalSecondaryIndices(b2 -> b2.indexName("products_by_isbn")
                .projection(b4 -> b4
                        .projectionType(ProjectionType.INCLUDE)
                        .nonKeyAttributes("price", "authors"))
                .provisionedThroughput(b3 -> b3.writeCapacityUnits(5L).readCapacityUnits(5L))
        )
);
```

Il client avanzato utilizza la seguente classe di dati annotati. Il DynamoDB Enhanced Client mappa i tipi di dati Java ai tipi di dati DynamoDB per un codice meno dettagliato e più facile da seguire. `ProductCatalog`è un esempio di utilizzo di una classe immutabile con DynamoDB Enhanced Client. [L'uso delle classi Immutabili per le classi di dati mappate viene discusso più avanti in questo argomento.](ddb-en-client-use-immut.md)

### Classe `ProductCatalog`
<a name="ddb-en-client-use-compare-cs3"></a>

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

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbIgnore;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.Set;

@DynamoDbImmutable(builder = ProductCatalog.Builder.class)
public class ProductCatalog implements Comparable<ProductCatalog> {
    private Integer id;
    private String title;
    private String isbn;
    private Set<String> authors;
    private BigDecimal price;


    private ProductCatalog(Builder builder){
        this.authors = builder.authors;
        this.id = builder.id;
        this.isbn = builder.isbn;
        this.price = builder.price;
        this.title = builder.title;
    }

    public static Builder builder(){ return new Builder(); }

    @DynamoDbPartitionKey
    public Integer id() { return id; }
    
    @DynamoDbSortKey
    public String title() { return title; }
    
    @DynamoDbSecondaryPartitionKey(indexNames = "products_by_isbn")
    public String isbn() { return isbn; }
    public Set<String> authors() { return authors; }
    public BigDecimal price() { return price; }


    public static final class Builder {
      private Integer id;
      private String title;
      private String isbn;
      private Set<String> authors;
      private BigDecimal price;
      private Builder(){}

      public Builder id(Integer id) { this.id = id; return this; }
      public Builder title(String title) { this.title = title; return this; }
      public Builder isbn(String ISBN) { this.isbn = ISBN; return this; }
      public Builder authors(Set<String> authors) { this.authors = authors; return this; }
      public Builder price(BigDecimal price) { this.price = price; return this; }
      public ProductCatalog build() { return new ProductCatalog(this); }
  }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("ProductCatalog{");
        sb.append("id=").append(id);
        sb.append(", title='").append(title).append('\'');
        sb.append(", isbn='").append(isbn).append('\'');
        sb.append(", authors=").append(authors);
        sb.append(", price=").append(price);
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ProductCatalog that = (ProductCatalog) o;
        return id.equals(that.id) && title.equals(that.title) && Objects.equals(isbn, that.isbn) && Objects.equals(authors, that.authors) && Objects.equals(price, that.price);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, isbn, authors, price);
    }

    @Override
    @DynamoDbIgnore
    public int compareTo(ProductCatalog other) {
        if (this.id.compareTo(other.id) != 0){
            return this.id.compareTo(other.id);
        } else {
            return this.title.compareTo(other.title);
        }
    }
}
```

I due esempi di codice seguenti di scrittura in batch illustrano la verbosità e la mancanza di sicurezza dei tipi quando si utilizza il client standard anziché il client avanzato.

### Confronto: Scrittura in batch utilizzando il client DynamoDB standard
<a name="ddb-en-client-use-compare-cs4"></a>

```
    public static void batchWriteStandard(DynamoDbClient dynamoDbClient, String tableName) {

        Map<String, AttributeValue> catalogItem = Map.of(
                "authors", AttributeValue.builder().ss("a", "b").build(),
                "id", AttributeValue.builder().n("1").build(),
                "isbn", AttributeValue.builder().s("1-565-85698").build(),
                "title", AttributeValue.builder().s("Title 1").build(),
                "price", AttributeValue.builder().n("52.13").build());

        Map<String, AttributeValue> catalogItem2 = Map.of(
                "authors", AttributeValue.builder().ss("a", "b", "c").build(),
                "id", AttributeValue.builder().n("2").build(),
                "isbn", AttributeValue.builder().s("1-208-98073").build(),
                "title", AttributeValue.builder().s("Title 2").build(),
                "price", AttributeValue.builder().n("21.99").build());

        Map<String, AttributeValue> catalogItem3 = Map.of(
                "authors", AttributeValue.builder().ss("g", "k", "c").build(),
                "id", AttributeValue.builder().n("3").build(),
                "isbn", AttributeValue.builder().s("7-236-98618").build(),
                "title", AttributeValue.builder().s("Title 3").build(),
                "price", AttributeValue.builder().n("42.00").build());

        Set<WriteRequest> writeRequests = Set.of(
                WriteRequest.builder().putRequest(b -> b.item(catalogItem)).build(),
                WriteRequest.builder().putRequest(b -> b.item(catalogItem2)).build(),
                WriteRequest.builder().putRequest(b -> b.item(catalogItem3)).build());

        Map<String, Set<WriteRequest>> productCatalogItems = Map.of(
                "ProductCatalog", writeRequests);

        BatchWriteItemResponse response = dynamoDbClient.batchWriteItem(b -> b.requestItems(productCatalogItems));

        logger.info("Unprocessed items: " + response.unprocessedItems().size());
    }
```

### Confronto: Scrittura in batch utilizzando il DynamoDB Enhanced Client
<a name="ddb-en-client-use-compare-cs5"></a>

```
    public static void batchWriteEnhanced(DynamoDbTable<ProductCatalog> productCatalog) {
        ProductCatalog prod = ProductCatalog.builder()
                .id(1)
                .isbn("1-565-85698")
                .authors(new HashSet<>(Arrays.asList("a", "b")))
                .price(BigDecimal.valueOf(52.13))
                .title("Title 1")
                .build();
        ProductCatalog prod2 = ProductCatalog.builder()
                .id(2)
                .isbn("1-208-98073")
                .authors(new HashSet<>(Arrays.asList("a", "b", "c")))
                .price(BigDecimal.valueOf(21.99))
                .title("Title 2")
                .build();
        ProductCatalog prod3 = ProductCatalog.builder()
                .id(3)
                .isbn("7-236-98618")
                .authors(new HashSet<>(Arrays.asList("g", "k", "c")))
                .price(BigDecimal.valueOf(42.00))
                .title("Title 3")
                .build();

        BatchWriteResult batchWriteResult = DependencyFactory.enhancedClient()
                .batchWriteItem(b -> b.writeBatches(
                        WriteBatch.builder(ProductCatalog.class)
                                .mappedTableResource(productCatalog)
                                .addPutItem(prod).addPutItem(prod2).addPutItem(prod3)
                                .build()
                ));
        logger.info("Unprocessed items: " + batchWriteResult.unprocessedPutItemsForTable(productCatalog).size());
    }
```