

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Lernen Sie die Grundlagen der DynamoDB Enhanced Client API kennen
<a name="ddb-en-client-use"></a>

In diesem Thema werden die grundlegenden Funktionen der DynamoDB Enhanced Client API beschrieben und sie mit der [standardmäßigen DynamoDB-Client-API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html) verglichen.

Wenn Sie mit der DynamoDB Enhanced Client API noch nicht vertraut sind, empfehlen wir Ihnen, das [Einführungstutorial](ddb-en-client-getting-started.md) zu lesen, um sich mit den grundlegenden Klassen vertraut zu machen.

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

DynamoDB-Tabellen speichern Elemente. Abhängig von Ihrem Anwendungsfall können Elemente auf der Java-Seite die Form von statisch strukturierten Daten oder dynamisch erstellten Strukturen annehmen. 

Wenn Ihr Anwendungsfall Elemente mit einem konsistenten Satz von Attributen erfordert, verwenden Sie [annotierte Klassen](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean) oder verwenden Sie einen [Builder](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-builder), um die entsprechenden statisch typisierten Elemente zu generieren. `TableSchema` 

Wenn Sie Elemente speichern müssen, die aus unterschiedlichen Strukturen bestehen, können Sie alternativ eine erstellen. `DocumentTableSchema` `DocumentTableSchema`ist Teil der [Enhanced Document API](ddb-en-client-doc-api.md) und benötigt nur einen statisch typisierten Primärschlüssel und funktioniert mit `EnhancedDocument` Instanzen, die die Datenelemente enthalten. [Die Enhanced Document API wird in einem anderen Thema behandelt.](ddb-en-client-doc-api.md)

## Attributtypen für Datenmodellklassen
<a name="ddb-en-client-use-types"></a>

Obwohl DynamoDB im Vergleich zum Rich-Type-System [von Java eine geringe Anzahl von Attributtypen](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) unterstützt, bietet die DynamoDB Enhanced Client API Mechanismen zum Konvertieren von Mitgliedern einer Java-Klasse in und aus DynamoDB-Attributtypen.

Bei den Attributtypen (Eigenschaften) Ihrer Java-Datenklassen sollte es sich um Objekttypen und nicht um Primitive handeln. Verwenden Sie beispielsweise immer Datentypen `Long` und `Integer` Objekte, nicht `long` `int` Primitive.

[Standardmäßig unterstützt die DynamoDB Enhanced Client-API Attributkonverter für eine Vielzahl von Typen, wie [Integer [BigDecimal](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/BigDecimalAttributeConverter.html)](https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html), [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) und Instant.](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/InstantAsStringAttributeConverter.html) Die Liste wird in den [bekannten Implementierungsklassen der AttributeConverter Schnittstelle](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) angezeigt. Die Liste enthält viele Typen und Sammlungen wie Karten, Listen und Sets.

Um die Daten für einen Attributtyp zu speichern, der standardmäßig nicht unterstützt wird oder nicht der JavaBean Konvention entspricht, können Sie eine benutzerdefinierte `AttributeConverter` Implementierung für die Konvertierung schreiben. Ein [Beispiel](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example) finden Sie im Abschnitt zur Attributkonvertierung.

Um die Daten für einen Attributtyp zu speichern, dessen Klasse der Java-Beans-Spezifikation (oder einer [unveränderlichen Datenklasse](ddb-en-client-use-immut.md)) entspricht, können Sie zwei Ansätze wählen. 
+ Wenn Sie Zugriff auf die Quelldatei haben, können Sie die Klasse mit `@DynamoDbBean` (oder) annotieren. `@DynamoDbImmutable` Der Abschnitt, der verschachtelte Attribute behandelt, zeigt [Beispiele für](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-anno) die Verwendung von Klassen mit Anmerkungen.
+ Wenn Sie keinen Zugriff auf die Quelldatei der JavaBean Datenklasse für das Attribut haben (oder Sie die Quelldatei einer Klasse, auf die Sie Zugriff haben, nicht mit Anmerkungen versehen möchten), können Sie den Builder-Ansatz verwenden. Dadurch wird ein Tabellenschema erstellt, ohne die Schlüssel zu definieren. Anschließend können Sie dieses Tabellenschema in einem anderen Tabellenschema verschachteln, um die Zuordnung durchzuführen. Der Abschnitt mit verschachtelten Attributen enthält ein [Beispiel](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-builder), das die Verwendung verschachtelter Schemas zeigt.

### Null-Werte
<a name="ddb-en-client-use-types-nulls"></a>

Wenn Sie die `putItem` Methode verwenden, nimmt der erweiterte Client keine nullwertigen Attribute eines zugewiesenen Datenobjekts in die Anforderung an DynamoDB auf.

Das Standardverhalten des SDK für `updateItem` Anfragen entfernt Attribute aus dem Element in DynamoDB, die in dem Objekt, das Sie in der Methode einreichen, auf Null gesetzt sind. `updateItem` Wenn Sie beabsichtigen, einige Attributwerte zu aktualisieren und die anderen unverändert zu lassen, haben Sie zwei Möglichkeiten.
+ Rufen Sie das Element (mithilfe von`getItem`) ab, bevor Sie Änderungen an den Werten vornehmen. Mit diesem Ansatz übermittelt das SDK alle aktualisierten und alten Werte an DynamoDB.
+ Verwenden Sie entweder `[IgnoreNullsMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/IgnoreNullsMode.html).SCALAR_ONLY` oder, `IgnoreNullsMode.MAPS_ONLY` wenn Sie die Anfrage erstellen, um das Element zu aktualisieren. Beide Modi ignorieren nullwertige Eigenschaften im Objekt, die skalare Attribute in DynamoDB darstellen. Das [Aktualisieren Sie Elemente, die komplexe Typen enthalten](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-updates) Thema in diesem Handbuch enthält weitere Informationen zu den `IgnoreNullsMode` Werten und zur Arbeit mit komplexen Typen.

Das folgende `ignoreNullsMode()` Beispiel zeigt die `updateItem()` Methode.

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

## Grundlegende Methoden des DynamoDB Enhanced Client
<a name="ddb-en-client-use-basic-ops"></a>

Die grundlegenden Methoden des erweiterten Clients sind den DynamoDB-Dienstoperationen zugeordnet, nach denen sie benannt sind. Die folgenden Beispiele zeigen die einfachste Variante der einzelnen Methoden. Sie können jede Methode anpassen, indem Sie ein erweitertes Anforderungsobjekt übergeben. Verbesserte Anforderungsobjekte bieten die meisten Funktionen, die im Standard-DynamoDB-Client verfügbar sind. Sie sind in der AWS SDK for Java 2.x API-Referenz vollständig dokumentiert.

Das Beispiel verwendet das zuvor [`Customer`-Klasse](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) Gezeigte.

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

## DynamoDB Enhanced Client mit dem Standard-DynamoDB-Client vergleichen
<a name="ddb-en-client-use-compare"></a>

Sowohl der [standardmäßige](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html) als auch der [erweiterte](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/package-summary.html) DynamoDB-Client APIs ermöglichen es Ihnen, mit DynamoDB-Tabellen zu arbeiten, um CRUD-Operationen (Create, Read, Update and Delete) auf Datenebene durchzuführen. Der Unterschied zwischen den Clients besteht darin, wie dies erreicht wird. APIs Mit dem Standard-Client arbeiten Sie direkt mit Datenattributen auf niedriger Ebene. Die erweiterte Client-API verwendet vertraute Java-Klassen und ist der Low-Level-API im Hintergrund zugeordnet.

Während beide Clients Operationen auf Datenebene APIs unterstützen, unterstützt der standardmäßige DynamoDB-Client auch Operationen auf Ressourcenebene. Operationen auf Ressourcenebene verwalten die Datenbank, z. B. das Erstellen von Backups, das Auflisten von Tabellen und das Aktualisieren von Tabellen. Die erweiterte Client-API unterstützt eine bestimmte Anzahl von Vorgängen auf Ressourcenebene, z. B. das Erstellen, Beschreiben und Löschen von Tabellen.

Um die unterschiedlichen Ansätze der beiden Clients zu veranschaulichen APIs, zeigen die folgenden Codebeispiele die Erstellung derselben `ProductCatalog` Tabelle mit dem Standard-Client und dem erweiterten Client.

### Vergleichen: Erstellen Sie eine Tabelle mit dem standardmäßigen DynamoDB-Client
<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))
);
```

### Vergleichen: Erstellen Sie eine Tabelle mit dem 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))
        )
);
```

Der erweiterte Client verwendet die folgende Datenklasse mit Anmerkungen. Der DynamoDB Enhanced Client ordnet Java-Datentypen DynamoDB-Datentypen zu und sorgt so für weniger ausführlichen Code, der leichter nachzuvollziehen ist. `ProductCatalog`ist ein Beispiel für die Verwendung einer unveränderlichen Klasse mit dem DynamoDB Enhanced Client. Die Verwendung unveränderlicher Klassen für zugeordnete Datenklassen wird später in diesem [Thema erörtert](ddb-en-client-use-immut.md).

### `ProductCatalog`-Klasse
<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);
        }
    }
}
```

Die folgenden beiden Codebeispiele für Batch-Schreibvorgänge veranschaulichen die Ausführlichkeit und die mangelnde Typsicherheit bei der Verwendung des Standardclients im Gegensatz zum erweiterten Client.

### Vergleich: Batch-Schreiben mit dem standardmäßigen DynamoDB-Client
<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());
    }
```

### Vergleich: Batch-Schreiben mit dem 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());
    }
```