

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.

# Programmieren mit DynamoDB und AWS SDKs
<a name="Programming"></a>

In diesem Abschnitt werden entwicklerbezogene Themen behandelt. Wenn Sie stattdessen Codebeispiele ausführen möchten, lesen Sie [Ausführen der Codebeispiele in diesem Entwicklerhandbuch](CodeSamples.md). 

**Anmerkung**  
Im Dezember 2017 AWS begann der Prozess der Migration aller Amazon DynamoDB DynamoDB-Endpunkte zur Verwendung von sicheren Zertifikaten, die von Amazon Trust Services (ATS) ausgestellt wurden. Weitere Informationen finden Sie unter [Behebung von Problemen SSL/TLS beim Verbindungsaufbau mit DynamoDB](ats-certs.md). 

**Topics**
+ [

# Überblick über die AWS SDK-Unterstützung für DynamoDB
](Programming.SDKOverview.md)
+ [

# Programmieren von Amazon DynamoDB mit Python und Boto3
](programming-with-python.md)
+ [

# Programmieren von Amazon DynamoDB mit JavaScript
](programming-with-javascript.md)
+ [

# Programmieren von DynamoDB mit dem AWS SDK for Java 2.x
](ProgrammingWithJava.md)
+ [

# Fehlerbehandlung mit DynamoDB
](Programming.Errors.md)
+ [

# DynamoDB mit einem SDK verwenden AWS
](sdk-general-information-section.md)

# Überblick über die AWS SDK-Unterstützung für DynamoDB
<a name="Programming.SDKOverview"></a>

Das folgende Diagramm bietet einen allgemeinen Überblick über die Amazon DynamoDB DynamoDB-Anwendungsprogrammierung mit dem. AWS SDKs

![\[Programmiermodell für die Verwendung von DynamoDB mit. AWS SDKs\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. Sie schreiben eine Anwendung mit einem AWS SDK für Ihre Programmiersprache.

1. Jedes AWS SDK bietet eine oder mehrere programmatische Schnittstellen für die Arbeit mit DynamoDB. Welche spezifischen Schnittstellen verfügbar sind, hängt davon ab, welche Programmiersprache und welches AWS SDK Sie verwenden. Zu den Optionen gehören:
   + [Low-Level-Schnittstellen, die mit DynamoDB funktionieren](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [Dokumentschnittstellen, die mit DynamoDB funktionieren](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [Schnittstellen für Objektpersistenz, die mit DynamoDB funktionieren](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [High-Level-Schnittstellen](HigherLevelInterfaces.md)

1. Das AWS SDK erstellt HTTP (S) -Anfragen zur Verwendung mit der Low-Level-DynamoDB-API.

1. Das AWS SDK sendet die Anfrage an den DynamoDB-Endpunkt.

1. DynamoDB führt die Anforderung aus. Wenn die Anforderung erfolgreich ist, gibt DynamoDB einen HTTP-200-Antwortcode zurück (OK). Wenn die Anforderung fehlschlägt, gibt DynamoDB einen HTTP-Fehlercode und eine Fehlermeldung zurück.

1. Das AWS SDK verarbeitet die Antwort und leitet sie zurück an Ihre Anwendung.

Jedes von ihnen AWS SDKs stellt wichtige Dienste für Ihre Anwendung bereit, darunter die folgenden:
+ Formatieren von HTTP(S)-Anforderungen und Serialisieren von Anforderungsparametern
+ Erstellen einer kryptografischen Signatur für jede Anforderung
+ Weiterleiten von Anforderungen an einen DynamoDB-Endpunkt und Empfangen von Antworten von DynamoDB.
+ Extrahieren der Ergebnisse dieser Antworten
+ Implementieren einer grundlegenden Retry-Logik im Falle von Fehlern

Sie müssen für keine dieser Aufgaben einen Code schreiben.

**Anmerkung**  
Weitere Informationen AWS SDKs, einschließlich Installationsanweisungen und Dokumentation, finden Sie unter [Tools for Amazon Web Services](https://aws.amazon.com/tools).

## SDK-Unterstützung für AWS kontobasierte Endgeräte
<a name="Programming.SDKs.endpoints"></a>

AWS führt die SDK-Unterstützung für AWS-account-basierte Endpunkte für DynamoDB ein, beginnend mit dem AWS SDK for Java V1 am 4. September 2024. Diese neuen Endpunkte tragen dazu bei AWS , eine hohe Leistung und Skalierbarkeit sicherzustellen. Die aktualisierte SDKs Version verwendet automatisch die neuen Endpunkte, die das Format haben. `https://(account-id).ddb.(region).amazonaws.com`

Wenn Sie eine einzelne Instance eines SDK-Clients verwenden, um Anfragen an mehrere Konten zu stellen, hat Ihre Anwendung weniger Möglichkeiten, Verbindungen wiederzuverwenden. AWS empfiehlt, Ihre Anwendung so anzupassen, dass pro SDK-Client-Instance weniger Konten angesprochen werden. Eine Alternative besteht darin, Ihren SDK-Client mithilfe dieser `ACCOUNT_ID_ENDPOINT_MODE` Einstellung so einzurichten, dass er weiterhin regionale Endpunkte verwendet, wie im Referenzhandbuch [https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html) dokumentiert.

# Programmierschnittstellen, die mit DynamoDB funktionieren
<a name="Programming.SDKs.Interfaces"></a>

Jedes [AWS SDK ](https://aws.amazon.com/tools) bietet eine oder mehrere programmgesteuerte Schnittstellen für die Arbeit mit Amazon DynamoDB. Diese Schnittstellen reichen von einfachen Low-Level-DynamoDB-Wrapper zu objektorientierten Persistenzschichten. Die verfügbaren Schnittstellen variieren je nach AWS SDK und verwendeter Programmiersprache.

![\[Programmatische Schnittstellen sind in verschiedenen Ausführungen AWS SDKs für die Arbeit mit DynamoDB verfügbar.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


Der folgende Abschnitt hebt einige der verfügbaren Schnittstellen hervor und verwendet AWS SDK für Java als Beispiel. (Nicht alle Schnittstellen sind in allen verfügbar.) AWS SDKs

**Topics**
+ [

## Low-Level-Schnittstellen, die mit DynamoDB funktionieren
](#Programming.SDKs.Interfaces.LowLevel)
+ [

## Dokumentschnittstellen, die mit DynamoDB funktionieren
](#Programming.SDKs.Interfaces.Document)
+ [

## Schnittstellen für Objektpersistenz, die mit DynamoDB funktionieren
](#Programming.SDKs.Interfaces.Mapper)

## Low-Level-Schnittstellen, die mit DynamoDB funktionieren
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

Jedes sprachspezifische AWS SDK bietet eine Low-Level-Schnittstelle für Amazon DynamoDB mit Methoden, die DynamoDB-API-Anfragen auf niedriger Ebene sehr ähnlich sind.

In einigen Fällen müssen Sie die Datentypen der Attribute mithilfe von [Datentypbeschreibungen](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors) identifizieren, so wie `S` für Zeichenfolge und `N` für Zahl.

**Anmerkung**  
Ein Low-Level-Schnittstelle ist in jeder sprachspezifischen AWS -SDK verfügbar.

Das folgende Java-Programm verwendet die Low-Level-Schnittstelle des AWS SDK für Java. 

### Beispiel einer Low-Level-Schnittstelle
<a name="low-level-example"></a>

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

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal>

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

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

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

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

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

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

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

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

## Dokumentschnittstellen, die mit DynamoDB funktionieren
<a name="Programming.SDKs.Interfaces.Document"></a>

Viele AWS SDKs bieten eine Dokumentschnittstelle, über die Sie Operationen auf Datenebene (Erstellen, Lesen, Aktualisieren, Löschen) für Tabellen und Indizes ausführen können. Mit einer Dokumentschnittstelle müssen Sie [Datentypbeschreibungen](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors) nicht angeben. Die Datentypen werden durch die Semantiken der Daten selber bereitgestellt. Diese bieten AWS SDKs auch Methoden zur einfachen Konvertierung von JSON-Dokumenten in und aus nativen Amazon DynamoDB DynamoDB-Datentypen.

**Anmerkung**  
[Dokumentschnittstellen sind im AWS SDKs für [Java](https://aws.amazon.com/sdk-for-java), [.NET](https://aws.amazon.com/sdk-for-net), [Node.js](https://aws.amazon.com/sdk-for-node-js) und JavaScript SDK verfügbar.](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)

Das folgende Java-Programm verwendet die Dokumentschnittstelle des AWS SDK für Java. Das Programm erstellt ein `Table`-Objekt, das die `Music`-Tabelle repräsentiert und fordert dieses Objekt auf, `GetItem` zu verwenden, um einen Song abzurufen. Das Programm gibt dann das Jahr aus, in dem der Song veröffentlicht wurde.

Die `software.amazon.dynamodb.document.DynamoDB`-Klasse implementiert die DynamoDB-Dokumentschnittstelle. Beachten Sie, wie `DynamoDB` als Wrapper um den Low-Level-Client agiert (`AmazonDynamoDB`).

### Beispiel für eine Dokumentschnittstelle
<a name="document-level-example"></a>

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

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

public class MusicDocumentDemo {

    public static void main(String[] args) {

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

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

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

    }
}
```

## Schnittstellen für Objektpersistenz, die mit DynamoDB funktionieren
<a name="Programming.SDKs.Interfaces.Mapper"></a>

Einige AWS SDKs bieten eine Schnittstelle zur Objektpersistenz, über die Sie keine direkten Operationen auf der Datenebene ausführen können. Stattdessen erstellen Sie Objekte, die Elemente in Amazon-DynamoDB-Tabellen und Indexe repräsentieren, und interagieren ausschließlich mit diesen Objekten. Auf diese Weise können Sie objektorientierte Codes statt datenbankorientierter Codes schreiben.

**Anmerkung**  
Schnittstellen AWS SDKs für Objektpersistenz sind in Java und .NET verfügbar. Weitere Informationen finden Sie unter [Higher-Level-Programmierschnittstellen für DynamoDB](HigherLevelInterfaces.md) für DynamoDB.

### Beispiel einer Objektpersistenzschnittstelle
<a name="mapper-level-example"></a>

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

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

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

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

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

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

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

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

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

# Higher-Level-Programmierschnittstellen für DynamoDB
<a name="HigherLevelInterfaces"></a>

 AWS SDKs Sie bieten Anwendungen mit Low-Level-Schnittstellen für die Arbeit mit Amazon DynamoDB. Diese clientseitigen Klassen und Methoden entsprechen direkt der Low-Level-API von DynamoDB API. Doch viele Entwickler stellen *Impedanzfehlanpassungen* fest, wenn sie Elementen in einer Datenbanktabelle komplexe Datentypen zuordnen müssen. Mit einer Low-Level-Datenbankschnittstelle müssen Entwickler Methoden zum Lesen oder Schreiben von Objektdaten in Datenbanktabellen und umgekehrt entwickeln. Die Menge des zusätzlich erforderlichen Codes für jede Kombination aus Objekttyp und Datenbanktabelle kann überwältigend erscheinen.

Um die Entwicklung zu vereinfachen, bieten die AWS SDKs für Java und .NET zusätzliche Schnittstellen mit höheren Abstraktionsebenen. Mit den High-Level-Schnittstellen für DynamoDB-Objekte können Sie die Beziehungen zwischen Objekten in Ihrem Programm und den Datenbanktabellen definieren, die die Daten dieser Objekte speichern. Nachdem Sie diese Mappings definiert haben, rufen Sie einfache Objektmethoden wie `save`, `load` oder `delete` auf. Die zugrunde liegenden DynamoDB-Low-Level-Operationen werden dann in Ihrem Namen automatisch aufgerufen. Auf diese Weise können Sie objektorientierte Codes statt datenbankorientierter Codes schreiben.

Die übergeordneten Programmierschnittstellen für DynamoDB sind in den Versionen AWS SDKs für Java und .NET verfügbar.

**Java**
+ [Java 1.x: Dynamo DBMapper](DynamoDBMapper.md)
+ [Java 2.x: Erweiterter DynamoDB-Client](DynamoDBEnhanced.md)

**.NET**
+ [Arbeiten dem .NET-Dokumentmodell in DynamoDB](DotNetSDKMidLevel.md)
+ [Arbeiten mit dem Object Persistence-Modell von .NET und DynamoDB](DotNetSDKHighLevel.md)

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

**Anmerkung**  
Das SDK für Java ist in zwei Versionen verfügbar: 1.x und 2.x. Die Version end-of-support für 1.x wurde [am 12. Januar 2024 angekündigt](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/). Es wird und end-of-support ist am 31. Dezember 2025 fällig. Für Neuentwicklungen wird die Verwendung von Version 2.x empfohlen.

Die AWS SDK für Java stellt eine `DynamoDBMapper` Klasse bereit, mit der Sie Ihre clientseitigen Klassen Amazon DynamoDB-Tabellen zuordnen können. Um `DynamoDBMapper` zu verwenden, definieren Sie die Beziehung zwischen Elementen in einer DynamoDB-Tabelle und ihren entsprechenden Objekt-Instances im Code. Die `DynamoDBMapper`-Klasse ermöglicht Ihnen auch die Ausführung verschiedener Create-, Read-, Update-, und Delete-Operationen (CRUD) für Elemente sowie das Ausführen von Abfragen und Scans für Tabellen.

**Topics**
+ [

# Dynamo-Klasse DBMapper
](DynamoDBMapper.Methods.md)
+ [

# Unterstützte Datentypen für Dynamo DBMapper für Java
](DynamoDBMapper.DataTypes.md)
+ [

# Java-Anmerkungen für DynamoDB
](DynamoDBMapper.Annotations.md)
+ [

# Optionale Konfigurationseinstellungen für Dynamo DBMapper
](DynamoDBMapper.OptionalConfig.md)
+ [

# DynamoDB und optimistische Sperren mit Versionsnummer
](DynamoDBMapper.OptimisticLocking.md)
+ [

# Zuordnen willkürlicher Daten in DynamoDB
](DynamoDBMapper.ArbitraryDataMapping.md)
+ [

# Beispiele für DynamoDBMapper
](DynamoDBMapper.Examples.md)

**Anmerkung**  
Die `DynamoDBMapper`-Klasse erlaubt kein Erstellen, Aktualisieren oder Löschen von Tabellen. Zum Ausführen dieser Aufgaben verwenden Sie stattdessen die Low-Level-SDK-für-Java-Schnittstelle. 

Das SDK für Java stellt eine Reihe von Anmerkungstypen bereit, damit Sie Ihre Klassen zu Tabellen zuweisen können. Betrachten Sie beispielsweise eine `ProductCatalog`-Tabelle, die `Id` als Partitionsschlüssel verwendet. 

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

Sie können der `ProductCatalog`-Tabelle eine Klasse in Ihrer Client-Anwendung zuweisen wie im folgenden Java-Code gezeigt. Diese Code definiert ein Plain Old Java Object (POJO) mit dem Namen `CatalogItem`, das Anmerkungen verwendet, um Objektfelder zu DynamoDB-Attributnamen zuzuweisen:

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

Im vorherigen Code weist die Anmerkung `@DynamoDBTable` die Klasse `CatalogItem` der Tabelle `ProductCatalog` zu. Sie können einzelne Klassen-Instances als Elemente in der Tabelle speichern. Die Anmerkung `@DynamoDBHashKey` weist die Eigenschaft `Id` dem Primärschlüssel zu. 

Standardmäßig sind die Klasseneigenschaften denselben Attributnamen in der Tabelle zugeordnet. Die Eigenschaften `Title` und `ISBN` sind den gleichen Attributnamen in der Tabelle zugeordnet. 

Die `@DynamoDBAttribute`-Anmerkung ist optional, wenn der Name des DynamoDB-Attributs dem Namen der in der Klasse angegebenen Eigenschaft entspricht. Wenn sich die Namen unterscheiden, verwenden Sie diese Anmerkung mit dem Parameter `attributeName`, um anzugeben, mit welchem DynamoDB-Attribut diese Eigenschaft übereinstimmt. 

Im vorangegangenen Beispiel wird jeder Eigenschaft die Annotation `@DynamoDBAttribute` hinzugefügt, um sicherzustellen, dass Eigenschaftsnamen genau den Tabellen entsprechen, die in einem vorherigen Schritt erstellt wurden und um die Attributnamen, die in anderen Codebeispielen in diesem Handbuch verwendet werden, einzuhalten. 

Ihre Klassendefinition kann Eigenschaften besitzen, die keinen Attributen in der Tabelle zugeordnet sind. Sie erkennen diese Eigenschaften, indem Sie die `@DynamoDBIgnore`-Anmerkung hinzufügen. Im vorangegangenen Beispiel ist die `SomeProp`-Eigenschaft mit der `@DynamoDBIgnore`-Anmerkung gekennzeichnet. Wenn Sie eine `CatalogItem`-Instance in die Tabelle hochladen, enthält Ihre `DynamoDBMapper`-Instance die Eigenschaft `SomeProp` nicht. Darüber hinaus gibt der Mapper dieses Attribut nicht zurück, wenn Sie ein Element aus der Tabelle abrufen. 

Nachdem Sie die Mappingklasse definierthaben, können Sie `DynamoDBMapper`-Methoden verwenden, um eine Instance dieser Klasse zu einem entsprechenden Element in der Tabelle `Catalog` zu schreiben. Das folgende Codebeispiel zeigt diese Technik.

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

Im folgenden Codebeispiel wird gezeigt, wie Sie das Element abrufen und auf einige seiner Attribute zugreifen.

```
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` ermöglicht ein intuitives und natürliches Arbeiten mit DynamoDB-Daten in Java. Er bietet auch verschiedene integrierte Funktionen wie optimistische Sperre, ACID-Transaktionen, automatisch generierte Partitions- und Sortierschlüsselwerte sowie Objektversionierung.

# Dynamo-Klasse DBMapper
<a name="DynamoDBMapper.Methods"></a>



Die Klasse A`DynamoDBMapper` ist der Eintrittspunkt für Amazon DynamoDB. Sie stellt Zugriff auf einen DynamoDB-Endpunkt bereit und ermöglicht Ihnen, auf Ihre Daten in verschiedenen Tabellen zuzugreifen. Sie ermöglicht Ihnen auch die Ausführung verschiedener Create-, Read-, Update-, und Delete-Operationen (CRUD) für Elemente sowie das Ausführen von Abfragen und Scans auf Tabellen. Diese Klasse bietet die folgenden Methoden für die Arbeit mit DynamoDB.

*Die entsprechende Javadoc-Dokumentation finden Sie unter [Dynamo DBMapper](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) in der API-Referenz.AWS SDK für Java *

**Topics**
+ [

## save
](#DynamoDBMapper.Methods.save)
+ [

## load
](#DynamoDBMapper.Methods.load)
+ [

## delete
](#DynamoDBMapper.Methods.delete)
+ [

## query
](#DynamoDBMapper.Methods.query)
+ [

## queryPage
](#DynamoDBMapper.Methods.queryPage)
+ [

## scan
](#DynamoDBMapper.Methods.scan)
+ [

## scanPage
](#DynamoDBMapper.Methods.scanPage)
+ [

## parallelScan
](#DynamoDBMapper.Methods.parallelScan)
+ [

## batchSave
](#DynamoDBMapper.Methods.batchSave)
+ [

## batchLoad
](#DynamoDBMapper.Methods.batchLoad)
+ [

## batchDelete
](#DynamoDBMapper.Methods.batchDelete)
+ [

## batchWrite
](#DynamoDBMapper.Methods.batchWrite)
+ [

## transactionWrite
](#DynamoDBMapper.Methods.transactionWrite)
+ [

## transactionLoad
](#DynamoDBMapper.Methods.transactionLoad)
+ [

## count
](#DynamoDBMapper.Methods.count)
+ [

## generateCreateTableAnfrage
](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [

## createS3Link
](#DynamoDBMapper.Methods.createS3Link)
+ [

## GetS3 ClientCache
](#DynamoDBMapper.Methods.getS3ClientCache)

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

Speichert das angegebene Objekt in der Tabelle. Das Objekt, das Sie speichern möchten, ist der einzige erforderliche Parameter für diese Methode. Sie können optionale Konfigurationsparameter mithilfe des `DynamoDBMapperConfig`-Objekts bereitstellen. 

Wenn ein Element mit demselben Primärschlüssel nicht vorhanden ist, erstellt diese Methode ein neues Element in der Tabelle. Wenn ein Element mit demselben Primärschlüssel vorhanden ist, aktualisiert sie das vorhandene Element. Wenn der Partitions- und Sortierschlüssel den Typ String haben und mit `@DynamoDBAutoGeneratedKey` angemerkt sind, erhalten sie einen Random Universally Unique Identifier (UUID), wenn sie nicht initialisiert werden. Versionsfelder, die mit `@DynamoDBVersionAttribute` angemerkt sind, werden um eins erhöht. Wenn ein Versionsfeld aktualisiert oder ein Schlüssel generiert wird, wird das übergebene Objekt als Folge der Operation aktualisiert. 

Standardmäßig werden nur Attribute aktualisiert, die Eigenschaften der zugewiesenen Klasse entsprechen. Zusätzlich für ein Element vorhandene Attribute sind nicht betroffen. Wenn Sie jedoch `SaveBehavior.CLOBBER` angeben, können Sie die vollständige Überschreibung des Elements erzwingen.

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

Wenn Versioning aktiviert ist, müssen die client- und serverseitigen Elementversionen übereinstimmen. Jedoch muss die Version nicht übereinstimmen, wenn die Option `SaveBehavior.CLOBBER` verwendet wird. Weitere Informationen über das Versioning finden Sie unter [DynamoDB und optimistische Sperren mit Versionsnummer](DynamoDBMapper.OptimisticLocking.md).

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

Ruft ein Element aus einer Tabelle ab. Sie müssen den Primärschlüssel des Elements bereitstellen, das Sie abrufen möchten. Sie können optionale Konfigurationsparameter mithilfe des `DynamoDBMapperConfig`-Objekts bereitstellen. Beispielsweise können Sie optional Strongly Consistent-Lesevorgänge anfordern, um sicherzustellen, dass diese Methode ausschließlich die neuesten Elementwerte, wie in der folgenden Java-Anweisung dargestellt, bereitstellt. 

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

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

Standardmäßig gibt DynamoDB das Element zurück, das über Eventually-Consistent-Werte verfügt. Weitere Informationen über das Eventual-Consistency-Modell von DynamoDB finden Sie unter [DynamoDB-Lesekonsistenz](HowItWorks.ReadConsistency.md).

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

Löscht ein Element aus der Tabelle. Sie müssen eine Objekt-Instance aus der zugeordneten Klasse übergeben. 

Wenn Versioning aktiviert ist, müssen die client- und serverseitigen Elementversionen übereinstimmen. Jedoch muss die Version nicht übereinstimmen, wenn die Option `SaveBehavior.CLOBBER` verwendet wird. Weitere Informationen zum Versioning finden Sie unter [DynamoDB und optimistische Sperren mit Versionsnummer](DynamoDBMapper.OptimisticLocking.md). 

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

Fragt eine Tabelle oder einen sekundären Index ab.

Angenommen, Sie verfügen über die Tabelle `Reply`, die Antworten für Forum-Threads speichert. Jedes Thread-Thema kann null oder mehr Antworten enthalten. Der Primärschlüssel der Tabelle `Reply` besteht aus den Feldern `Id` und `ReplyDateTime`, wobei `Id` der Partitionsschlüssel und `ReplyDateTime` der Sortierschlüssel des Primärschlüssels ist.

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

Angenommen, Sie haben eine Mapping zwischen der Klasse `Reply` und der entsprechenden Tabelle `Reply` in DynamoDB erstellt. Der folgende Java-Code verwendet `DynamoDBMapper`, um alle Antworten der letzten zwei Wochen zu einem bestimmten Thread-Thema zu finden.

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

Die Abfrage gibt eine Sammlung von `Reply`-Objekten zurück. 

Die `query`-Methode gibt standardmäßig eine "lazy-loaded"-Sammlung zurück. Sie gibt anfänglich ausschließlich eine Ergebnisseite zurück und führt dann bei Bedarf einen Dienstaufruf für die nächste Seite durch. Um alle übereinstimmenden Elemente zu erhalten, müssen Sie die Sammlung `latestReplies` durchlaufen. 

Beachten Sie, dass beim Aufrufen der `size()`-Methode für die Sammlung jedes Ergebnis geladen wird, um eine genaue Zählung zu liefern. Dies kann dazu führen, dass viel bereitgestellter Durchsatz verbraucht wird, und bei einer sehr großen Tabelle könnte sogar der gesamte Speicher in Ihrer JVM ausgeschöpft werden.

Für eine Indexabfrage müssen Sie zuerst den Index als eine Mapper-Klasse modellieren. *Angenommen, die `Reply` Tabelle hat einen globalen sekundären Index namens -Message-Index. PostedBy* Der Partitionsschlüssel für diesen Index ist `PostedBy` und der Sortierschlüssel ist `Message`. Die Klassendefinition für ein Element im Index würde wie folgt aussehen.

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

Die Anmerkung `@DynamoDBTable` gibt an, dass dieser Index mit der Tabelle `Reply` verknüpft ist. Die `@DynamoDBIndexHashKey` Anmerkung bezeichnet den Partitionsschlüssel (*PostedBy*) des Indexes und `@DynamoDBIndexRangeKey` den Sortierschlüssel (*Message*) des Indexes.

Sie können jetzt `DynamoDBMapper` nutzen, um den Index abzufragen, der eine Teilmenge der Nachrichten, die von einem bestimmten Benutzer gepostet wurden, abruft. Sie müssen den Indexnamen nicht angeben, wenn Sie keine widersprüchlichen Zuordnungen zwischen Tabellen und Indizes haben und die Zuordnungen bereits im Mapper vorgenommen wurden. Der Mapper leitet anhand des Primärschlüssels und des Sortierschlüssels ab. Der folgende Code fragt den globalen sekundären Index ab. Da globale sekundäre Indizes Eventually Consistent-Lesevorgänge, jedoch keine Strongly Consistent-Lesevorgänge unterstützen, müssen Sie `withConsistentRead(false)` angeben.

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

Die Abfrage gibt eine Sammlung von `PostedByMessage`-Objekten zurück.

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

Fragt eine Tabelle oder einen sekundären Index ab und gibt eine einzelne Seite der übereinstimmenden Ergebnisse zurück. Ebenso wie bei der `query`-Methode, müssen Sie einen Partitions-Schlüsselwert und einen Abfragefilter angeben, der auf das Sortierschlüsselattribut angewendet wird. `queryPage` gibt jedoch ausschließlich die erste „Seite“ der Daten zurück, d. h. Menge von Daten, die in 1 MB passt. 

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

Scannt eine gesamte Tabelle oder einen sekundären Index. Sie können optional einen `FilterExpression` angeben, um den Ergebnissatz zu filtern.

Angenommen, Sie verfügen über die Tabelle `Reply`, die Antworten für Forum-Threads speichert. Jedes Thread-Thema kann null oder mehr Antworten enthalten. Der Primärschlüssel der Tabelle `Reply` besteht aus den Feldern `Id` und `ReplyDateTime`, wobei `Id` der Partitionsschlüssel und `ReplyDateTime` der Sortierschlüssel des Primärschlüssels ist.

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

Wenn Sie der Tabelle `Reply` eine Java-Klasse zugewiesen haben, können Sie `DynamoDBMapper` verwenden, um die Tabelle zu scannen. Der folgende Java-Code scannt beispielsweise die gesamte Tabelle `Reply` und gibt nur die Antworten für ein bestimmtes Jahr zurück.

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

Die `scan`-Methode gibt standardmäßig eine "lazy-loaded"-Sammlung zurück. Sie gibt anfänglich ausschließlich eine Ergebnisseite zurück und führt dann bei Bedarf einen Dienstaufruf für die nächste Seite durch. Um alle übereinstimmenden Elemente zu erhalten, müssen Sie die Sammlung `replies` durchlaufen.

Beachten Sie, dass beim Aufrufen der `size()`-Methode für die Sammlung jedes Ergebnis geladen wird, um eine genaue Zählung zu liefern. Dies kann dazu führen, dass viel bereitgestellter Durchsatz verbraucht wird, und bei einer sehr großen Tabelle könnte sogar der gesamte Speicher in Ihrer JVM ausgeschöpft werden.

Um einen Index zu scannen, müssen Sie zuerst den Index als eine Mapper-Klasse modellieren. Angenommen, die `Reply`-Tabelle hat einen globalen sekundären Index namens `PostedBy-Message-Index`. Der Partitionsschlüssel für diesen Index ist `PostedBy` und der Sortierschlüssel ist `Message`. Im Abschnitt [query](#DynamoDBMapper.Methods.query) wird eine Mapper-Klasse für diesen Index gezeigt. Sie verwendet die Anmerkungen `@DynamoDBIndexHashKey` und `@DynamoDBIndexRangeKey`, um den Partitions- und Sortierschlüssel des Index anzugeben.

Im folgenden Codebeispiel wird `PostedBy-Message-Index` gescannt. Er verwendet keinen Scan-Filter, sodass alle Elemente im Index an Sie zurückgegeben werden.

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

Scannt eine Tabelle oder einen sekundären Index und gibt eine einzelne Seite der übereinstimmenden Ergebnisse zurück. Ebenso wie bei der `scan`-Methode, können Sie optional einen `FilterExpression` festlegen, um den Ergebnissatz zu filtern. `scanPage` gibt jedoch nur die erste „Seite“ der Daten zurück, d. h. Menge von Daten, die in 1 MB passt.

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

Führt einen parallelen Scan einer gesamten Tabelle oder einem sekundären Index durch. Sie geben eine Reihe von logischen Segmente für die Tabelle zusammen mit einem Scan-Ausdruck an, um Ergebnisse zu filtern. Der `parallelScan` teilt die Scan-Aufgabe unter mehreren Benutzern auf, einer für jedes logische Segment; die Benutzer verarbeiten die Daten parallel und geben die Ergebnisse zurück.

Im folgenden Java-Codebeispiel wird ein paralleler Scan der Tabelle `Product` ausgeführt.

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

Speichert Objekte in eine oder mehrere Tabellen mithilfe eines Aufrufs oder mehrerer Aufrufe der Methode `AmazonDynamoDB.batchWriteItem`. Diese Methode bietet keine Transaktionsgarantien.

Der folgende Java-Code speichert zwei Elemente (Bücher) in der Tabelle `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>

Ruft mehrere Elemente aus einer oder mehreren Tabellen anhand ihrer Primärschlüssel ab.

Der folgende Java-Code ruft zwei Elemente aus zwei verschiedenen Tabellen ab.

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

Löscht Objekte aus einer oder mehreren Tabellen mithilfe einer oder mehrerer Aufrufe der `AmazonDynamoDB.batchWriteItem`-Methode. Diese Methode bietet keine Transaktionsgarantien. 

Der folgende Java-Code löscht zwei Elemente (Bücher) aus der Tabelle `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>

Speichert Objekte in und löscht Objekte aus einer oder mehreren Tabellen mithilfe einer oder mehrerer Aufrufe der `AmazonDynamoDB.batchWriteItem`-Methode. Diese Methode bietet keine Transaktionsgarantien oder Versioning-Support (bedingte Ablege- oder Löschvorgänge).

Der folgende Java-Code schreibt ein neues Element in die Tabelle `Forum`, schreibt ein neues Element in die Tabelle `Thread` und löscht ein Element aus der Tabelle `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>

Speichert Objekte in und löscht Objekte aus mindestens einer Tabelle mithilfe eines Aufrufs der `AmazonDynamoDB.transactWriteItems`-Methode. 

[Eine Liste der transaktionsspezifischen Ausnahmen finden Sie unter Fehler. TransactWriteItems ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors) 

Weitere Informationen zu DynamoDB-Transaktionen und den bereitgestellten Garantien für Atomizität, Konsistenz, Isolation und Beständigkeit (Atomicity, Consistency, Isolation, Durability – ACID) finden Sie unter [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

**Anmerkung**  
 Diese Methode unterstützt Folgendes nicht:  
[DBMapperDynamo-Konfiguration. SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html).

Der folgende Java-Code schreibt transaktional jeweils ein neues Element in die Tabellen `Forum` und `Thread`.

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

Lädt Objekte aus mindestens einer Tabelle mithilfe eines Aufrufs der `AmazonDynamoDB.transactGetItems`-Methode. 

[Eine Liste der transaktionsspezifischen Ausnahmen finden Sie unter Fehler. TransactGetItems ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors) 

Weitere Informationen zu DynamoDB-Transaktionen und den bereitgestellten Garantien für Atomizität, Konsistenz, Isolation und Beständigkeit (Atomicity, Consistency, Isolation, Durability – ACID) finden Sie unter [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

Der folgende Java-Code lädt transaktional jeweils ein Element aus den Tabellen `Forum` und `Thread`.

```
Forum dynamodbForum = new Forum();
dynamodbForum.setName("DynamoDB Forum");
Thread dynamodbForumThread = new Thread();
dynamodbForumThread.setForumName("DynamoDB Forum");

TransactionLoadRequest transactionLoadRequest = new TransactionLoadRequest();
transactionLoadRequest.addLoad(dynamodbForum);
transactionLoadRequest.addLoad(dynamodbForumThread);
mapper.transactionLoad(transactionLoadRequest);
```

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

Bewertet den angegebenen Scanausdruck und gibt die Anzahl der übereinstimmenden Elemente zurück. Es werden keine Elementdaten zurückgegeben.

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

Analysiert eine POJO-Klasse, die eine DynamoDB-Tabelle repräsentiert und gibt eine `CreateTableRequest` für diese Tabelle zurück.

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

Erstellt einen Link zu einem Objekt in Amazon S3. Sie müssen einen Bucket-Namen und einen Schlüsselnamen angeben, welches das Objekt in dem Bucket eindeutig identifiziert.

Um `createS3Link` zu verwenden, muss die Mapper-Klasse die Methoden "Getter" und "Setter" definieren. Das folgende Codebeispiel veranschaulicht dies, indem der `CatalogItem` Klasse ein neues Attribut und neue getter/setter Methoden hinzugefügt werden.

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

...
}
```

Der folgende Java-Code definiert ein neues Element, das in die Tabelle `Product` geschrieben werden soll. Das Element enthält einen Link zu einemr Produktimage. Die Imagedaten werden auf Amazon S3 hochgeladen.

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

Die `S3Link`-Klasse bietet viele andere Methoden für die Bearbeitung von Objekten in Amazon S3. Weitere Informationen finden Sie unter [Javadocs for `S3Link`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html).

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

Gibt den zugrunde liegenden `S3ClientCache` für den Zugriff auf Amazon S3 zurück. Ein `S3ClientCache` ist ein intelligentes Mapping für `AmazonS3Client`-Objekte. Wenn Sie mehrere Kunden haben, `S3ClientCache` kann Ihnen an dabei helfen, die Kunden nach AWS Regionen zu organisieren und bei Bedarf neue Amazon S3 S3-Clients zu erstellen.

# Unterstützte Datentypen für Dynamo DBMapper für Java
<a name="DynamoDBMapper.DataTypes"></a>

Dieser Abschnitt beschreibt die unterstützten primitiven Java-Datentypen, Sammlungen und beliebige Datentypen in Amazon DynamoDB. 

Amazon DynamoDB unterstützt folgenden primitiven Java-Datentypen und primitiven Wrapperklassen. 
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (als [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) Millisekunden-Präzisionszeichenfolge, verschoben nach UTC)
+ `Calendar` (als [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) Millisekunden-Präzisionszeichenfolge, verschoben nach UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**Anmerkung**  
Weitere Informationen zu DynamoDB-Benennungsregeln und den verschiedenen unterstützten Datentypen finden sie unter [Unterstützte Datentypen und Benennungsregeln in Amazon DynamoDB](HowItWorks.NamingRulesDataTypes.md). 
Leere Binärwerte werden von Dynamo DBMapper unterstützt.
Leere Zeichenfolgenwerte werden unterstützt von AWS SDK for Java 2.x.  
In AWS SDK for Java 1.x DBMapper unterstützt Dynamo das Lesen leerer String-Attributwerte, schreibt jedoch keine leeren String-Attributwerte, da diese Attribute aus der Anforderung gelöscht werden.

DynamoDB unterstützt die Java-Sammlungstypen [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) und [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html). Die folgende Tabelle fasst zusammen, wie diese Java-Typen den DynamoDB-Typen zugewiesen werden.


****  

| Java-Typ | DynamoDB-Typ | 
| --- | --- | 
|  Alle Zahlentypen  |  `N` (Zahlentyp)  | 
|  Zeichenfolgen  |  `S` (Zeichenfolgetyp)   | 
|  Boolesch  |  `BOOL` (Boolescher Typ), 0 oder 1.  | 
|  ByteBuffer  |  `B` (Binärtyp)  | 
|  Date  |  `S` (Zeichenfolgetyp). Die Datumswerte werden als ISO-8601-formatierte Zeichenfolge gespeichert.  | 
| [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html)-Sammlungstypen |  `SS` (Zeichenfolgesatz)-Typ, `NS` (Zahlensatz)-Typ oder `BS` (Binärsatz)-Typ.  | 

 Die `DynamoDBTypeConverter`-Schnittstelle ermöglicht das Mapping eigener beliebiger Datentypen zu einem Datentyp, der von DynamoDB nativ unterstützt wird. Weitere Informationen finden Sie unter [Zuordnen willkürlicher Daten in DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md). 

# Java-Anmerkungen für DynamoDB
<a name="DynamoDBMapper.Annotations"></a>

Dieser Abschnitt beschreibt die Anmerkungen, die für das Mapping Ihrer Klassen und Eigenschaften zu Tabellen und Attributen in Amazon DynamoDB verfügbar sind.

Die entsprechende Javadoc-Dokumentation finden Sie unter [Annotation Types Summary](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html) in der [AWS SDK für Java API-Referenz](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

**Anmerkung**  
In den folgenden Anmerkungen sind ausschließlich `DynamoDBTable` und der `DynamoDBHashKey` erforderlich. 

**Topics**
+ [

## Dynamo DBAttribute
](#DynamoDBMapper.Annotations.DynamoDBAttribute)
+ [

## Dynamo DBAuto GeneratedKey
](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey)
+ [

## Dynamo DBAuto GeneratedTimestamp
](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp)
+ [

## Dynamo DBDocument
](#DynamoDBMapper.Annotations.DynamoDBDocument)
+ [

## Dynamo-Schlüssel DBHash
](#DynamoDBMapper.Annotations.DynamoDBHashKey)
+ [

## Dynamo DBIgnore
](#DynamoDBMapper.Annotations.DynamoDBIgnore)
+ [

## Dynamo DBIndex HashKey
](#DynamoDBMapper.Annotations.DynamoDBIndexHashKey)
+ [

## Dynamo DBIndex RangeKey
](#DynamoDBMapper.Annotations.DynamoDBIndexRangeKey)
+ [

## Dynamo-Schlüssel DBRange
](#DynamoDBMapper.Annotations.DynamoDBRangeKey)
+ [

## Dynamo DBTable
](#DynamoDBMapper.Annotations.DynamoDBTable)
+ [

## Dynamo wurde konvertiert DBType
](#DynamoDBMapper.Annotations.DynamoDBTypeConverted)
+ [

## Dynamo DBTyped
](#DynamoDBMapper.Annotations.DynamoDBTyped)
+ [

## Dynamo-Attribut DBVersion
](#DynamoDBMapper.Annotations.DynamoDBVersionAttribute)

## Dynamo DBAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBAttribute"></a>

Ordnet eine Eigenschaft einem Tabellenattribut zu. Standardmäßig wird jede Klasseneigenschaft einem Elementattribut mit demselben Namen zugeordnet. Wenn die Namen jedoch nicht identisch sind, können Sie diese Anmerkung verwenden, um dem Attribut eine Eigenschaft zuzuordnen. Im folgenden Java-Ausschnitt ordnet `DynamoDBAttribute` die `BookAuthors`-Eigenschaft dem `Authors`-Attributnamen in der Tabelle zu.

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

Der `DynamoDBMapper` verwendet `Authors` als Attributnamen bei der Speicherung des Objekts in die Tabelle. 

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

Kennzeichnet eine Partitions- oder Sortierschlüsseleigenschaft als automatisch generiert. `DynamoDBMapper` generiert beim Speichern dieser Attribute nach dem Zufallsprinzip eine [UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html). Ausschließlich Zeichenfolgeeigenschaften können als automatisch generierte Schlüssel markiert werden. 

Das folgende Beispiel zeigt die Verwendung von automatisch generierten Schlüsseln.

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

## Dynamo DBAuto GeneratedTimestamp
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp"></a>

Generiert automatisch einen Zeitstempel.

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

Optional kann die Strategie für die automatische Generierung durch Angabe eines Strategieattributs definiert werden. Der Standardwert ist `ALWAYS`.

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

Gibt an, dass eine Klasse als Amazon-DynamoDB-Dokument serialisiert werden kann.

Angenommen, Sie möchten ein JSON-Dokument einem DynamoDB-Attribut des Typs „Map“ zuweisen (`M`). Im folgenden Codebeispiel wird ein Element definiert, das ein verschachteltes Attribut (Bilder) des Typs „Map“ enthält.

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

     }
}
```

Anschließend könnten Sie ein neues `ProductCatalog`-Element mit `Pictures` speichern wie im folgenden Beispiel gezeigt.

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

Das resultierende `ProductCatalog`-Element würde wie folgt aussehen (im JSON-Format).

```
{
  "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"
  }
}
```

## Dynamo-Schlüssel DBHash
<a name="DynamoDBMapper.Annotations.DynamoDBHashKey"></a>

Ordnet eine Klasseneigenschaft dem Partitionsschlüssel der Tabelle zu. Die Eigenschaft muss ein skalarer Zeichenfolge-, Zahlen- oder Binärtyp sein. Die Eigenschaft darf kein Sammlungstyp sein. 

Angenommen, Sie besitzen eine Tabelle `ProductCatalog`, die `Id` als Primärschlüssel verwendet. Der folgende Java-Code definiert eine `CatalogItem`-Klasse und ordnet ihre Eigenschaft `Id` dem Primärschlüssel der Tabelle `ProductCatalog` mithilfe des Tags `@DynamoDBHashKey` zu.

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

## Dynamo DBIgnore
<a name="DynamoDBMapper.Annotations.DynamoDBIgnore"></a>

Zeigt der `DynamoDBMapper`-Instance an, dass die zugeordnete Eigenschaft ignoriert werden sollte. Beim Speichern der Daten in die Tabelle, speichert der `DynamoDBMapper` diese Eigenschaft nicht in die Tabelle.

 Wird auf die Getter-Methode oder das Klassenfeld für eine nicht modellierte Eigenschaft angewendet. Wenn die Anmerkung direkt auf das Klassenfeld angewendet wird, müssen die entsprechenden Getter- und Setter-Methoden in derselben Klasse deklariert werden. 

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

Ordnet eine Klasseneigenschaft dem Partitionsschlüssel eines globalen sekundären Index zu. Die Eigenschaft muss ein skalarer Zeichenfolge-, Zahlen- oder Binärtyp sein. Die Eigenschaft darf kein Sammlungstyp sein. 

Verwenden Sie diese Anmerkung, wenn Sie `Query` einen globalen sekundären Index brauchen. Sie müssen den Indexnamen angeben (`globalSecondaryIndexName`). Wenn sich der Name der Klasseneigenschaft vom Indexpartitionsschlüssel unterscheidet, müssen Sie auch den Namen dieses Indexattributs (`attributeName`).

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

Ordnet eine Klasseneigenschaft dem Sortierschlüssel eines globalen sekundären Index oder eines lokalen sekundären Index zu. Die Eigenschaft muss ein skalarer Zeichenfolge-, Zahlen- oder Binärtyp sein. Die Eigenschaft darf kein Sammlungstyp sein. 

Verwenden Sie diese Anmerkung, wenn Sie `Query` für einen lokalen sekundären Index oder einen globalen sekundären Index ausführen müssen und die Ergebnisse mithilfe des Index-Sortierschlüssels verfeinern möchten. Sie müssen den Indexnamen angeben (entweder `globalSecondaryIndexName` oder `localSecondaryIndexName`). Wenn der Name der Klasseneigenschaft sich von dem Indexsortierschlüssel unterscheidet, müssen Sie auch den Namen dieses Indexattributs (`attributeName`).

## Dynamo-Schlüssel DBRange
<a name="DynamoDBMapper.Annotations.DynamoDBRangeKey"></a>

Ordnet eine Klasseneigenschaft dem Sortierschlüssel der Tabelle zu. Die Eigenschaft muss ein skalarer Zeichenfolge-, Zahlen- oder Binärtyp sein. Sie darf kein Sammlungstyp sein. 

Wenn der Primärschlüssel zusammengesetzt ist (Partitionsschlüssel und Sortierschlüssel), können Sie diesen Tag verwenden, um Ihr Klassenfeld dem Sortierschlüssel zuzuordnen. Angenommen, Sie verfügen über eine Tabelle `Reply`, die Antworten für Forum-Threads speichert. Jeder Thread kann zahlreiche Antworten enthalten. Daher ist der Primärschlüssel dieser Tabelle sowohl die `ThreadId` als auch `ReplyDateTime`. Die `ThreadId` ist der Partitionsschlüssel und `ReplyDateTime` ist der Sortierschlüssel. 

Der folgende Java-Code definiert die Klasse `Reply` und ordnet sie der Tabelle `Reply` zu. Es werden die `@DynamoDBHashKey` und `@DynamoDBRangeKey`-Tags für die Identifizierung der Klasseneigenschaften, die dem Primärschlüssel zugeordnet werden, verwendet.

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

## Dynamo DBTable
<a name="DynamoDBMapper.Annotations.DynamoDBTable"></a>

Identifiziert die Zieltabelle in DynamoDB. Der folgende Java-Code definiert beispielsweise die Klasse `Developer` und ordnet sie der `People`-Tabelle in DynamoDB zu. 

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

Die `@DynamoDBTable`-Anmerkung kann geerbt werden. Jede neue Klasse, die von der Klasse `Developer` erbt, wird ebenfalls der Tabelle `People` zugeordnet. Angenommen, Sie erstellen beispielsweise eine `Lead` -Klasse, die von der `Developer`-Klasse erbt. Da Sie die Klasse `Developer` der Tabelle `People` zugeordnet haben, werden die Objekte der Klasse `Lead` ebenfalls in dieser Tabelle gespeichert.

Die `@DynamoDBTable` kann auch außer Kraft gesetzt werden. Jede neue Klasse, die standardmäßig von der Klasse `Developer` erbt, wird dieser Tabelle `People` zugeordnet. Sie können jedoch dieses Standardmapping außer Kraft setzen. Wenn Sie beispielsweise eine Klasse erstellen, die von der Klasse `Developer` erbt, können Sie sie ausdrücklich einer anderen Tabelle zuweisen, indem Sie die Anmerkung `@DynamoDBTable` hinzufügen wie im folgenden Java-Codebeispiel gezeigt.

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

## Dynamo wurde konvertiert DBType
<a name="DynamoDBMapper.Annotations.DynamoDBTypeConverted"></a>

Eine Anmerkung, die angibt, dass eine Eigenschaft einen benutzerdefinierten Typkonverter verwendet. Kann in einer benutzerdefinierten Anmerkung mit Anmerkungen versehen werden, um dem `DynamoDBTypeConverter` zusätzliche Eigenschaften zu übergeben. 

 Die `DynamoDBTypeConverter`-Schnittstelle ermöglicht das Mapping eigener beliebiger Datentypen zu einem Datentyp, der von DynamoDB nativ unterstützt wird. Weitere Informationen finden Sie unter [Zuordnen willkürlicher Daten in DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md).

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

Eine Anmerkung, mit der die standardmäßige Attributtypbindung überschrieben wird. Standard-Typen erfordern die Anmerkung nicht, wenn Sie die Standard-Attributbindung für diesen Typ anwenden. 

## Dynamo-Attribut DBVersion
<a name="DynamoDBMapper.Annotations.DynamoDBVersionAttribute"></a>

Identifiziert eine Klasseneigenschaft für das Speichern einer Versionsnummer der optimistischen Sperre. `DynamoDBMapper` weist dieser Eigenschaft eine Versionsnummer zu, wenn ein neues Element gespeichert wird, und erhöht sie bei jeder Aktualisierung des Elements. Ausschließlich Zahlentypen und skalare Typen werden unterstützt. Weitere Informationen zu Datentypen finden Sie unter [Datentypen](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes). Weitere Informationen über das Versioning finden Sie unter [DynamoDB und optimistische Sperren mit Versionsnummer](DynamoDBMapper.OptimisticLocking.md).

# Optionale Konfigurationseinstellungen für Dynamo DBMapper
<a name="DynamoDBMapper.OptionalConfig"></a>

Wenn Sie eine Instance von `DynamoDBMapper` erstellen, verfügt sie über bestimmte Standardverhaltensweisen. Sie können diese Standards überschreiben, indem Sie die `DynamoDBMapperConfig`-Klasse verwenden. 

Der folgende Codeausschnitt erstellt einen `DynamoDBMapper` mit benutzerdefinierten Einstellungen:

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

Weitere Informationen finden Sie unter [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) in der [AWS SDK für Java API-Referenz.](https://docs.aws.amazon.com/sdk-for-java/latest/reference/)

Sie können folgende Argumente für die Instance von `DynamoDBMapperConfig` verwenden:
+ Einen `DynamoDBMapperConfig.ConsistentReads`-Aufzählungswert:
  + `EVENTUAL` – die Mapper-Instance verwendet eine Eventually Consistent-Anforderung.
  + `CONSISTENT` – die Mapper-Instance verwendet eine Strongly-Consistent-Leseanforderung. Sie können diese optionale Einstellung mit der `load`-, `query`- oder `scan`-Operation verwenden. Strongly-Consistent-Lesevorgänge haben Auswirkungen auf Leistung und Fakturierung. Weitere Informationen finden Sie auf der DynamoDB-[Produktdetailseite](https://aws.amazon.com/dynamodb).

  Wenn Sie keine Lesekonsistenzeinstellung für die Mapper-Instance festgelegt haben, ist der Standard `EVENTUAL`.
**Anmerkung**  
Dieser Wert wird bei den `batch load` Operationen`query`, `querypage``load`, und von Dynamo DBMapper angewendet.
+ Ein `DynamoDBMapperConfig.PaginationLoadingStrategy`-Aufzählungswert – kontrolliert wie die Mapper-Instance eine paginierte Datenliste, z. B. ein `query`- oder `scan`-Ergebnis, verarbeitet:
  + `LAZY_LOADING` – Die Mapper-Instance lädt wenn möglich Daten und belässt alle geladenen Ergebnisse im Speicher.
  + `EAGER_LOADING` – die Mapper-Instance lädt die Daten, sobald die Liste initialisiert wird.
  + `ITERATION_ONLY` – Sie können nur einen Iterator nutzen, um aus der Liste zu lesen. Während der Iteration wird die Liste alle vorherigen Ergebnisse löschen, bevor die nächste Seite geladen wird, sodass die Liste höchstens eine Seite der geladenen Ergebnisse im Speicher hält. Dies bedeutet auch, dass die Liste nur einmal iteriert werden kann. Diese Strategie wird bei der Bearbeitung von großen Elementen empfohlen, um den Speichermehraufwand zu reduzieren.

  Wenn Sie keine Paginierungsladestrategie für die Mapper-Instance angeben, ist der Standard `LAZY_LOADING`.
+ Ein `DynamoDBMapperConfig.SaveBehavior`-Aufzählungswert – gibt an wie die Mapper-Instance während Speichervorgängen mit den Attributen umgehen sollte:
  + `UPDATE` – während eines Speichervorgangs werden alle modellierten Attribute aktualisiert, nicht modellierte Attribute bleiben davon unberührt. Primitive Zahlentypen (Byte, int, long) werden auf 0 gesetzt. Objekttypen werden auf Null gesetzt. 
  + `CLOBBER` – löscht und ersetzt alle Attribute während eines Speichervorgangs, nicht modellierte Attribute eingeschlossen. Dies erfolgt durch das Löschen des Elements und seiner Neuerstellung. Versionierte Feldeinschränkungen werden ebenfalls ignoriert.

   Wenn Sie die Speicherverhaltensweise der Mapper-Instance nicht festlegen, ist der Standard `UPDATE`.
**Anmerkung**  
DBMapper Dynamo-Transaktionsoperationen unterstützen keine Aufzählung. `DynamoDBMapperConfig.SaveBehavior` 
+ Ein `DynamoDBMapperConfig.TableNameOverride`-Objekt – weist die Mapper-Instance an, den Tabellennamen, der durch die `DynamoDBTable`-Anmerkung einer Klasse festgelegt wurde, zu ignorieren und stattdessen einen anderen Tabellennamen zu verwenden, den Sie festlegen. Dies ist beim Partitionieren der Daten in mehrere Tabellen zur Laufzeit nützlich. 

Sie können das Standardkonfigurationsobjekt für `DynamoDBMapper` pro Operation falls nötig überschreiben.

# DynamoDB und optimistische Sperren mit Versionsnummer
<a name="DynamoDBMapper.OptimisticLocking"></a>

*Optimistische Sperren* stellen eine Strategie dar, die sicherstellt, dass das clientseitige Element, das Sie aktualisieren (oder löschen), das gleiche Element wie in Amazon DynamoDB ist. Wenn Sie diese Strategie verwenden, werden Ihre Datenbankschreibvorgänge vor dem Überschreiben durch Schreibvorgänge anderer Benutzer geschützt und umgekehrt.

Mit der optimistischen Sperre verfügt jedes Element über ein Attribut, das als Versionsnummer fungiert. Wenn Sie ein Element in einer Tabelle abrufen, zeichnet die Anwendung die Versionsnummer dieses Elements auf. Sie können das Element aktualisieren, jedoch nur, wenn die serverseitige Versionsnummer nicht geändert wurde. Wenn Versionen nicht übereinstimmen, bedeutet das, dass ein anderer Benutzer das Element vor Ihnen geändert hat. Die Aktualisierung schlägt fehlt, da Sie eine veraltete Version des Elements besitzen. Wenn dies der Fall ist, wiederholen Sie den Vorgang, indem Sie das Element abrufen und anschließend versuchen, es zu aktualisieren. Die optimistische Sperre hindert Sie daran, versehentlich Änderungen anderer Benutzer zu überschreiben. Sie hindert auch andere Benutzer daran, versehentlich Ihre Änderungen zu überschreiben.

Sie können zwar Ihre eigene optimistische Sperrstrategie implementieren, stellt jedoch die AWS SDK für Java Anmerkung bereit. `@DynamoDBVersionAttribute` In der Mappingklasse für Ihre Tabelle legen Sie eine Eigenschaft zum Speichern der Versionsnummer fest und kennzeichnen diese mithilfe dieser Anmerkung. Wenn Sie ein Objekt speichern, wird das entsprechende Element in der DynamoDB-Tabelle über ein Attribut verfügen, das die Versionsnummer speichert. Der `DynamoDBMapper` weist eine Versionsnummer zu, wenn Sie das Element zum ersten Mal speichern und er erhöht automatisch die Versionsnummer bei jeder Aktualisierung des Elements. Die Aktualisierungs- oder Löschanforderungen sind nur erfolgreich, wenn die clientseitige Objektversion der entsprechenden Versionsnummer des Elements in der DynamoDB-Tabelle entspricht.

 `ConditionalCheckFailedException` wird aufgeworfen, wenn: 
+  Sie eine optimistische Sperre mit `@DynamoDBVersionAttribute` verwenden und sich der Versionswert auf dem Server von dem Wert auf der Client-Seite unterscheidet. 
+  Sie Ihre eigenen bedingten Einschränkungen beim Speichern der Daten angeben, indem Sie `DynamoDBMapper` mit `DynamoDBSaveExpression` verwenden, und diese Einschränkungen fehlgeschlagen sind. 

**Anmerkung**  
Globale Tabellen in DynamoDB verwenden bei gleichzeitigen Updates einen Mechanismus, bei dem der letzte Schreibvorgang gültig ist. Bei Verwendung von globalen Tabellen ist immer der letzte Schreibvorgang gültig. In diesem Fall funktioniert das Sperren daher nicht wie erwartet.
Transaktionale Schreibvorgänge von `DynamoDBMapper` unterstützen keine `@DynamoDBVersionAttribute`-Anmerkung und -Bedingungsausdrücke auf demselben Objekt. Wenn ein Objekt innerhalb eines transaktionalen Schreibvorgangs mit einer Anmerkung versehen ist `@DynamoDBVersionAttribute` und auch über einen Bedingungsausdruck verfügt, SdkClientException wird ein ausgelöst.

Der folgende Java-Code definiert beispielsweise die Klasse `CatalogItem`, die über mehrere Eigenschaften verfügt. Die `Version`-Eigenschaft wird mit der `@DynamoDBVersionAttribute`-Anmerkung gekennzeichnet.

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

Sie können die `@DynamoDBVersionAttribute`-Anmerkung auf löschbare Typen anwenden, die durch primitive Wrapper-Klassen bereitgestellt wurden, die wiederum einen löschbaren Typ wie `Long` und `Integer` bereitstellen. 

Die optimistische Sperre hat folgende Auswirkungen auf diese `DynamoDBMapper`-Methoden:
+ `save` – für ein neues Element weist der `DynamoDBMapper` eine erste Versionsnummer 1 zu. Wenn Sie ein Element abrufen, eine oder mehrere seiner Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, ist die Speicheroperation nur dann erfolgreich, wenn die clientseitige und die serverseitige Versionsnummer übereinstimmen. Der `DynamoDBMapper` erhöht die Versionsnummer automatisch.
+ `delete` – die `delete`-Methode übernimmt ein Objekt als einen Parameter und der `DynamoDBMapper` führt einen Versionscheck durch, bevor er das Element löscht. Der Versionscheck kann deaktiviert werden, wenn `DynamoDBMapperConfig.SaveBehavior.CLOBBER` in der Anforderung angegeben wird.

  Die interne Implementierung der optimistischen Sperre im `DynamoDBMapper` nutzt die von DynamoDB bereitgestellte Unterstützung für bedingtes Aktualisieren und bedingtes Löschen. 
+ `transactionWrite` —
  + `Put` – für ein neues Element weist der `DynamoDBMapper` eine erste Versionsnummer 1 zu. Wenn Sie ein Element abrufen, eine oder mehrere seiner Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, ist die Put-Operation nur dann erfolgreich, wenn die clientseitige und die serverseitige Versionsnummer übereinstimmen. Der `DynamoDBMapper` erhöht die Versionsnummer automatisch.
  + `Update` – für ein neues Element weist der `DynamoDBMapper` eine erste Versionsnummer 1 zu. Wenn Sie ein Element abrufen, eine oder mehrere seiner Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, ist die Update-Operation nur dann erfolgreich, wenn die clientseitige und die serverseitige Versionsnummer übereinstimmen. Der `DynamoDBMapper` erhöht die Versionsnummer automatisch.
  + `Delete` – `DynamoDBMapper` führt eine Versionsprüfung durch, bevor er das Element löscht. Die Lösch-Operation ist nur dann erfolgreich, wenn die Versionsnummern auf Clientseite und auf Serverseite übereinstimmen.
  + `ConditionCheck` – die `@DynamoDBVersionAttribute`-Anmerkung wird für `ConditionCheck`-Operationen nicht unterstützt. Ein SdkClientException wird ausgelöst, wenn ein `ConditionCheck` Element mit einer Anmerkung versehen ist. `@DynamoDBVersionAttribute` 

## Deaktivieren der optimistischen Sperre
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

Um die optimistische Sperre zu deaktivieren, können Sie den `DynamoDBMapperConfig.SaveBehavior`-Aufzählungswert von `UPDATE` auf `CLOBBER` ändern. Sie können dies tun, indem Sie eine `DynamoDBMapperConfig`-Instance erstellen, die eine Versionsüberprüfung überspringt und diese Instance für alle Anforderungen verwendet. Weitere Informationen zu `DynamoDBMapperConfig.SaveBehavior` und anderen optionalen `DynamoDBMapper`-Parametern finden Sie unter [Optionale Konfigurationseinstellungen für Dynamo DBMapper](DynamoDBMapper.OptionalConfig.md). 

Sie können auch ein Sperrverhalten ausschließlich für eine bestimmte Operation festlegen. Der folgende Java-Ausschnitt verwendet beispielsweise den `DynamoDBMapper`, um ein Katalogelement zu speichern. Er legt ein `DynamoDBMapperConfig.SaveBehavior` fest, indem er optionale `DynamoDBMapperConfig`-Parameter der `save`-Methode hinzufügt. 

**Anmerkung**  
Die TransactionWrite-Methode unterstützt Dynamo DBMapper Config nicht. SaveBehaviorKonfiguration. Das Deaktivieren der optimistischen Sperre für transactionWrite wird nicht unterstützt.

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

# Zuordnen willkürlicher Daten in DynamoDB
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

Zusätzlich zu den unterstützten Java-Typen (siehe [Unterstützte Datentypen für Dynamo DBMapper für Java](DynamoDBMapper.DataTypes.md)) können Sie Typen in der Anwendungen verwenden, für die es keine direkte Mapping zu Amazon-DynamoDB-Typen gibt. Um diese Typen zuzuweisen, müssen Sie eine Implementierung bereitstellen, die Ihren komplexen Typ in einen von DynamoDB unterstützten Typ und umgekehrt konvertiert, und die komplexe Typzugriffsmethode unter Verwendung der Anmerkung `@DynamoDBTypeConverted` kommentieren. Der Konverter-Code wandelt Daten um, wenn Objekte gespeichert oder geladen werden. Er wird außerdem für alle Operationen verwendet, die komplexe Typen nutzen. Beachten Sie, dass beim Vergleichen von Daten während der Abfrage- und Scan-Operationen, die Vergleiche für die in DynamoDB gespeicherten Daten gemacht werden.

Betrachten Sie zum Beispiel die folgende `CatalogItem`-Klasse, die die Eigenschaft `Dimension` mit dem Typ `DimensionType` definiert. Diese Eigenschaft speichert die Elementabmessungen wie Höhe, Breite und Dicke. Gehen Sie davon aus, dass Sie sich dazu entscheiden, diese Elementmaße als Zeichenfolge (z. B. 8,5 x 11 x ,05) in DynamoDB zu speichern. Das folgende Beispiel stellt einen Konverter-Code bereit, der das `DimensionType`-Objekt in eine Zeichenfolge und eine Zeichenfolge in einen `DimensionType` konvertiert.



**Anmerkung**  
In diesem Codebeispiel wird davon ausgegangen, dass Sie bereits Daten für Ihr Konto in DynamoDB geladen haben, indem Sie die Anweisungen im Abschnitt [Erstellen von Tabellen und Laden von Daten für Codebeispiele in DynamoDB](SampleData.md) befolgen.  
 step-by-stepAnweisungen zur Ausführung des folgenden Beispiels finden Sie unter. [Java-Codebeispiele](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;
        }
    }
}
```

# Beispiele für DynamoDBMapper
<a name="DynamoDBMapper.Examples"></a>

Das AWS-SDK für Java stellt eine `DynamoDBMapper`-Klasse bereit, mit der Sie Ihre clientseitigen Klassen zu Amazon-DynamoDB-Tabellen zuweisen können. Um `DynamoDBMapper` zu verwenden, definieren Sie die Beziehung zwischen Elementen in einer DynamoDB-Tabelle und ihren entsprechenden Objekt-Instances im Code. Die `DynamoDBMapper`-Klasse ermöglicht Ihnen auch die Ausführung verschiedener Create-, Read-, Update-, und Delete-Operationen (CRUD) für Elemente sowie das Ausführen von Abfragen und Scans für Tabellen.

Weitere Informationen für die Verwendung von `DynamoDBMapper` finden Sie unter [DynamoDB-Beispiele für die Verwendung des AWS-SDK für Java](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html) im *AWS-SDK für Java 1.x-Entwicklerhandbuch*. 

# Java 2.x: Erweiterter DynamoDB-Client
<a name="DynamoDBEnhanced"></a>

Der erweiterte DynamoDB-Client ist eine Bibliothek auf hoher Ebene, die Teil von AWS SDK für Java Version 2 (v2) ist. Er bietet eine einfache Möglichkeit, clientseitige Klassen zu DynamoDB-Tabellen zuzuordnen. Sie definieren die Beziehungen zwischen Tabellen und ihren jeweiligen Modellklassen im Code. Nach der Definition dieser Beziehungen können Sie verschiedene Operationen zum Erstellen, Lesen, Aktualisieren oder Löschen (Create, Read, Update, Delete, CRUD) für Tabellen oder Elemente in DynamoDB auf intuitive Weise ausführen.

Weitere Informationen darüber, wie Sie den erweiterten Client mit DynamoDB verwenden können, finden Sie unter [Verwenden des erweiterten DynamoDB-Clients im AWS SDK für Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html). 

# Arbeiten dem .NET-Dokumentmodell in DynamoDB
<a name="DotNetSDKMidLevel"></a>

Das AWS SDK für .NET bietet Dokumentmodellklassen, die einige der Low-Level-Amazon-DynamoDB-Operationen zur weiteren Vereinfachung der Codierung umschließen. Die primären Klassen im Dokumentmodell sind `Table` und `Document`. Die `Table`-Klasse bietet Datenoperationsmethoden wie `PutItem`, `GetItem` und `DeleteItem`. Außerdem stellt sie auch die `Query`- und die `Scan`-Methode bereit. Die `Document`-Klasse steht für ein einzelnes Element in einer Tabelle.

Die zuvor genannten Dokumentmodellklassen sind in dem `Amazon.DynamoDBv2.DocumentModel`-Namespace verfügbar.

**Anmerkung**  
Sie können die Dokumentmodellklassen nicht zum Erstellen, Aktualisieren und Löschen von Tabellen nutzen. Das Dokumentmodell unterstützt jedoch die meisten allgemeinen Datenoperationen.

**Topics**
+ [

## Unterstützte Datentypen
](#MidLevelAPILimitations.SupportedTypes)

## Unterstützte Datentypen
<a name="MidLevelAPILimitations.SupportedTypes"></a>

Das Dokumentmodell unterstützt eine Reihe von primitiven .NET-Datentypen und Sammlungsdatentypen. Das Modell unterstützt die folgenden primitiven Datentypen. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

In der folgenden Tabelle ist das Mapping der vorhergehenden .NET-Typen zu den DynamoDB-Typen zusammengefasst.


****  

| .NET-primitiver Typ | DynamoDB-Typ | 
| --- | --- | 
|  Alle Zahlentypen  |  `N` (Zahlentyp)  | 
|  Alle Zeichenfolgetypen  |  `S` (Zeichenfolgetyp)   | 
|  MemoryStream, Byte []  |  `B` (Binärtyp)   | 
| bool | N (Zahlentyp) 0 repräsentiert False und 1 steht für True. | 
| DateTime | S (Zeichenfolgetyp). Die DateTime-Werte werden als ISO-8601-formatierte Zeichenfolgen gespeichert. | 
| Guid | S (Zeichenfolgetyp). | 
| Sammlungstypen (Liste, HashSet und Array) | BS-(Binärsatz)-Typ, SS-(Zeichenfolgesatz)-Typ und NS-(Zahlensatz)-Typ. | 

AWS SDK für .NET definiert Typen für das Mapping der booleschen, Null-, Listen- und Map-Typen von DynamoDB zur .NET-Dokumentmodell-API:
+ Verwenden Sie als booleschen Typ `DynamoDBBool`.
+ Verwenden Sie als den Null-Typ `DynamoDBNull`.
+ Verwenden Sie als Listentyp `DynamoDBList`.
+ Verwenden Sie als Map-Typ `Document`.

**Anmerkung**  
Leere Binärwerte werden unterstützt.
Das Lesen von leeren Zeichenfolgenwerten wird unterstützt. Leere Zeichenfolgen-Attributwerte werden beim Schreiben zu DynamoDB in Attributwerten vom Typ Zeichenfolgensatz unterstützt. Leere Zeichenfolgen-Attributwerte des Zeichenfolgentyps und leere Zeichenfolgenwerte innerhalb des Listen- oder Map-Typs werden aus Schreibanforderungen gelöscht.

# Arbeiten mit dem Object Persistence-Modell von .NET und DynamoDB
<a name="DotNetSDKHighLevel"></a>

Das AWS SDK für .NET bietet ein Objektpersistenzmodell, mit dem Sie Ihre clientseitigen Klassen Amazon DynamoDB-Tabellen zuordnen können. Die einzelnen Objekt-Instances werden anschließend einem Element in den entsprechenden Tabellen zugeordnet. Zum Speichern der clientseitigen Objekte in den Tabellen stellt das Object-Persistence-Modell die Klasse `DynamoDBContext` bereit, einen Eintrittspunkt für DynamoDB. Mit dieser Klasse verfügen Sie über eine Verbindung zu DynamoDB, können auf Tabellen zugreifen und verschiedene CRUD-Operationen sowie Abfragen ausführen.

Das Objektpersistenzmodell bietet eine Reihe von Attributen, um clientseitige Klassen Tabellen und Tabellenattributen zuzuordnen. properties/fields 

**Anmerkung**  
Das Object Persistence-Modell stellt keine API zum Erstellen, Aktualisieren oder Löschen von Tabellen bereit. Es stellt ausschließlich Datenoperationen bereit. Sie können nur die AWS SDK für .NET Low-Level-API verwenden, um Tabellen zu erstellen, zu aktualisieren und zu löschen.

Das folgende Beispiel zeigt, wie das Object Persistence-Modell funktioniert. Es wird mit der Tabelle `ProductCatalog` gestartet. Es besitzt `Id` als Primärschlüssel.

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

Angenommen, Sie besitzen die Klasse `Book` mit den Eigenschaften `Title`, `ISBN` und `Authors`. Sie können die Klasse `Book` der Tabelle `ProductCatalog` zuordnen, indem Sie die durch das Object Persistence-Modell definierten Attribute hinzufügen wie im folgenden C\$1-Codeausschnitt gezeigt.

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

Im vorherigen Beispiel ordnet das Attribut `DynamoDBTable` die Klasse `Book` der Tabelle `ProductCatalog` zu.

Das Object Persistence-Modell unterstützt die explizite und das Standardmapping zwischen Klasseneigenschaften und Tabellenattributen.
+ **Explizites Mapping – **Um eine Eigenschaft einem Primärschlüssel zuzuordnen, müssen Sie die `DynamoDBHashKey`- und `DynamoDBRangeKey`-Attribute des „Object-Persistence“-Modells verwenden. Außerdem gilt für andere als Primärschlüsselattribute, dass Sie das Mapping durch explizites Hinzufügen des Attributs `DynamoDBProperty` definieren müssen, wenn der Name einer Eigenschaft in Ihrer Klasse und des Tabellenattributs, dem Sie diese zuordnen möchten, nicht identisch sind.

  Im vorherigen Beispiel werden die Eigenschaft `Id` dem Primärschlüssel mit dem gleichen Namen und die Eigenschaft `BookAuthors` dem Attribut `Authors` in der Tabelle `ProductCatalog` zugeordnet.
+ **Standard-Mapping – **Standardmäßig ordnet das „Object Persistence“-Modell die Klasseneigenschaften den Attributen mit identischem Namen in der Tabelle zu.

  Im vorherigen Beispiel werden die Eigenschaften `Title` und `ISBN` den Attributen mit den gleichen Namen in der Tabelle `ProductCatalog` zugeordnet.

Sie müssen nicht jede einzelne Klasseneigenschaft zuordnen. Sie erkennen diese Eigenschaften, indem Sie das `DynamoDBIgnore`-Attribut hinzufügen. Wenn Sie eine `Book`-Instance in die Tabelle hochladen, enthält der `DynamoDBContext` nicht die `CoverPage`-Eigenschaft. Diese Eigenschaft wird auch nicht zurückgegeben, wenn Sie die Book-Instance abrufen.

Sie können Eigenschaften von primitiven .NET-Typen wie „int“ und „string“ zuweisen. Sie können auch beliebige Datentypen zuordnen, solange Sie einen geeigneten Konverter bereitstellen, um diese Datentypen einem DynamoDB-Datentyp zuzuordnen. Weitere Informationen zum Mapping beliebiger Datentypen finden Sie unter [Zuordnen beliebiger Daten mit DynamoDB mithilfe des AWS SDK für .NET Objektpersistenzmodells](DynamoDBContext.ArbitraryDataMapping.md).

Das Object Persistence-Modell unterstützt die optimistische Sperre. Während einer Aktualisierung stellt diese Funktion sicher, dass Sie über die neueste Kopie des zu aktualisierenden Elements verfügen. Weitere Informationen finden Sie unter [Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell](DynamoDBContext.VersionSupport.md).

Weitere Informationen finden Sie in den folgenden Themen.

**Topics**
+ [

## Unterstützte Datentypen
](#DotNetDynamoDBContext.SupportedTypes)
+ [

# DynamoDB-Attribute aus dem Object Persistence-Modell von .NET
](DeclarativeTagsList.md)
+ [

# DBContext Dynamo-Klasse aus dem .NET-Objektpersistenzmodell
](DotNetDynamoDBContext.md)
+ [

# Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell
](DynamoDBContext.VersionSupport.md)
+ [

# Zuordnen beliebiger Daten mit DynamoDB mithilfe des AWS SDK für .NET Objektpersistenzmodells
](DynamoDBContext.ArbitraryDataMapping.md)

## Unterstützte Datentypen
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

Das Object Persistence-Modell unterstützt eine Reihe primitiver .NET-Datentypen, Sammlungen sowie beliebiger Datentypen. Das Modell unterstützt die folgenden primitiven Datentypen. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

Das Objektpersistenzmodell unterstützt auch die .NET-Sammlungstypen. `DynamoDBContext`ist in der Lage, konkrete Sammlungstypen und einfache Plain Old CLR-Objekte () POCOs zu konvertieren.

In der folgenden Tabelle ist das Mapping der vorhergehenden .NET-Typen zu den DynamoDB-Typen zusammengefasst.


****  

| .NET-primitiver Typ | DynamoDB-Typ | 
| --- | --- | 
|  Alle Zahlentypen  |  `N` (Zahlentyp)  | 
|  Alle Zeichenfolgetypen  |  `S` (Zeichenfolgetyp)   | 
|  MemoryStream, Byte []  |  `B` (Binärtyp)   | 
| bool | N (Zahlentyp) 0 repräsentiert False und 1 steht für True. | 
| Sammlungstypen | BS-(Binärsatz)-Typ, SS-(Zeichenfolgesatz)-Typ und NS-(Zahlensatz)-Typ. | 
| DateTime | S (Zeichenfolgetyp). Die DateTime-Werte werden als ISO-8601-formatierte Zeichenfolgen gespeichert. | 

Das Object Persistence-Modell unterstützt außerdem beliebige Datentypen. Allerdings müssen Sie einen Konverter-Code bereitstellen, um die komplexen Typen den DynamoDB-Typen zuzuordnen.

**Anmerkung**  
Leere Binärwerte werden unterstützt.
Das Lesen von leeren Zeichenfolgenwerten wird unterstützt. Leere Zeichenfolgen-Attributwerte werden beim Schreiben zu DynamoDB in Attributwerten vom Typ Zeichenfolgensatz unterstützt. Leere Zeichenfolgen-Attributwerte des Zeichenfolgentyps und leere Zeichenfolgenwerte innerhalb des Listen- oder Map-Typs werden aus Schreibanforderungen gelöscht.

# DynamoDB-Attribute aus dem Object Persistence-Modell von .NET
<a name="DeclarativeTagsList"></a>

Dieser Abschnitt beschreibt die Attribute, die das Object-Persistence-Modell bereitstellt, damit Sie Ihre Klassen und Eigenschaften den DynamoDB-Tabellen und -Attributen zuordnen können.

**Anmerkung**  
In den folgenden Attributen werden ausschließlich `DynamoDBTable` und `DynamoDBHashKey` benötigt.

## Dynamo DBGlobal SecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

Ordnet eine Klasseneigenschaft dem Partitionsschlüssel eines globalen sekundären Indexes zu. Verwenden Sie dieses Attribut, wenn Sie einen globalen sekundären Index `Query` möchten.

## Dynamo DBGlobal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

Ordnet eine Klasseneigenschaft dem Sortierungsschlüssel eines globalen sekundären Indexes zu. Verwenden Sie dieses Attribut, wenn Sie eine `Query` für einen globalen sekundären Schlüssel ausführen müssen und die Ergebnisse mithilfe des Indexsortierschlüssels verfeinern möchten.

## Dynamo-Schlüssel DBHash
<a name="w2aac17b9c21c23c37c11"></a>

Ordnet eine Klasseneigenschaft dem Partitionsschlüssel des Primärschlüssels der Tabelle zu. Die Primärschlüsselattribute können nicht ein Sammlungstyp sein.

Im folgenden C\$1-Codebeispiel werden die Klasse `Book` der Tabelle `ProductCatalog` und die Eigenschaft `Id` dem Partitionsschlüssel des Primärschlüssels der Tabelle zugeordnet.

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

    // Additional properties go here.
}
```

## Dynamo DBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

Zeigt an, dass die zugeordnete Eigenschaft ignoriert werden sollte. Wenn Sie keine Klasseneigenschaften speichern möchten, können Sie dieses Attribut hinzufügen, um `DynamoDBContext` anzuweisen, diese Eigenschaft beim Speichern von Objekten zur Tabelle nicht einzufügen.

## Dynamo DBLocal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

Ordnet eine Klasseneigenschaft dem Sortierungsschlüssel eines lokalen sekundären Indexes zu. Verwenden Sie dieses Attribut, wenn Sie eine `Query` für einen lokalen sekundären Index ausführen müssen und die Ergebnisse mithilfe des Indexsortierschlüssels verfeinern möchten.

## Dynamo DBProperty
<a name="w2aac17b9c21c23c37c17"></a>

Ordnet eine Klasseneigenschaft einem Tabellenattribut zu. Wenn die Klasseneigenschaft einem Tabellenattribut mit dem gleichen Namen zugeordnet ist, müssen Sie dieses Attribut nicht angeben. Wenn die Namen jedoch nicht identisch sind, können Sie diesen Tag verwenden, um das Mapping bereitzustellen. In der folgenden C\$1-Anweisung ordnet `DynamoDBProperty` die Eigenschaft `BookAuthors` dem Attribut `Authors` in der Tabelle zu. 

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

`DynamoDBContext` verwendet diese Mappinginformationen, um beim Speichern von Objektdaten zur entsprechenden Tabelle das Attribut `Authors` zu erstellen.

## Dynamo DBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

Gibt einen alternativen Namen für eine Klasseneigenschaft an. Dies eignet sich für das Schreiben eines benutzerdefinierten Konverters, um beliebige Daten einer DynamoDB-Tabelle, in der sich der Name der Klasseneigenschaft von dem des Tabellenattributs unterscheidet, zuzuordnen.

## Dynamo-Schlüssel DBRange
<a name="w2aac17b9c21c23c37c21"></a>

Ordnet eine Klasseneigenschaft dem Sortierschlüssel des Primärschlüssels der Tabelle zu. Wenn die Tabelle über einen zusammengesetzten Primärschlüssel (Partitionsschlüssel und Sortierschlüssel) verfügt, müssen Sie sowohl das Attribut `DynamoDBHashKey` als auch das Attribut `DynamoDBRangeKey` im Klassenmapping angeben.

Die Beispieltabelle `Reply` verfügt über einen Primärschlüssel, der aus dem Partitionsschlüssel `Id` und dem Sortierschlüssel `Replenishment` besteht. Im folgenden C\$1-Codebeispiel wird die Klasse `Reply` der Tabelle `Reply` zugeordnet. Die Klassendefinition gibt ebenfalls an, dass zwei ihrer Eigenschaften den Primärschlüsseln zugeordnet werden.

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

## Dynamo DBTable
<a name="w2aac17b9c21c23c37c23"></a>

Identifiziert die Zieltabelle in DynamoDB, zu der die Klasse zugeordnet wird. Im folgenden C\$1-Codebeispiel wird beispielsweise die Klasse `Developer` der Tabelle `People` in DynamoDB zugeordnet.

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

Dieses Attribut kann geerbt oder überschrieben werden.
+ Das `DynamoDBTable`-Attribut kann geerbt werden. Wenn Sie im vorherigen Beispiel die neue Klasse `Lead` hinzufügen, die von der Klasse `Developer` erbt, wird diese ebenfalls der Tabelle `People` zugeordnet. Sowohl das Objekt `Developer` als auch das Objekt `Lead` werden in der Tabelle `People` gespeichert.
+ Das `DynamoDBTable`-Attribut kann auch überschrieben werden. Im folgenden C\$1-Codebeispiel erbt die Klasse `Manager` von der Klasse `Developer`. Durch das explizite Hinzufügen des Attributs `DynamoDBTable` wird die Klasse jedoch einer anderen Tabelle (`Managers`) zugeordnet.

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

 Sie können den optionalen Parameter `LowerCamelCaseProperties` hinzufügen, um DynamoDB aufzufordern, den ersten Buchstaben des Eigenschaftsnamens beim Speichern von Objekten in einer Tabelle klein zu schreiben wie im folgenden C\$1-Codebeispiel gezeigt.

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

Beim Speichern von Instances der Klasse `Developer` speichert `DynamoDBContext` die Eigenschaft `DeveloperName` als `developerName`.

## Dynamo DBVersion
<a name="w2aac17b9c21c23c37c25"></a>

Identifiziert eine Klasseneigenschaft für das Speichern der Versionsnummer des Elements. Weitere Informationen über das Versioning finden Sie unter [Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell](DynamoDBContext.VersionSupport.md).

# DBContext Dynamo-Klasse aus dem .NET-Objektpersistenzmodell
<a name="DotNetDynamoDBContext"></a>

Die `DynamoDBContext`-Klasse ist der Eintrittspunkt zu der Amazon-DynamoDB-Datenbank. Mit dieser Klasse verfügen Sie über eine Verbindung zu DynamoDB und können auf die Daten in unterschiedlichen Tabellen zugreifen, verschiedene CRUD-Operationen durchführen sowie Abfragen ausführen. Die Klasse `DynamoDBContext`-stellt folgende Methoden bereit.

**Topics**
+ [

## Erstellen MultiTable BatchGet
](#w2aac17b9c21c23c39b7)
+ [

## Erschaffen MultiTable BatchWrite
](#w2aac17b9c21c23c39b9)
+ [

## CreateBatchGet
](#w2aac17b9c21c23c39c11)
+ [

## CreateBatchWrite
](#w2aac17b9c21c23c39c13)
+ [

## Delete
](#w2aac17b9c21c23c39c15)
+ [

## Dispose
](#w2aac17b9c21c23c39c17)
+ [

## ExecuteBatchGet
](#w2aac17b9c21c23c39c19)
+ [

## ExecuteBatchWrite
](#w2aac17b9c21c23c39c21)
+ [

## FromDocument
](#w2aac17b9c21c23c39c23)
+ [

## FromQuery
](#w2aac17b9c21c23c39c25)
+ [

## FromScan
](#w2aac17b9c21c23c39c27)
+ [

## GetTargetTable
](#w2aac17b9c21c23c39c29)
+ [

## Load
](#w2aac17b9c21c23c39c31)
+ [

## Query
](#w2aac17b9c21c23c39c33)
+ [

## Save
](#w2aac17b9c21c23c39c35)
+ [

## Scan
](#w2aac17b9c21c23c39c37)
+ [

## ToDocument
](#w2aac17b9c21c23c39c39)
+ [

## Optionale Parameter für Dynamo angeben DBContext
](#OptionalConfigParams)

## Erstellen MultiTable BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Erstellt ein `MultiTableBatchGet`-Objekt, das aus verschiedenen einzelnen `BatchGet`-Objekten besteht. Jedes dieser `BatchGet`-Objekte kann verwendet werden, um Elemente aus einer einzelnen DynamoDB-Tabelle abzurufen.

Um die Elemente aus Tabellen abzurufen, verwenden Sie die Methode `ExecuteBatchGet`, indem Sie das `MultiTableBatchGet`-Objekt als Parameter übergeben.

## Erschaffen MultiTable BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Erstellt ein `MultiTableBatchWrite`-Objekt, das aus verschiedenen einzelnen `BatchWrite`-Objekten besteht. Jedes dieser `BatchWrite`-Objekte kann für das Schreiben und das Löschen von Elementen in einer einzelnen DynamoDB-Tabelle verwendet werden.

Um zu Tabellen zu schreiben, verwenden Sie die Methode `ExecuteBatchWrite`, indem Sie das `MultiTableBatchWrite`-Objekt als Parameter übergeben.

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

Erstellt ein `BatchGet`-Objekt, welches für das Abrufen mehrerer Elemente aus einer Tabelle verwenden werden kann. 

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

Erstellt ein `BatchWrite`-Objekt, das Sie zum Ablegen mehrerer Elemente in einer Tabelle oder zum Löschen mehrerer Elemente aus einer Tabelle verwenden können. 

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

Löscht ein Element aus der Tabelle. Die Methode erfordert den Primärschlüssel des Elements, das Sie löschen möchten. Sie können entweder den Primärschlüsselwert oder ein clientseitiges Objekt bereitstellen, das einen Primärschlüsselwert als Parameter für diese Methode enthält.
+ Wenn Sie ein clientseitiges Objekt als Parameter angeben und die optimistische Sperre aktiviert haben, ist der Löschvorgang nur dann erfolgreich, wenn die clientseitigen und die serverseitigen Versionen des Objekts übereinstimmen.
+ Wenn Sie lediglich den Primärschlüsselwert als Parameter angeben, ist der Löschvorgang erfolgreich, unabhängig davon, ob die optimistische Sperre aktiv ist oder nicht.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `DeleteAsync`-Methode.

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

Entsorgt alle verwalteten und nicht verwalteten Ressourcen.

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

Liest Daten aus einer oder mehreren Tabellen und verarbeitet alle `BatchGet`-Objekte in einem `MultiTableBatchGet`.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `ExecuteBatchGetAsync`-Methode.

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

Liest oder löscht Daten aus einer oder mehreren Tabellen und verarbeitet alle `BatchWrite`-Objekte in einem `MultiTableBatchWrite`.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `ExecuteBatchWriteAsync`-Methode.

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

Angesichts einer `Document`-Instance, gibt die `FromDocument`-Methode eine Instance der clientseitigen Klasse zurück.

Dies ist hilfreich, wenn Sie die Dokumentenmodell-Klassen zusammen mit dem Object Persistence-Modell verwenden möchten, um beliebige Datenoperationen durchzuführen. Weitere Hinweise zu den von der bereitgestellten Dokumentmodellklassen finden Sie unter[Arbeiten dem .NET-Dokumentmodell in DynamoDB](DotNetSDKMidLevel.md). AWS SDK für .NET

Angenommen, Sie besitzen ein `Document`-Objekt mit dem Namen `doc`, das eine Darstellung eines `Forum`-Elements enthält. (Informationen zum Konstruieren dieses Objekts finden Sie in der Beschreibung der Methode `ToDocument` weiter unten in diesem Thema.) Sie können `FromDocument` verwenden, um das `Forum`-Element aus dem `Document` abzurufen, wie im folgendem C\$1-Codebeispiel gezeigt.

**Example**  

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

**Anmerkung**  
Wenn das `Document`-Objekt die `IEnumerable`-Schnittstelle implementiert, können Sie stattdessen die `FromDocuments`-Methode nutzen. Auf diese Weise können Sie alle Klassen-Instances im `Document` durchlaufen.

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

Führt eine `Query`-Operation mit den Abfrageparametern aus, die in einem `QueryOperationConfig`-Objekt definiert sind.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `FromQueryAsync`-Methode.

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

Führt eine `Scan`-Operation mit den Scan-Parametern aus, die in einem `ScanOperationConfig`-Objekt definiert sind.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `FromScanAsync`-Methode.

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

Ruft die Zieltabelle für den angegebenen Typ ab. Dies ist nützlich, wenn Sie einen benutzerdefinierten Konverter schreiben, der einer DynamoDB-Tabelle beliebige Daten zuordnet, und ermitteln müssen, welche Tabelle einem benutzerdefinierten Datentyp zugeordnet ist.

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

Ruft ein Element aus einer Tabelle ab. Die Methode erfordert lediglich den Primärschlüssel des Elements, das Sie abrufen möchten. 

Standardmäßig gibt DynamoDB das Element mit Werten die Eventually Consistent sind zurück. Weitere Informationen zum Eventual Consistency-Modell finden Sie unter [DynamoDB-Lesekonsistenz](HowItWorks.ReadConsistency.md).

`Load`oder `LoadAsync` Methode ruft den [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)Vorgang auf, bei dem Sie den Primärschlüssel für die Tabelle angeben müssen. Da der `IndexName`-Parameter von `GetItem` ignoriert wird, können Sie ein Element nicht mithilfe der Partition oder des Sortierschlüssels eines Indexes laden. Daher müssen Sie den Primärschlüssel der Tabelle verwenden, um ein Element zu laden.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `LoadAsync`-Methode. Ein Beispiel für die Verwendung der `LoadAsync`-Methode zur Ausführung von CRUD-Vorgängen auf hoher Ebene in einer DynamoDB-Tabelle finden Sie im Folgenden.

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

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

Abfragen einer Tabelle basierend auf den Abfrageparametern, die Sie bereitstellen.

Sie können eine Tabelle nur dann abfragen, wenn sie über einen zusammengesetzten Primärschlüssel verfügt (Partitionsschlüssel und Sortierschlüssel). Bei der Abfrage müssen Sie einen Partitionsschlüssel und eine Bedingung angeben, die für den Sortierschlüssel gilt.

Angenommen, Sie verfügen über die clientseitige Klasse `Reply`, die der Tabelle `Reply` in DynamoDB zugeordnet ist. Das folgende C\$1-Codebeispiel fragt die Tabelle `Reply` ab, um alle Forum-Thread-Antworten zu finden, die in den letzten 15 Tagen veröffentlicht wurden. Die Tabelle `Reply` verfügt über einen Primärschlüssel, der aus einem Partitionsschlüssel (`Id`) und Sortierschlüssel (`ReplyDateTime`) besteht.

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

Dies gibt eine Sammlung von `Reply`-Objekten zurück. 

Die Methode `Query` gibt standardmäßig eine „lazy-loaded“ `IEnumerable`-Sammlung zurück. Sie gibt anfänglich ausschließlich eine Ergebnisseite zurück und führt dann bei Bedarf einen Dienstaufruf für die nächste Seite durch. Um alle übereinstimmenden Elemente zu erhalten, müssen Sie lediglich die `IEnumerable`-Sammlung durchlaufen.

Wenn die Tabelle über einen einfachen Primärschlüssel (Partitionsschlüssel) verfügt, können Sie die Methode `Query` nicht verwenden. Stattdessen können Sie die Methode `Load` verwenden und den Partitionsschlüssel bereitstellen, um das Element abzurufen.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `QueryAsync`-Methode.

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

Speichert das angegebene Objekt in der Tabelle. Wenn der im Eingabeobjekt angegebene Primärschlüssel in der Tabelle nicht vorhanden ist, fügt die Methode der Tabelle ein neues Element hinzu. Wenn der Primärschlüssel vorhanden ist, aktualisiert die Methode das vorhandene Element.

Wenn Sie eine optimistische Sperre konfiguriert haben, ist die Aktualisierung nur dann erfolgreich, wenn die client- und serverseitigen Versionen des Elements übereinstimmen. Weitere Informationen finden Sie unter [Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell](DynamoDBContext.VersionSupport.md).

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `SaveAsync`-Methode.

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

Führt einen gesamten Tabellen-Scan durch. 

Sie können Scan-Ergebnisse filtern, indem Sie eine Scan-Bedingung angeben. Die Bedingung kann auf jedem Attribut in der Tabelle ausgewertet werden. Angenommen, Sie verfügen über die clientseitige Klasse `Book`, die der Tabelle `ProductCatalog` in DynamoDB zugeordnet ist. Im folgenden C\$1-Beispiel werden die Tabelle gescannt und ausschließlich die Book-Elemente zurückgegeben, deren Preis kleiner als 0 ist.

**Example**  

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

Die Methode `Scan` gibt standardmäßig eine „lazy-loaded“ `IEnumerable`-Sammlung zurück. Sie gibt anfänglich ausschließlich eine Ergebnisseite zurück und führt dann bei Bedarf einen Dienstaufruf für die nächste Seite durch. Um alle übereinstimmenden Elemente zu erhalten, müssen Sie lediglich die `IEnumerable`-Sammlung durchlaufen.

Aus Leistungsgründen sollten Sie Ihre Tabellen abfragen und einen Tabellen-Scan vermeiden.

**Anmerkung**  
Um diese Operation im Hintergrund auszuführen, nutzen Sie stattdessen die `ScanAsync`-Methode.

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

Gibt eine Instance der `Document`-Dokumentenmodell-Klasse aus Ihrer Klassen-Instance zurück. 

Dies ist hilfreich, wenn Sie die Dokumentenmodell-Klassen zusammen mit dem Object Persistence-Modell verwenden möchten, um beliebige Datenoperationen durchzuführen. Weitere Hinweise zu den von der bereitgestellten Dokumentmodellklassen finden Sie unter[Arbeiten dem .NET-Dokumentmodell in DynamoDB](DotNetSDKMidLevel.md). AWS SDK für .NET

Angenommen, Sie verfügen über eine clientseitige Klasse, die der Tabelle `Forum` zugeordnet ist. Sie können anschließend einen `DynamoDBContext` verwenden, um ein Element als `Document`-Objekt aus der Tabelle `Forum` abzurufen, wie im folgenden C\$1-Codebeispiel gezeigt.

**Example**  

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

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

## Optionale Parameter für Dynamo angeben DBContext
<a name="OptionalConfigParams"></a>

Wenn Sie das Object Persistence-Modell verwenden, können Sie für den `DynamoDBContext` folgende optionale Parameter angeben.
+ **`ConsistentRead` – **Beim Abrufen von Daten mithilfe der `Load`, `Query` oder `Scan`-Operation können Sie diesen Parameter optional hinzufügen, um die neuesten Werte der Daten anzufordern.
+ **`IgnoreNullValues` – **Dieser Parameter teilt `DynamoDBContext` mit, Null-Werte von Attributen während einer `Save`-Operation zu ignorieren. Wenn dieser Parameter „false“ oder nicht festgelegt ist, wird ein Nullwert als Anweisung interpretiert, das betreffende Attribut zu löschen. 
+ **`SkipVersionCheck`—** Dieser Parameter teilt `DynamoDBContext` mit, beim Speichern oder Löschen von Elementen keine Versionen zu vergleichen. Weitere Informationen über das Versioning finden Sie unter [Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix` – ** Stellt allen Tabellennamen eine bestimmte Zeichenfolge voran. Wenn dieser Parameter Null ist (oder nicht festgelegt ist), dann wird kein Präfix verwendet.
+ `DynamoDBEntryConversion` – Gibt das Konvertierungsschema an, das vom Client verwendet wird. Sie können diesen Parameter auf Version V1 oder V2 festlegen. V1 ist die Standardversion.

  Je nach der von Ihnen festgelegten Version ändert sich das Verhalten dieses Parameters. Beispiel:
  + In V1 wird der Datentyp `bool` in den Zahlentyp `N` konvertiert, wobei 0 für falsch und 1 für wahr steht. In V2 wird `bool` in `BOOL` konvertiert.
  + In V2 werden Listen und Arrays nicht zusammen mit gruppiert. HashSets Listen und Arrays mit numerischen, auf Zeichenketten basierenden Typen und binären Typen werden in den Typ `L` (List) konvertiert, der leer gesendet werden kann, um eine Liste zu aktualisieren. Dies ist anders als bei V1, wo das Senden einer leeren Liste nicht möglich ist.

    In V1 werden Sammlungstypen wie List und Arrays gleich behandelt. HashSet Liste und HashSet Array von Zahlen werden in den Typ `NS` (Zahlensatz) konvertiert. 

  Im folgenden Beispiel wird die Version des Konvertierungsschemas auf V2 festgelegt, wodurch das Konvertierungsverhalten zwischen .NET-Typen und DynamoDB-Datentypen geändert wird.

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

Im folgenden C\$1-Codebeispiel wird durch Angabe von zwei der vorherigen optionalen Parameter, `ConsistentRead` und `SkipVersionCheck`, ein neuer Parameter `DynamoDBContext` erstellt.

**Example**  

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

`DynamoDBContext` berücksichtigt diese optionalen Parameter bei jeder Anforderung, die unter Verwendung dieses Kontextes gesendet werden. 

Anstatt diese Parameter auf der `DynamoDBContext`-Ebene festzulegen, können Sie diese mithilfe von `DynamoDBContext` für einzelne von Ihnen ausgeführte Operationen festlegen, wie im folgenden C\$1-Codebeispiel gezeigt. Das Beispiel lädt ein bestimmtes Book-Element. Die `Load`-Methode von `DynamoDBContext` gibt die optionalen Parameter `ConsistentRead` und `SkipVersionCheck` an.

**Example**  

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

In diesem Fall berücksichtigt `DynamoDBContext` diese Parameter ausschließlich beim Senden der `Get`-Anforderung.

# Optimistisches Sperren mit DynamoDB und dem AWS SDK für .NET Objektpersistenzmodell
<a name="DynamoDBContext.VersionSupport"></a>

Die Unterstützung der optimistischen Sperre im Object Persistence-Modell stellt sicher, dass die Elementversion für Ihre Anwendung dieselbe ist wie die serverseitige Elementversion, bevor das Element aktualisiert oder gelöscht wird. Angenommen, Sie rufen ein Element für eine Aktualisierung ab. Bevor Sie jedoch Ihre Aktualisierungen zurücksenden, aktualisiert eine andere Anwendung das gleiche Element. Jetzt verfügt Ihre Anwendung über eine veraltete Kopie des Elements. Ohne optimistische Sperre wird jede von Ihnen durchgeführte Aktualisierung die Aktualisierung von anderen Anwendungen überschreiben. 

Die Funktion "optimistische Sperre" des Object Persistence-Modells stellt den `DynamoDBVersion`-Tag bereit, den Sie für die Aktivierung der optimistische Sperre nutzen können. Um diese Funktion zu verwenden, fügen Sie Ihrer Klasse eine Eigenschaft hinzu, mit der die Versionsnummer gespeichert wird. Sie fügen der Eigenschaft das Attribut `DynamoDBVersion` hinzu. Wenn Sie das Element zum ersten Mal speichern, weist `DynamoDBContext` diesem eine Versionsnummer hinzu. Dieser Wert wird bei jeder Aktualisierung des Elements inkrementell erhöht. 

Ihre Aktualisierungs- oder Löschanforderungen werden nur erfolgreich ausgeführt, wenn die clientseitige Objektversion mit der entsprechenden Versionsnummer des Elements auf der Serverseite übereinstimmt. Wenn Ihre Anwendung über eine veraltete Kopie verfügt, muss sie die aktuelle Version vom Server erhalten, bevor sie das Element aktualisieren oder löschen kann.

Im folgenden C\$1-Codebeispiel wird die Klasse `Book` mit Object Persistence-Attributen definiert, die diese der Tabelle `ProductCatalog` zuordnen. Die Eigenschaft `VersionNumber` in der Klasse, die das `DynamoDBVersion`-Attribut aufweist, speichert den Wert der Versionsnummer.

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

**Anmerkung**  
Sie können das `DynamoDBVersion`-Attribut ausschließlich auf einen löschbaren numerischen primitiven Typen anwenden (z. B. `int?`). 

Die optimistische Sperre hat folgende Auswirkungen auf diese `DynamoDBContext`-Operationen:
+ Für ein neues Element weist `DynamoDBContext` die Erstversionsnummer 0 zu. Wenn Sie ein vorhandenes Element abrufen, eine oder mehrere von dessen Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, wird die Speicheroperation nur dann erfolgreich ausgeführt, wenn die client- und serverseitige Versionsnummer übereinstimmen. `DynamoDBContext` erhöht die Versionsnummer inkrementell. Sie müssen die Versionsnummer nicht festlegen.
+ Die Methode `Delete` stellt Überladungen bereit, die entweder einen Primärschlüsselwert oder ein Objekt als Parameter aufnehmen können, wie im folgenden C\$1-Codebeispiel gezeigt.  
**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);
  ```

  Wenn Sie ein Objekt als Parameter bereitstellen, ist der Löschvorgang nur dann erfolgreich, wenn die Objektversion mit der entsprechenden serverseitigen Elementversion übereinstimmt. Wenn Sie jedoch einen Primärschlüsselwert als Parameter bereitstellen, erkennt `DynamoDBContext` keine Versionsnummern und löscht das Element, ohne die Version zu prüfen. 

  Beachten Sie, dass die interne Implementierung von optimistischen Sperren in dem Code des Object-Persistence-Modells bedingte Aktualisierungen und bedingte Löschungs-API-Aktionen in DynamoDB verwendet.

## Deaktivieren der optimistischen Sperre
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Um die optimistische Sperre zu deaktivieren, verwenden Sie die Konfigurationseigenschaft `SkipVersionCheck`. Sie können diese Eigenschaft bei der Erstellung von `DynamoDBContext` festlegen. In diesem Fall wird die optimistische Sperre für alle Anforderungen deaktiviert, die Sie unter Verwendung des Kontextes ausführen. Weitere Informationen finden Sie unter [Optionale Parameter für Dynamo angeben DBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

Anstatt die Eigenschaft auf der Kontextebene festzulegen, können Sie die optimistische Sperre für eine bestimmte Operation deaktivieren wie im folgenden C\$1-Codebeispiel gezeigt. Im Beispiel wird der Kontext verwendet, um ein Book-Element zu löschen. Die Methode `Delete` legt die optionale Eigenschaft `SkipVersionCheck` auf „true“ fest und deaktiviert damit die Versionsprüfung.

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

# Zuordnen beliebiger Daten mit DynamoDB mithilfe des AWS SDK für .NET Objektpersistenzmodells
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Zusätzlich zu den unterstützten .NET-Typen (siehe [Unterstützte Datentypen](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)) können Sie Typen in Ihrer Anwendung verwenden, für die es kein direktes Mapping zu Amazon-DynamoDB-Typen gibt. Das Object-Persistence-Modell unterstützt das Speichern von Daten mit beliebigen Typen, solange Sie einen Konverter bereitstellen, um Daten des beliebigen Typs in den DynamoDB-Typ und umgekehrt zu konvertieren. Der Konverter-Code wandelt Daten während des Speicherns und Ladens der Objekte um.

Sie können clientseitig alle Typen erstellen. Die in den Tabellen gespeicherten Daten haben jedoch einen DynamoDB-Datentyp. Während Abfragen und Scans werden alle Datenvergleiche anhand der in DynamoDB gespeicherten Daten ausgeführt.

Das folgende C\$1-Codebeispiel definiert eine `Book`-Klasse mit den Eigenschaften `Id`, `Title`, `ISBN` und `Dimension`. Die Eigenschaft `Dimension` gehört zum `DimensionType`, der die Eigenschaften `Height`, `Width` und `Thickness` beschreibt. Der Beispielcode stellt die Konverter-Methoden `ToEntry` und `FromEntry` bereit, um Daten zwischen den Zeichenfolgetypen `DimensionType` und DynamoDB zu konvertieren. Beispielsweise erstellt der Konverter beim Speichern einer `Book`-Instance eine `Dimension`-Zeichenfolge wie „8.5x11x.05“. Wenn Sie ein Book abrufen, wird die Zeichenfolge in eine `DimensionType`-Instance konvertiert.

Im Beispiel wird der `Book`-Typ der Tabelle `ProductCatalog` zugewiesen. Es speichert eine `Book`-Beispiel-Instance, ruft sie ab, aktualisiert ihre Abmessungen und speichert die aktualisierte `Book`-Instance erneut.



 step-by-stepAnweisungen zum Testen des folgenden Beispiels finden Sie unter. [.NET-Codebeispiele](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;
        }
    }
}
```

# Ausführen der Codebeispiele in diesem Entwicklerhandbuch
<a name="CodeSamples"></a>

 AWS SDKs Sie bieten umfassende Unterstützung für Amazon DynamoDB in den folgenden Sprachen:
+ [Java](https://aws.amazon.com/sdk-for-java)
+ [JavaScript im Browser](https://aws.amazon.com/sdk-for-browser)
+ [.NET](https://aws.amazon.com/sdk-for-net)
+ [Node.js](https://aws.amazon.com/sdk-for-node-js)
+ [PHP](https://aws.amazon.com/sdk-for-php)
+ [Python](https://aws.amazon.com/sdk-for-python)
+ [Ruby](https://aws.amazon.com/sdk-for-ruby)
+ [C\$1\$1](https://aws.amazon.com/sdk-for-cpp)
+ [Go](https://aws.amazon.com/sdk-for-go)
+ [Android](https://aws.amazon.com/mobile/sdk/)
+ [iOS](https://aws.amazon.com/mobile/sdk/)

Die Codebeispiele in diesem Entwicklerhandbuch stellen umfassendere Informationen zu DynamoDB-Operationen unter Verwendung der folgenden Programmiersprachen bereit:
+ [Java-Codebeispiele](CodeSamples.Java.md)
+ [.NET-Codebeispiele](CodeSamples.DotNet.md)

Bevor Sie mit dieser Übung beginnen können, müssen Sie ein AWS Konto erstellen, Ihren Zugriffsschlüssel und Ihren geheimen Schlüssel abrufen und AWS Command Line Interface (AWS CLI) auf Ihrem Computer einrichten. Weitere Informationen finden Sie unter [Einrichten von DynamoDB (Webservice)](SettingUp.DynamoWebService.md).

**Anmerkung**  
Wenn Sie die herunterladbare Version von DynamoDB verwenden, müssen Sie die verwenden, AWS CLI um die Tabellen und Beispieldaten zu erstellen. Sie müssen den `--endpoint-url` Parameter auch bei jedem AWS CLI Befehl angeben. Weitere Informationen finden Sie unter [Festlegen des lokalen Endpunkts](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint).

# Erstellen von Tabellen und Laden von Daten für Codebeispiele in DynamoDB
<a name="SampleData"></a>

Im Folgenden finden Sie die Grundlagen zum Erstellen von Tabellen in DynamoDB, zum Laden eines Beispiel-Datensatzes, zum Abfragen der Daten und zum Aktualisieren der Daten.
+ [Schritt 1: Erstellen einer Tabelle in DynamoDB](getting-started-step-1.md)
+ [Schritt 2: Schreiben von Daten in eine DynamoDB-Tabelle](getting-started-step-2.md)
+ [Schritt 3: Lesen von Daten aus einer DynamoDB-Tabelle](getting-started-step-3.md)
+ [Schritt 4: Aktualisieren von Daten in einer DynamoDB-Tabelle](getting-started-step-4.md)

# Java-Codebeispiele
<a name="CodeSamples.Java"></a>

**Topics**
+ [

## Java: Deine AWS Zugangsdaten einrichten
](#CodeSamples.Java.Credentials)
+ [

## Java: AWS Region und Endpunkt festlegen
](#CodeSamples.Java.RegionAndEndpoint)

Dieses Entwicklerhandbuch enthält Java-Codefragmente und ready-to-run -Programme. Sie finden diese Codebeispiele in den folgenden Abschnitten:
+ [Arbeiten mit Elementen und Attributen in DynamoDB](WorkingWithItems.md)
+ [Arbeiten mit Tabellen und Daten in DynamoDB](WorkingWithTables.md)
+ [Abfragen von Tabellen in DynamoDB](Query.md)
+ [Scannen von Tabellen in DynamoDB](Scan.md)
+ [Verbessern des Datenzugriffs mit sekundären Indizes in DynamoDB](SecondaryIndexes.md)
+ [Java 1.x: Dynamo DBMapper](DynamoDBMapper.md)
+ [Ändern Sie die Datenerfassung für DynamoDB Streams](Streams.md)

Sie können sofort beginnen, indem Sie Eclipse mit dem [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/) verwenden. Neben einer IDE mit vollem Funktionsumfang erhalten Sie auch die AWS SDK für Java mit automatischen Updates und vorkonfigurierten Vorlagen für die Erstellung von Anwendungen. AWS 

**So führen Sie Java-Codebeispiele (mit Eclipse) aus**

1. Laden Sie die [Eclipse](http://www.eclipse.org)-IDE herunter und installieren Sie sie.

1. Laden Sie das [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/) herunter und installieren Sie es.

1. Starten Sie Eclipse und wählen Sie im **Eclipse**-Menü **File (Datei)**, **New (Neu)** und anschließend **Other (Sonstiges)** aus.

1. Wählen Sie unter **Assistent auswählen** **AWS** aus, wählen Sie **AWS Java-Projekt** und dann **Weiter** aus.

1. Gehen **Sie unter Create an AWS Java** wie folgt vor:

   1. Geben Sie im Feld **Projektname** einen Namen für Ihr Projekt an.

   1. Wählen Sie in **Select Account (Konto wählen)** das Anmeldeinformationsprofil in der Liste aus.

      Wenn Sie das zum ersten Mal verwenden [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/), wählen Sie ** AWS Konten konfigurieren**, um Ihre AWS Anmeldeinformationen einzurichten.

1. Wählen Sie **Finish** aus, um das Projekt zu erstellen.

1. Wählen Sie im **Eclipse**-Menü **File**, **New** und anschließend **Class** aus.

1. Geben Sie in **Java Class (Java-Klasse)** unter **Name (Name)** einen Namen für Ihre Klasse ein (verwenden Sie denselben Namen wie das Codebeispiel, das Sie ausführen möchten). Wählen Sie dann **Finish (Fertigstellen)** aus, um die Klasse zu erstellen.

1. Kopieren Sie das Codebeispiel aus der Dokumentationsseite in den Eclipse-Editor.

1. Wählen Sie im Eclipse-Menü **Run (Ausführen)** aus, um den Code auszuführen.

Das SDK für Java stellt threadsichere Clients für die Arbeit mit DynamoDB bereit. Als bewährte Methode sollten Ihre Anwendungen einen Client erstellen und diesen zwischen den Threads wiederverwenden.

Weitere Informationen hierzu finden Sie unter [AWS SDK für Java](https://aws.amazon.com/sdk-for-java).

**Anmerkung**  
Die Codebeispiele in diesem Handbuch sind für die Verwendung mit der neuesten Version des AWS SDK für Java vorgesehen.  
Wenn Sie das verwenden AWS Toolkit for Eclipse, können Sie automatische Updates für das SDK for Java konfigurieren. Gehen Sie dazu in Eclipse zu **Einstellungen** und wählen Sie **AWS Toolkit**, **AWS SDK für Java**, **Neues SDKs automatisch herunterladen**.

## Java: Deine AWS Zugangsdaten einrichten
<a name="CodeSamples.Java.Credentials"></a>

Das SDK for Java erfordert, dass Sie zur Laufzeit AWS Anmeldeinformationen für Ihre Anwendung angeben. Bei den Codebeispielen in diesem Handbuch wird davon ausgegangen, dass Sie eine AWS Anmeldeinformationsdatei verwenden, wie unter [Einrichten Ihrer AWS Anmeldeinformationen](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html) im *AWS SDK für Java Entwicklerhandbuch* beschrieben.

Im Folgenden finden Sie ein Beispiel für eine AWS Anmeldeinformationsdatei mit dem Namen`~/.aws/credentials`, wobei die Tilde (`~`) für Ihr Home-Verzeichnis steht.

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

## Java: AWS Region und Endpunkt festlegen
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

Standardmäßig greifen die Codebeispiele auf DynamoDB in der Region USA West (Oregon) auf. Sie können die Region ändern, indem Sie die `AmazonDynamoDB`-Eigenschaften ändern.

Im folgenden Codebeispiel wird ein neuer `AmazonDynamoDB` instanziiert.

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

Sie können die Methode `withRegion` verwenden, um den Code für DynamoDB in jeder verfügbaren Region auszuführen. Die vollständige Liste finden Sie unter [AWS -Regionen und -Endpunkte](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) in der *Allgemeine Amazon Web Services-Referenz*.

Wenn Sie die Codebeispiele mit DynamoDB lokal auf Ihrem Computer ausführen möchten, müssen Sie den Endpunkt wie folgt festlegen.

### AWS SDK V1
<a name="CodeSamples.Java.RegionAndEndpoint.V1"></a>

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

### AWS SDK V2
<a name="CodeSamples.Java.RegionAndEndpoint.V2"></a>

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

# .NET-Codebeispiele
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [

## .NET: Ihre Anmeldeinformationen einrichten AWS
](#CodeSamples.DotNet.Credentials)
+ [

## .NET: AWS Region und Endpunkt festlegen
](#CodeSamples.DotNet.RegionAndEndpoint)

Dieses Handbuch enthält.NET-Codefragmente und -Programme. ready-to-run Sie finden diese Codebeispiele in den folgenden Abschnitten:
+ [Arbeiten mit Elementen und Attributen in DynamoDB](WorkingWithItems.md)
+ [Arbeiten mit Tabellen und Daten in DynamoDB](WorkingWithTables.md)
+ [Abfragen von Tabellen in DynamoDB](Query.md)
+ [Scannen von Tabellen in DynamoDB](Scan.md)
+ [Verbessern des Datenzugriffs mit sekundären Indizes in DynamoDB](SecondaryIndexes.md)
+ [Arbeiten dem .NET-Dokumentmodell in DynamoDB](DotNetSDKMidLevel.md)
+ [Arbeiten mit dem Object Persistence-Modell von .NET und DynamoDB](DotNetSDKHighLevel.md)
+ [Ändern Sie die Datenerfassung für DynamoDB Streams](Streams.md)

Sie können schnell loslegen, indem Sie das AWS SDK für .NET mit dem Toolkit for Visual Studio verwenden.

**So führen Sie die .NET-Codebeispiele (mit Visual Studio) aus**

1. Laden Sie [Microsoft Visual Studio](https://www.visualstudio.com) herunter und installieren Sie es.

1. (Optional) Laden Sie das [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/) herunter und installieren Sie es.

1. Richten Sie Ihre AWS Anmeldeinformationen ein. Konfigurieren Sie ein Profil mit Anmeldeinformationen in Ihrer Datei mit gemeinsam genutzten AWS Anmeldeinformationen (`~/.aws/credentials`). Weitere Informationen finden Sie unter [Configure AWS credentials (Konfigurieren von AWS -Anmeldeinformationen)](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) im *AWS SDK für .NET -Entwicklerhandbuch*.

1. Starten Sie Visual Studio. Wählen Sie **File (Datei)**, **New (Neu)** und **Project (Projekt)** aus.

1. Suchen Sie nach **Console App**, wählen Sie die C\$1-Vorlage aus, die auf .NET abzielt, und klicken Sie dann auf **Weiter**. Konfigurieren Sie den Namen und den Speicherort Ihres Projekts und wählen Sie dann **Create** aus.

1. Fügen Sie das AWS SDK für NuGet DynamoDB-Paket zu Ihrem Projekt hinzu:

   1. Öffnen Sie im Solution Explorer das Kontextmenü (mit der rechten Maustaste) für Ihr Projekt und wählen Sie dann Pakete **verwalten NuGet** aus.

   1. Wählen Sie im NuGet Package Manager die Option **Durchsuchen** aus.

   1. Geben Sie im Suchfeld **AWSSDK.DynamoDBv2** ein und warten Sie, bis die Suche abgeschlossen ist.

   1. **Wählen Sie **AWSSDK.Dynamo DBv2** und dann Installieren.**

1. Öffnen Sie in Ihrem Visual Studio-Projekt. `Program.cs` Ersetzen Sie den Inhalt durch das Codebeispiel auf der Dokumentationsseite, das Sie ausführen möchten.

1. Wählen Sie auf der Visual Studio-Symbolleiste die Schaltfläche **Start (Starten)** aus, um den Code auszuführen.

Der SDK für .NET bietet Thread-sichere Clients für die Arbeit mit DynamoDB. Als bewährte Methode sollten Ihre Anwendungen einen Client erstellen und diesen zwischen den Threads wiederverwenden.

Weitere Informationen finden Sie unter [AWS SDK for .NET](https://aws.amazon.com/sdk-for-net).

**Anmerkung**  
Die Codebeispiele in diesem Handbuch sind für die Verwendung mit der neuesten Version des AWS SDK für .NET vorgesehen.

## .NET: Ihre Anmeldeinformationen einrichten AWS
<a name="CodeSamples.DotNet.Credentials"></a>

Das SDK für .NET erfordert, dass Sie zur Laufzeit AWS Anmeldeinformationen für Ihre Anwendung angeben. Bei den Codebeispielen in diesem Handbuch wird davon ausgegangen, dass Sie den SDK Store zur Verwaltung Ihrer AWS Anmeldeinformationsdatei verwenden, wie [unter Verwenden des AWS SDK für .NET SDK-Speichers](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store) *im Entwicklerhandbuch* beschrieben.

Toolkit for Visual Studio unterstützt mehrere Gruppen von Anmeldeinformationen aus einer beliebigen Anzahl von Konten. Jede Gruppe wird als *profile* bezeichnet. Visual Studio fügt der `App.config` Projektdatei Einträge hinzu, sodass Ihre Anwendung die AWS Anmeldeinformationen zur Laufzeit finden kann.

Das folgende Beispiel zeigt die `App.config`-Standarddatei, die bei der Erstellung eines neuen Projekts mit Toolkit for Visual Studio generiert wird.

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

Zur Laufzeit verwendet das `default` Programm die im `AWSProfileName` Eintrag angegebenen AWS Anmeldeinformationen. Die AWS Anmeldeinformationen selbst werden in verschlüsselter Form im SDK-Speicher gespeichert. Das Toolkit for Visual Studio bietet eine grafische Benutzeroberfläche, um Ihre Anmeldeinformationen vollständig über Visual Studio zu verwalten. Weitere Informationen finden Sie unter [Anmeldeinformationen angeben](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds) im *AWS Toolkit for Visual Studio -Benutzerleitfaden*.

**Anmerkung**  
Standardmäßig greifen die Codebeispiele auf DynamoDB in der Region USA West (Oregon) auf. Sie können die Region ändern, indem Sie den `AWSRegion`-Eintrag in der Datei App.config ändern. Sie können `AWSRegion` auf jede Region festlegen, in der DynamoDB verfügbar ist. Die vollständige Liste finden Sie unter [AWS -Regionen und -Endpunkte](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) in der *Allgemeine Amazon Web Services-Referenz*.

## .NET: AWS Region und Endpunkt festlegen
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

Standardmäßig greifen die Codebeispiele auf DynamoDB in der Region USA West (Oregon) auf. Sie können die Region ändern, indem Sie den `AWSRegion`-Eintrag in der Datei `App.config` ändern. Sie können auch die Region ändern, indem Sie die `AmazonDynamoDBClient`-Eigenschaften ändern.

Im folgenden Codebeispiel wird ein neuer `AmazonDynamoDBClient` instanziiert. Der Client wird so geändert, dass der Code für DynamoDB in einer anderen Region ausgeführt wird.

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

Die vollständige Liste der Regionen finden Sie unter [AWS -Regionen und -Endpunkte](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) in der *Allgemeine Amazon Web Services-Referenz*.

Wenn Sie die Codebeispiele mit DynamoDB lokal auf Ihrem Computer ausführen möchten, müssen Sie den Endpunkt wie folgt festlegen.

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

# DynamoDB Low-Level-API
<a name="Programming.LowLevelAPI"></a>

Die Amazon-DynamoDB-*Low-Level-API* ist die Schnittstelle auf Protokollebene für DynamoDB. Auf dieser Ebene muss jede HTTP(S)-Anforderung ordnungsgemäß formatiert sein und eine gültige digitale Signatur aufweisen.

Sie AWS SDKs erstellen DynamoDB-API-Anfragen auf niedriger Ebene in Ihrem Namen und verarbeiten die Antworten von DynamoDB. So können Sie sich auf Ihre Anwendungslogik konzentrieren und müssen sich nicht mit Einzelheiten der unteren Ebene aufhalten. Dennoch ist es hilfreich, grundlegende Kenntnisse darüber zu haben, wie die DynamoDB-API auf niedriger Ebene funktioniert.

Weitere Informationen zur DynamoDB-Low-Level-API finden Sie unter [Amazon-DynamoDB-API-Referenz](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**Anmerkung**  
DynamoDB Streams verfügt über eine eigene Low-Level-API, die von der von DynamoDB getrennt ist und vollständig von der unterstützt wird. AWS SDKs  
Weitere Informationen finden Sie unter [Ändern Sie die Datenerfassung für DynamoDB Streams](Streams.md). Informationen zur DynamoDB Streams-API auf niedriger Ebene finden Sie in der [Amazon-DynamoDB-Streams-API-Referenz](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html).

Die DynamoDB-API auf niedriger Ebene verwendet JavaScript Object Notation (JSON) als Wire-Protokollformat. JSON stellt Daten in einer Hierarchie dar, sodass Datenwerte und Datenstruktur gleichzeitig übermittelt werden. Name-Wert-Paare werden im Format `name:value` definiert. Die Datenhierarchie wird durch verschachtelte Klammern von Name-Wert-Paaren definiert.

DynamoDB verwendet JSON nur als Transportprotokoll, nicht als Speicherformat. AWS SDKs Sie verwenden JSON, um Daten an DynamoDB zu senden, und DynamoDB antwortet mit JSON. DynamoDB speichert Daten nicht dauerhaft im JSON-Format.

**Anmerkung**  
Weitere Informationen zu JSON finden Sie in der [Einführung zu JSON](http://json.org) auf der Website `JSON.org`.

**Topics**
+ [

## Anforderungsformat
](#Programming.LowLevelAPI.RequestFormat)
+ [

## Reaktionsformat
](#Programming.LowLevelAPI.ResponseFormat)
+ [

## Datentypbeschreibungen
](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [

## Numerische Daten
](#Programming.LowLevelAPI.Numbers)
+ [

## Binäre Daten
](#Programming.LowLevelAPI.Binary)

![\[DynamoDB-Low-Level-API und wie AWS SDKs mit Anfragen und Antworten auf Protokollebene umgegangen wird.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## Anforderungsformat
<a name="Programming.LowLevelAPI.RequestFormat"></a>

Die DynamoDB-Low-Level-API akzeptiert HTTP(S)-`POST`-Anforderungen als Eingabe. Sie AWS SDKs erstellen diese Anfragen für Sie.

Angenommen, Sie verfügen über eine Tabelle namens `Pets` mit einem Schlüsselschema bestehend aus `AnimalType` (Partitionsschlüssel) und `Name` (Sortierschlüssel). Beide Attribute sind vom Typ `string`. Um ein Element von abzurufen`Pets`, erstellt das AWS SDK die folgende Anfrage.

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

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

Beachten Sie bei dieser Anforderung Folgendes:
+ Der Header `Authorization` enthält Informationen, die DynamoDB benötigt, um die Anforderung zu authentifizieren. Weitere Informationen finden Sie unter [Signieren von AWS API-Anfragen](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) und [Signiervorgang für Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) in der *Allgemeine Amazon Web Services-Referenz*.
+ Der Header `X-Amz-Target` enthält den Namen einer DynamoDB-Operation: `GetItem`. (Ebenfalls enthalten ist die Version der API auf niedriger Ebene, in diesem Fall `20120810`.)
+ Die Nutzlast (der Text) der Anforderung enthält die Parameter für die Operation im JSON-Format. Für die Operation `GetItem` lauten die Parameter `TableName` und `Key`.

## Reaktionsformat
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

Nach Eingang der Anforderung wird diese von DynamoDB verarbeitet und der Service gibt eine Antwort zurück. Bei der zuvor gezeigten Anforderung enthält die Nutzlast der HTTP(S)-Antwort die Ergebnisse aus der Operation wie in dem folgenden Beispiel gezeigt.

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

Zu diesem Zeitpunkt sendet das AWS SDK die Antwortdaten zur weiteren Verarbeitung an Ihre Anwendung zurück.

**Anmerkung**  
Wenn DynamoDB eine Anforderung nicht verarbeiten kann, gibt der Service einen HTTP-Fehlercode mit einer entsprechenden Meldung zurück. Das AWS -SDK überträgt diese an Ihre Anwendung in Form von Ausnahmen. Weitere Informationen finden Sie unter [Fehlerbehandlung mit DynamoDB](Programming.Errors.md).

## Datentypbeschreibungen
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

Das Low-Level-DynamoDB-API-Protokoll erfordert, dass jedes Attribut von einem Datentypdeskriptor begleitet wird. *Datentypdeskriptoren* sind Token, die DynamoDB mitteilen, wie jedes Attribut zu interpretieren ist.

Die Beispiele unter [Anforderungsformat](#Programming.LowLevelAPI.RequestFormat) und [Reaktionsformat](#Programming.LowLevelAPI.ResponseFormat) zeigen, wie Datentypbeschreibungen verwendet werden. Die `GetItem`-Anforderung gibt `S` für die `Pets`-Schlüsselschemaattribute an (`AnimalType` und `Name`, vom Typ `string`). Die `GetItem`-Antwort enthält ein *Pets*-Element mit Attributen vom Typ `string` (`S`), `number` (`N`), `map` (`M`) und `list` (`L`).

Im Folgenden sehen Sie eine vollständige Liste der DynamoDB-Datentypbeschreibungen:
+ **`S`** – Zeichenfolge
+ **`N`** – Zahl
+ **`B`** – Binary
+ **`BOOL`** – Boolean
+ **`NULL`** – Nullwert
+ **`M`** – Zuordnung
+ **`L`** – Liste
+ **`SS`** – Zeichenfolgensatz
+ **`NS`** – Zahlensatz
+ **`BS`** – Binärzahlensatz

Die folgende Tabelle zeigt das richtige JSON-Format für jeden Datentypdeskriptor. Beachten Sie, dass Zahlen aus Gründen der Genauigkeit als Zeichenketten dargestellt werden, während boolesche Werte und Nullen ihre nativen JSON-Typen verwenden.


| Deskriptor | JSON-Format | Hinweise | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | Der Wert ist eine JSON-Zeichenfolge. | 
| N | \$1"N": "123.45"\$1 | Der Wert ist eine Zeichenfolge, keine JSON-Nummer. Dadurch bleibt die Präzision in allen Sprachen erhalten. | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | Der Wert ist eine Base64-kodierte Zeichenfolge. | 
| BOOL | \$1"BOOL": true\$1 | Der Wert ist ein boolescher JSON-Wert (trueoderfalse), keine Zeichenfolge. | 
| NULL | \$1"NULL": true\$1 | Value ist der boolesche JSON-Wert, der Null angibttrue. | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | Value ist ein JSON-Objekt mit Attributname-Wert-Paaren. | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | Value ist ein JSON-Array von Attributwerten. | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | Value ist ein JSON-Array von Zeichenketten. | 
| NS | \$1"NS": ["1", "2.5"]\$1 | Value ist ein JSON-Array von Zahlenzeichenfolgen. | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | Value ist ein JSON-Array von Base64-codierten Zeichenketten. | 

**Anmerkung**  
 Detaillierte Beschreibungen von DynamoDB-Datentypen finden Sie unter [Datentypen](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes).

## Numerische Daten
<a name="Programming.LowLevelAPI.Numbers"></a>

Die unterschiedlichen Programmiersprachen bieten verschiedene Ebenen der Unterstützung für JSON. In einigen Fällen möchten Sie möglicherweise eine Drittanbieterbibliothek zum Validieren und Parsen von JSON-Dokumenten verwenden.

Einige Drittanbieterbibliotheken bieten basierend auf dem JSON-Nummerntyp eigene Typen wie z. B. `int`, `long` oder `double` an. Der native Zahlendatentyp in DynamoDB ist diesen Datentypen nicht exakt zuordenbar, sodass es bei Unterschieden zu Konflikten kommen kann. Außerdem verarbeiten viele JSON-Bibliotheken keine numerischen Werte mit fester Präzision und leiten automatisch einen Double-Datentyp für Ziffernfolgen ab, die ein Dezimaltrennzeichen enthalten.

Um diese Art von Problemen zu lösen, stellt DynamoDB einen einzigen numerischen Typ ohne Datenverluste bereit. Um unerwünschte implizite Umwandlungen in einen Double-Wert zu verhindern, verwendet DynamoDB Zeichenfolgen für die Datenübertragung von numerischen Werten. Dieser Ansatz bietet Flexibilität bei der Aktualisierung von Attributwerten und sorgt außerdem für eine korrekte Sortiersemantik (z. B. werden die Werte "01", "2" und "03" in die richtige Reihenfolge gebracht).

Wenn für Ihre Anwendung die Zahlengenauigkeit wichtig ist, sollten Sie numerische Werte in Zeichenfolgen konvertieren, bevor Sie sie an DynamoDB übergeben.

## Binäre Daten
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB unterstützt binäre Attribute. JSON bietet für binäre Daten jedoch keine native Unterstützung. Um binäre Daten in einer Anforderung zu senden, müssen Sie sie im base64-Format kodieren. Nach Eingang der Anforderung werden die base64-Daten von DynamoDB zurück in binäre Daten dekodiert. 

Das von DynamoDB verwendete base64-Codierungsschema wird unter [RFC 4648](http://tools.ietf.org/html/rfc4648) auf der Website der Internet Engineering Task Force (IETF) beschrieben.

# Programmieren von Amazon DynamoDB mit Python und Boto3
<a name="programming-with-python"></a>

Dieser Leitfaden bietet eine Einführung für Programmierer, die Amazon DynamoDB mit Python verwenden möchten. Erfahren Sie mehr über die Abstraktionsebenen, das Konfigurationsmanagement, den Umgang mit Fehlern, die Steuerung von Wiederholungsrichtlinien, die Verwaltung von Keepalive und mehr.

**Topics**
+ [

## Informationen zu Boto
](#programming-with-python-about)
+ [

## Verwenden der Boto-Dokumentation
](#programming-with-python-documentation)
+ [

## Grundlegendes zu den Abstraktionsebenen für Clients und Ressourcen
](#programming-with-python-client-resource)
+ [

## Verwenden der Tabellenressource batch\$1writer
](#programming-with-python-batch-writer)
+ [

## Zusätzliche Codebeispiele zur Client- und Ressourcenebene
](#programming-with-python-additional-code)
+ [

## Verständnis der Interaktion von Client- und Resource-Objekten mit Sitzungen und Threads
](#programming-with-python-sessions-thread-safety)
+ [

## Anpassen des Config-Objekts
](#programming-with-python-config)
+ [

## Fehlerbehandlung
](#programming-with-python-error-handling)
+ [

## Protokollierung
](#programming-with-python-logging)
+ [

## Ereignis-Hooks
](#programming-with-python-event-hooks)
+ [

## Paginierung und der Paginator
](#programming-with-python-pagination)
+ [

## Waiter
](#programming-with-python-waiters)

## Informationen zu Boto
<a name="programming-with-python-about"></a>

**Sie können von Python aus auf DynamoDB zugreifen, indem Sie das offizielle AWS SDK für Python verwenden, das allgemein als Boto3 bezeichnet wird.** Der Name Boto (ausgesprochen boh-toh) stammt von einem Süßwasserdelfin, der im Amazon heimisch ist. Die Boto3-Bibliothek ist die dritte Hauptversion der Bibliothek, die erstmals 2015 veröffentlicht wurde. Die Boto3-Bibliothek ist ziemlich groß, da sie alle AWS Dienste unterstützt, nicht nur DynamoDB. Dieser Leitfaden zielt nur auf die Teile von Boto3 ab, die für DynamoDB relevant sind.

Boto wird von einem Open-Source-Projekt verwaltet und veröffentlicht, das auf gehostet wird AWS . GitHub Es ist in zwei Pakete aufgeteilt: [Botocore](https://github.com/boto/botocore) und [Boto3](https://github.com/boto/boto3).
+ **Botocore** bietet die Low-Level-Funktionalität. In Botocore finden Sie die Klassen Client, Session, Credentials, Config und Exception. 
+ **Boto3** baut auf Botocore auf. Es bietet eine übergeordnete, pythonischere Oberfläche. Insbesondere macht es eine DynamoDB-Tabelle als Ressource verfügbar und bietet eine einfachere, elegantere Oberfläche als die serviceorientierte Client-Schnittstelle auf niedrigerer Ebene.

Da diese Projekte auf gehostet werden GitHub, können Sie den Quellcode einsehen, offene Probleme verfolgen oder Ihre eigenen Probleme einreichen.

## Verwenden der Boto-Dokumentation
<a name="programming-with-python-documentation"></a>

Beginnen Sie mit der Boto-Dokumentation anhand der folgenden Ressourcen:
+ Beginnen Sie mit dem [Quickstart-Abschnitt](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html), der einen soliden Ausgangspunkt für die Paketinstallation bietet. Dort finden Sie Anweisungen zur Installation von Boto3, falls dies noch nicht geschehen ist (Boto3 ist häufig automatisch in AWS Diensten wie) verfügbar. AWS Lambda
+ Konzentrieren Sie sich danach auf den [DynamoDB-Leitfaden](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html) der Dokumentation. Darin erfahren Sie, wie Sie die grundlegenden DynamoDB-Aktivitäten ausführen: eine Tabelle erstellen und löschen, Elemente bearbeiten, Batch-Operationen ausführen, eine Abfrage ausführen und einen Scan durchführen. Für die Beispiele wird die Schnittstelle **Ressourcen** verwendet. Wenn Sie `boto3.resource('dynamodb')` sehen, bedeutet das, dass Sie die übergeordnete Schnittstelle **Ressourcen** verwenden.
+ Nach dem Leitfaden können Sie sich die [DynamoDB-Referenz](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html) nochmals ansehen. Diese Startseite bietet eine vollständige Liste der Klassen und Methoden, die Ihnen zur Verfügung stehen. Ganz oben sehen Sie die `DynamoDB.Client`-Klasse. Diese bietet Low-Level-Zugriff auf alle Operationen auf der Steuerungsebene und der Datenebene. Schauen Sie sich ganz unten die `DynamoDB.ServiceResource`-Klasse an. Dies ist die Pythonic-Schnittstelle auf höherer Ebene. Damit können Sie eine Tabelle erstellen, tabellenübergreifende Batch-Operationen ausführen oder eine `DynamoDB.ServiceResource.Table`-Instance für tabellenspezifische Aktionen abrufen.

## Grundlegendes zu den Abstraktionsebenen für Clients und Ressourcen
<a name="programming-with-python-client-resource"></a>

Die beiden Schnittstellen, mit denen Sie arbeiten werden, sind die **Client**- und die **Ressourcen**-Schnittstelle. 
+ Die Low-Level-**Client**-Schnittstelle bietet eine Eins-zu-Eins-Zuordnung zur zugrunde liegenden Service-API. Jede von DynamoDB angebotene API ist über den Client verfügbar. Das bedeutet, dass die Client-Schnittstelle vollständige Funktionalität bieten kann, aber häufig ausführlicher und komplexer in der Anwendung ist.
+ Die High-Level-**Ressourcen**-Schnittstelle bietet keine 1-zu-1-Zuordnung der zugrunde liegenden Service-API. Sie bietet jedoch Methoden, die Ihnen den Zugriff auf den Service erleichtern, z. B `batch_writer`.

Hier ein Beispiel für das Einfügen eines Elements über die Client-Schnittstelle. Beachten Sie, dass alle Werte als Map übergeben werden, wobei der Schlüssel ihren Typ ('S' für Zeichenfolge, 'N' für Zahl) und ihren Wert als Zeichenfolge angibt. Dies wird als DynamoDB-JSON-Format bezeichnet.

```
import boto3

dynamodb = boto3.client('dynamodb')

dynamodb.put_item(
    TableName='YourTableName',
    Item={
        'pk': {'S': 'id#1'},
        'sk': {'S': 'cart#123'},
        'name': {'S': 'SomeName'},
        'inventory': {'N': '500'},
        # ... more attributes ...
    }
)
```

Hier ist dieselbe `PutItem`-Operation, jedoch unter Verwendung der Ressourcenschnittstelle. Die Datentypisierung ist implizit:

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

table.put_item(
    Item={
        'pk': 'id#1',
        'sk': 'cart#123',
        'name': 'SomeName',
        'inventory': 500,
        # ... more attributes ...
    }
)
```

Bei Bedarf können Sie mithilfe der in boto3 bereitgestellten Klassen `TypeSerializer` und `TypeDeserializer` von dem normalen JSON- zum DynamoDB-JSON-Format konvertieren:

```
def dynamo_to_python(dynamo_object: dict) -> dict:
    deserializer = TypeDeserializer()
    return {
        k: deserializer.deserialize(v) 
        for k, v in dynamo_object.items()
    }  
  
def python_to_dynamo(python_object: dict) -> dict:
    serializer = TypeSerializer()
    return {
        k: serializer.serialize(v)
        for k, v in python_object.items()
    }
```

So führen Sie eine Abfrage mithilfe der Client-Schnittstelle durch. Sie drückt die Abfrage als ein JSON-Konstrukt aus. Es wird eine `KeyConditionExpression`-Zeichenfolge verwendet, die eine Variablenersetzung erfordert, um mögliche Schlüsselwortkonflikte zu behandeln:

```
import boto3

client = boto3.client('dynamodb')

# Construct the query
response = client.query(
    TableName='YourTableName',
    KeyConditionExpression='pk = :pk_val AND begins_with(sk, :sk_val)',
    FilterExpression='#name = :name_val',
    ExpressionAttributeValues={
        ':pk_val': {'S': 'id#1'},
        ':sk_val': {'S': 'cart#'},
        ':name_val': {'S': 'SomeName'},
    },
    ExpressionAttributeNames={
        '#name': 'name',
    }
)
```

Dieselbe Abfrageoperation, die die Ressourcenschnittstelle verwendet, kann verkürzt und vereinfacht werden:

```
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

response = table.query(
    KeyConditionExpression=Key('pk').eq('id#1') & Key('sk').begins_with('cart#'),
    FilterExpression=Attr('name').eq('SomeName')
)
```

Stellen Sie sich als letztes Beispiel vor, Sie möchten die ungefähre Größe einer Tabelle ermitteln (dabei handelt es sich um Metadaten, die in der Tabelle gespeichert sind und etwa alle 6 Stunden aktualisiert werden). Mit der Client-Schnittstelle führen Sie eine `describe_table()`-Operation aus und ziehen die Antwort aus der zurückgegebenen JSON-Struktur:

```
import boto3

dynamodb = boto3.client('dynamodb')

response = dynamodb.describe_table(TableName='YourTableName')
size = response['Table']['TableSizeBytes']
```

Mit der Ressourcenschnittstelle führt die Tabelle die Beschreibungsoperation implizit aus und präsentiert die Daten direkt als Attribut:

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')
size = table.table_size_bytes
```

**Anmerkung**  
Beachten Sie bei der Entscheidung, ob Sie mit der Client- oder der Ressourcenschnittstelle entwickeln möchten, dass der Ressourcenschnittstelle gemäß der [Ressourcendokumentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html) keine neuen Funktionen hinzugefügt werden: „Das AWS Python SDK-Team beabsichtigt nicht, der Ressourcenschnittstelle in boto3 neue Funktionen hinzuzufügen. Vorhandene Schnittstellen werden während des Lebenszyklus von boto3 weiterhin funktionieren. Kunden können über die Client-Oberfläche auf neuere Service-Features zugreifen.“

## Verwenden der Tabellenressource batch\$1writer
<a name="programming-with-python-batch-writer"></a>

Ein Vorteil, der nur mit der High-Level-Tabellenressource verfügbar ist, ist der `batch_writer`. DynamoDB unterstützt Batch-Schreibvorgänge und ermöglicht bis zu 25 Put- oder Löschvorgänge in einer Netzwerkanfrage. Eine solche Batchverarbeitung verbessert die Effizienz, da Netzwerk-Roundtrips minimiert werden.

Mit der Low-Level-Client-Bibliothek verwenden Sie die `client.batch_write_item()`-Operation, um Batches auszuführen. Sie müssen Ihre Arbeit manuell in Batches von 25 aufteilen. Nach jedem Vorgang müssen Sie außerdem eine Liste der unverarbeiteten Elemente anfordern (einige Schreibvorgänge können erfolgreich sein, während andere fehlschlagen könnten). Anschließend müssen Sie diese unverarbeiteten Elemente erneut an eine spätere `batch_write_item()`-Operation übergeben. Es gibt eine beträchtliche Menge an Boilerplate-Code.

Die Methode [Table.batch\$1writer](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/batch_writer.html) erstellt einen Kontextmanager zum Schreiben von Objekten in einem Batch. Dieser stellt eine Schnittstelle bereit, bei der es so aussieht, als würden Sie Elemente einzeln schreiben, aber intern werden die Elemente gepuffert und in Batches gesendet. Außerdem verarbeitet er auch implizite Wiederholungen unverarbeiteter Elemente.

```
dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

movies = # long list of movies in {'pk': 'val', 'sk': 'val', etc} format
with table.batch_writer() as writer:
    for movie in movies:
        writer.put_item(Item=movie)
```

## Zusätzliche Codebeispiele zur Client- und Ressourcenebene
<a name="programming-with-python-additional-code"></a>

Sie können auch auf die folgenden Beispiel-Repositorys verweisen, die die Nutzung verschiedener Funktionen sowohl mit dem Client als auch mit der Ressourcenebene untersuchen:
+ [Offizielle AWS -Single-Action-Codebeispiele](https://docs.aws.amazon.com/code-library/latest/ug/python_3_dynamodb_code_examples.html) 
+ [Offizielle AWS szenarioorientierte Codebeispiele.](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python)
+ [Von der Community verwaltete Beispiele für Single-Action-Codes](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/python)

## Verständnis der Interaktion von Client- und Resource-Objekten mit Sitzungen und Threads
<a name="programming-with-python-sessions-thread-safety"></a>

Das Resource-Objekt ist nicht Thread-sicher und sollte nicht über Threads oder Prozesse hinweg gemeinsam genutzt werden. Weitere Informationen finden Sie im [Leitfaden zur Resource](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html#multithreading-or-multiprocessing-with-resources).

Das Client-Objekt hingegen ist im Allgemeinen Thread-sicher. Ausgenommen sind bestimmte fortgeschrittene Features. Weitere Informationen finden Sie im [Leitfaden zu Clients](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#multithreading-or-multiprocessing-with-clients). 

Das Sitzungsobjekt ist nicht Thread-sicher. Daher sollten Sie in einer Multi-Threading-Umgebung für jeden neuen Client oder jedes neue Ressourcenobjekt zunächst eine neue Sitzung erstellen und daraus dann den jeweiligen Client oder das Ressourcenobjekt ableiten. Weitere Informationen finden Sie im [Leitfaden zu Sitzungen](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/session.html#multithreading-or-multiprocessing-with-sessions). 

Wenn Sie `boto3.resource()` aufrufen, verwenden Sie implizit die Standardsitzung. Das ist praktisch für das Schreiben von Single-Threaded-Code. Für Multi-Threaded-Code sollten Sie hingegen für jeden Thread eine eigene Session erstellen und daraus die jeweilige Resource abrufen:

```
# Explicitly create a new Session for this thread 
session = boto3.Session()
dynamodb = session.resource('dynamodb')
```

## Anpassen des Config-Objekts
<a name="programming-with-python-config"></a>

Beim Erstellen eines Client- oder Resource-Objekts können Sie optionale benannte Parameter übergeben, um das Verhalten zu steuern. Der Parameter `config` schaltet dabei eine Vielzahl von Funktionen frei. Es handelt sich um eine Instance von `botocore.client.Config`, und die [Referenzdokumentation zu Config](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html) zeigt alle verfügbaren Optionen zur Steuerung. Die [Anleitung zur Konfiguration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) bietet einen guten Überblick.

**Anmerkung**  
Sie können viele dieser Verhaltenseinstellungen auf Sitzungsebene, in der AWS -Konfigurationsdatei oder als Umgebungsvariablen ändern.

**Config für Timeouts**

Eine Anwendung einer benutzerdefinierten Konfiguration besteht darin, das Netzwerkverhalten anzupassen:
+ **connect\$1timeout (float oder int)** – Die Zeit in Sekunden, bis eine Timeout-Ausnahme beim Versuch eines Verbindungsaufbaus ausgelöst wird. Standardmäßig ist ein Zeitraum von 60 Sekunden festgelegt.
+ **read\$1timeout (float oder int)** – Die Zeit in Sekunden, bis beim Versuch einer Verbindungslesung eine Timeout-Ausnahme ausgelöst wird. Standardmäßig ist ein Zeitraum von 60 Sekunden festgelegt.

Timeouts von 60 Sekunden sind für DynamoDB zu hoch. Das bedeutet, dass eine vorübergehende Netzwerkstörung eine Verzögerung von einer Minute verursacht, bevor der Client einen erneuten Versuch unternehmen kann. Der folgende Code verkürzt die Timeouts auf eine Sekunde:

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

Weitere Informationen zu Timeouts finden Sie unter [Tuning der AWS Java SDK-HTTP-Anforderungseinstellungen für latenzbewusste](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/) DynamoDB-Anwendungen. Beachten Sie, dass das Java-SDK mehr Timeout-Konfigurationsmöglichkeiten bietet als das Python-SDK.

**Config für Keepalive**

Wenn Sie Botocore 1.27.84 oder höher verwenden, können Sie auch **TCP Keepalive** steuern:
+ **tcp\$1keepalive** (bool) – Aktiviert die Socket-Option TCP-Keepalive beim Erstellen neuer Verbindungen, wenn diese auf `True` gesetzt wurde (Standard ist `False`). Dies ist nur ab Botocore 1.27.84 verfügbar.

Wenn Sie TCP Keepalive auf `True` setzen, können Sie die durchschnittlichen Latenzen reduzieren. Hier ein Beispielcode, der TCP Keepalive bedingt auf true setzt, wenn Sie die richtige Botocore-Version haben:

```
import botocore
import boto3
from botocore.config import Config
from distutils.version import LooseVersion

required_version = "1.27.84"
current_version = botocore.__version__

my_config = Config(
   connect_timeout = 0.5,
   read_timeout = 0.5
)
if LooseVersion(current_version) > LooseVersion(required_version):
    my_config = my_config.merge(Config(tcp_keepalive = True))

dynamodb = boto3.resource('dynamodb', config=my_config)
```

**Anmerkung**  
TCP Keepalive unterscheidet sich von HTTP Keepalive. Bei TCP Keepalive werden kleine Pakete vom zugrunde liegenden Betriebssystem über die Socket-Verbindung gesendet, um die Verbindung aufrechtzuerhalten und etwaige Unterbrechungen sofort zu erkennen. Mit HTTP Keepalive wird die auf dem zugrunde liegenden Socket aufgebaute Webverbindung wiederverwendet. HTTP Keepalive ist bei boto3 immer aktiviert.

Es gibt jedoch eine Begrenzung, wie lange eine inaktive Verbindung aufrechterhalten werden kann. Erwägen Sie, regelmäßige Anfragen zu senden (z. B. jede Minute), wenn Sie eine Leerlaufverbindung haben, aber möchten, dass die nächste Anfrage eine bereits bestehende Verbindung nutzt.

**Config für Wiederholungsversuche**

Die Konfiguration akzeptiert auch ein Wörterbuch namens **Wiederholungen**, in dem Sie Ihr gewünschtes Wiederholungsverhalten angeben können. Wiederholungen finden innerhalb des SDK statt, wenn das SDK einen Fehler empfängt und der Fehler vorübergehend ist. Wenn ein Fehler intern wiederholt wird (und der Wiederholungsversuch schließlich erfolgreich ist), wird aus Sicht des aufrufenden Codes kein Fehler sichtbar, sondern nur eine leicht erhöhte Latenz. Hier sind die Werte, die Sie angeben können:
+ **max\$1attempts** – Eine Ganzzahl, die die maximale Anzahl von Wiederholungsversuchen angibt, die bei einer einzelnen Anfrage durchgeführt werden. Wenn Sie diesen Wert beispielsweise auf 2 setzen, wird die Anfrage nach der ersten Anfrage höchstens zweimal wiederholt. Wenn Sie diesen Wert auf 0 setzen, werden nach der ersten Anfrage keine weiteren Wiederholungsversuche durchgeführt. 
+ **total\$1max\$1attempts** – Eine Ganzzahl, die die maximale Gesamtzahl der Versuche angibt, die bei einer einzelnen Anfrage unternommen werden. Dies schließt die erste Anfrage ein, sodass ein Wert von 1 bedeutet, dass keine weiteren Anfragen versucht werden. Wenn sowohl `total_max_attempts` als auch `max_attempts` angegeben sind, hat `total_max_attempts` Vorrang. `total_max_attempts` und nicht `max_attempts` wird bevorzugt, da er mit der Umgebungsvariable `AWS_MAX_ATTEMPTS` und dem Konfigurationswert `max_attempts` in der Konfigurationsdatei übereinstimmt.
+ **mode** – Eine Zeichenfolge, die den Typ des Wiederholungsmodus darstellt, den Botocore verwenden soll. Gültige Werte sind:
  + **legacy** – Der Standardmodus. Wartet 50 ms beim ersten Wiederholungsversuch und verwendet dann ein exponentielles Backoff mit dem Basisfaktor 2. Für DynamoDB sind es insgesamt maximal 10 Versuche (sofern nicht wie oben gezeigt überschrieben wurde).
**Anmerkung**  
Bei exponentiellem Backoff wird fast 13 Sekunden mit dem letzten Versuch gewartet.
  + **Standard — Wird** als Standard bezeichnet, weil er konsistenter mit anderen ist. AWS SDKs Beim ersten Wiederholungsversuch wird eine zufällige Zeitspanne zwischen 0 ms und 1 000 ms abgewartet. Sollte ein weiterer Versuch erforderlich sein, wird erneut ein zufälliger Zeitraum zwischen 0 ms und 1 000 ms gewählt und mit 2 multipliziert. Sollten weitere Wiederholungsversuche erforderlich sein, erfolgt dieselbe zufällige Auswahl, multipliziert mit 4 usw. Jede Wartezeit ist auf 20 Sekunden begrenzt. Dieser Modus führt mehr Wiederholungen für mehr erkannte Fehlerbedingungen aus als der `legacy`-Modus. Für DynamoDB sind es insgesamt maximal 3 Versuche (sofern nicht wie oben gezeigt überschrieben wurde). 
  + **adaptive** - Ein experimenteller Wiederholungsmodus, der alle Funktionalitäten des Standardmodus beinhaltet, aber eine automatische clientseitige Drosselung hinzufügt. Mit adaptiver Ratenbegrenzung SDKs kann die Geschwindigkeit, mit der Anfragen gesendet werden, verlangsamt werden, um der Kapazität der AWS Dienste besser gerecht zu werden. Dies ist ein vorläufiger Modus, dessen Verhalten sich ändern kann. 

Eine erweiterte Definition dieser Wiederholungsmodi finden Sie in der [Anleitung zu Wiederholungsversuchen](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html) sowie im [Thema Wiederholungsverhalten in der SDK-Referenz](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html).

Hier ein Beispiel, das explizit die `legacy`-Wiederholungsrichtlinie mit insgesamt maximal 3 Anfragen (2 Wiederholungen) verwendet:

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0,
   retries = {
     'mode': 'legacy',
     'total_max_attempts': 3
   }
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

Da es sich bei DynamoDB um ein System mit hoher Verfügbarkeit und geringer Latenz handelt, sollten Sie bei der Geschwindigkeit von Wiederholungsversuchen möglicherweise etwas aggressiver vorgehen, als es die integrierten Wiederholungsrichtlinien zulassen. Sie können Ihre eigene Wiederholungsrichtlinie implementieren, indem Sie die maximale Anzahl der Versuche auf 0 setzen, die Ausnahmen selbst abfangen und es gegebenenfalls in Ihrem eigenen Code erneut versuchen, anstatt sich bei impliziten Wiederholungsversuchen auf boto3 zu verlassen.

Wenn Sie Ihre eigene Wiederholungsrichtlinie verwalten, sollten Sie zwischen Drosselungen und Fehlern unterscheiden:
+ Eine **Drosselung** (gekennzeichnet durch `ProvisionedThroughputExceededException` oder `ThrottlingException`) weist auf einen fehlerfreien Service hin, der Sie darüber informiert, dass Sie Ihre Lese- oder Schreibkapazität in einer DynamoDB-Tabelle oder Partition überschritten haben. Mit jeder Millisekunde, die vergeht, wird etwas mehr Lese- oder Schreibkapazität zur Verfügung gestellt, sodass Sie schnell (z. B. alle 50 ms) erneut versuchen können, auf die neu freigegebene Kapazität zuzugreifen. Bei Drosselungen ist kein exponentieller Backoff erforderlich, da Drosselungen für DynamoDB leichtgewichtig sind und keine Gebühren pro Anfrage anfallen. Exponentielles Backoff weist längere Wartezeiten jenen Client-Threads zu, die bereits am längsten gewartet haben, wodurch sich die statistischen Kennzahlen p50 und p99 weiter nach außen verschieben.
+ Ein **Fehler** (unter anderem durch `InternalServerError` oder `ServiceUnavailable` gekennzeichnet) weist auf ein vorübergehendes Problem mit dem Service hin. Dies kann für die gesamte Tabelle oder möglicherweise nur für die Partition gelten, aus der Sie lesen oder in die Sie schreiben. Bei Fehlern sollten Sie längere Pausen zwischen den Wiederholungsversuchen einlegen (etwa 250 ms oder 500 ms) und Jitter verwenden, um die Wiederholungen zeitlich zu staffeln.

**Config für maximale Poolverbindungen**

Abschließend ermöglicht die Konfiguration die Steuerung der Größe des Verbindungs-Pools:
+ **max\$1pool\$1connections (int)** – Die maximale Anzahl von Verbindungen, die in einem Verbindungspool beibehalten werden sollen. Wenn kein Wert festgelegt ist, wird der Standardwert 10 verwendet.

Diese Option steuert die maximale Anzahl von HTTP-Verbindungen, die zur Wiederverwendung gepoolt werden sollen. Für jede Sitzung wird ein anderer Pool verwaltet. Wenn Sie erwarten, dass mehr als 10 Threads gleichzeitig auf Clients oder Ressourcen zugreifen, die aus derselben Sitzung erstellt wurden, sollten Sie diesen Wert erhöhen, damit Threads nicht auf andere Threads warten müssen, die gerade eine gepoolte Verbindung verwenden.

```
import boto3
from botocore.config import Config

my_config = Config(
   max_pool_connections = 20
)

# Setup a single session holding up to 20 pooled connections
session = boto3.Session(my_config)

# Create up to 20 resources against that session for handing to threads
# Notice the single-threaded access to the Session and each Resource
resource1 = session.resource('dynamodb')
resource2 = session.resource('dynamodb')
# etc
```

## Fehlerbehandlung
<a name="programming-with-python-error-handling"></a>

AWS Nicht alle Serviceausnahmen sind in Boto3 statisch definiert. Dies liegt daran, dass Fehler und Ausnahmen bei AWS Diensten sehr unterschiedlich sind und sich ändern können. Boto3 verpackt alle Service-Ausnahmen als `ClientError` und stellt die Details als strukturiertes JSON bereit. Ein Fehlerantwort könnte beispielsweise wie folgt aufgebaut sein:

```
{
    'Error': {
        'Code': 'SomeServiceException',
        'Message': 'Details/context around the exception or error'
    },
    'ResponseMetadata': {
        'RequestId': '1234567890ABCDEF',
        'HostId': 'host ID data will appear here as a hash',
        'HTTPStatusCode': 400,
        'HTTPHeaders': {'header metadata key/values will appear here'},
        'RetryAttempts': 0
    }
}
```

Der folgende Code fängt alle `ClientError`-Ausnahmen ab und prüft den Zeichenfolgenwert des `Code` innerhalb des `Error`, um zu bestimmen, welche Aktion ausgeführt werden soll:

```
import botocore
import boto3

dynamodb = boto3.client('dynamodb')

try:
    response = dynamodb.put_item(...)

except botocore.exceptions.ClientError as err:
    print('Error Code: {}'.format(err.response['Error']['Code']))
    print('Error Message: {}'.format(err.response['Error']['Message']))
    print('Http Code: {}'.format(err.response['ResponseMetadata']['HTTPStatusCode']))
    print('Request ID: {}'.format(err.response['ResponseMetadata']['RequestId']))

    if err.response['Error']['Code'] in ('ProvisionedThroughputExceededException', 'ThrottlingException'):
        print("Received a throttle")
    elif err.response['Error']['Code'] == 'InternalServerError':
        print("Received a server error")
    else:
        raise err
```

Einige (aber nicht alle) Ausnahmecodes wurden als Top-Level-Klassen materialisiert. Sie können diese direkt behandeln. Wenn Sie die Client-Schnittstelle verwenden, werden diese Ausnahmen dynamisch in Ihrem Client-Objekt bereitgestellt, und Sie fangen sie über Ihre Client-Instance ab:

```
except ddb_client.exceptions.ProvisionedThroughputExceededException:
```

Wenn Sie die Ressourcenschnittstelle verwenden, müssen Sie `.meta.client` nutzen, um vom Ressourcenobjekt zum zugrunde liegenden Client zu gelangen und auf die Ausnahmen zuzugreifen:

```
except ddb_resource.meta.client.exceptions.ProvisionedThroughputExceededException:
```

Um die Liste der materialisierten Ausnahmetypen zu überprüfen, können Sie die Liste dynamisch generieren:

```
ddb = boto3.client("dynamodb")
print([e for e in dir(ddb.exceptions) if e.endswith('Exception') or e.endswith('Error')])
```

Wenn Sie eine Schreiboperation mit einem Bedingungsausdruck ausführen, können Sie vorgeben, dass der Wert des Elements in der Fehlerantwort zurückgegeben wird, falls der Ausdruck fehlschlägt.

```
try:
    response = table.put_item(
        Item=item,
        ConditionExpression='attribute_not_exists(pk)',
        ReturnValuesOnConditionCheckFailure='ALL_OLD'
    )
except table.meta.client.exceptions.ConditionalCheckFailedException as e:
    print('Item already exists:', e.response['Item'])
```

Weitere Informationen zur Fehlerbehandlung und zu Ausnahmen finden Sie unter:
+ Der [boto3-Leitfaden zur Fehlerbehandlung](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html) enthält weitere Informationen über Methoden zur Fehlerbehandlung. 
+ Im [DynamoDB-Entwicklerhandbuch zu Programmierfehlern](Programming.Errors.md) ist aufgeführt, auf welche Fehler Sie stoßen könnten. 
+ Der [Abschnitt Häufige Fehler in der API-Referenz](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html).
+ In der Dokumentation zu den einzelnen API-Vorgängen ist aufgeführt, welche Fehler dieser Aufruf erzeugen könnte (zum Beispiel [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html)).

## Protokollierung
<a name="programming-with-python-logging"></a>

Die Boto3-Bibliothek integriert sich mit dem in Python eingebauten Protokollierungsmodul, um Vorgänge während einer Sitzung zu protokollieren. Sie können das Protokollierungsmodul konfigurieren, um die Protokollierungsebenen zu steuern:

```
import logging

logging.basicConfig(level=logging.INFO)
```

Dadurch wird der Root-Logger so konfiguriert, dass er `INFO` und Nachrichten höherer Ebenen protokolliert. Protokollierungsnachrichten, die weniger schwerwiegend sind als Level 4, werden ignoriert. Zu den Protokollierungsebenen gehören `DEBUG`, `INFO`, `WARNING`, `ERROR` und `CRITICAL`. Der Standardwert ist `WARNING`.

Die Logger in boto3 sind hierarchisch aufgebaut. Die Bibliothek verwendet verschiedene Logger, die jeweils unterschiedlichen Teilen der Bibliothek entsprechen. Sie können das Verhalten der einzelnen Logger separat steuern:
+ **boto3**: Der Hauptlogger für das boto3-Modul.
+ **botocore**: Der Hauptlogger für das Botocore-Paket.
+ **botocore.auth**: Wird zum Protokollieren der AWS -Signaturerstellung für Anfragen verwendet.
+ **botocore.credentials**: Wird zum Protokollieren des Abrufs und der Aktualisierung von Anmeldeinformationen verwendet.
+ **botocore.endpoint**: Wird verwendet, um die Erstellung von Anfragen zu protokollieren, bevor sie über das Netzwerk gesendet werden.
+ **botocore.hooks**: Wird zum Protokollieren von Ereignissen verwendet, die in der Bibliothek ausgelöst wurden.
+ **botocore.loaders**: Wird für die Protokollierung verwendet, wenn Teile von AWS Servicemodellen geladen werden.
+ **botocore.parsers**: Wird zum Protokollieren von AWS -Serviceantworten verwendet, bevor sie geparst werden.
+ **botocore.retryhandler: Wird zum Protokollieren der Verarbeitung von erneuten Versuchen von Serviceanfragen** verwendet (Legacy-Modus). AWS 
+ **botocore.retries.standard: Wird zum Protokollieren der Verarbeitung von erneuten Versuchen von Serviceanfragen verwendet (Standard-** oder adaptiver Modus). AWS 
+ **botocore.utils**: Wird zum Protokollieren verschiedener Aktivitäten in der Bibliothek verwendet.
+ **botocore.waiter: Wird verwendet, um die Funktionalität von Kellnern** zu protokollieren, die einen Dienst abfragen, bis ein bestimmter Status erreicht ist. AWS 

Andere Bibliotheken protokollieren ebenfalls. Intern verwendet boto3 die URLlib3 eines Drittanbieters für die HTTP-Verbindungsverarbeitung. Wenn Ihnen Latenz wichtig ist, können Sie sich die Protokolle ansehen, um sicherzustellen, dass Ihr Pool gut ausgelastet ist, indem Sie nachsehen, wann urllib3 eine neue Verbindung aufbaut oder eine inaktive Verbindung schließt.
+ **urllib3.connectionpool**: Wird für die Protokollierung von Ereignissen bei der Verwaltung des Verbindungspools verwendet.

Der folgende Codeausschnitt setzt die allgemeine Protokollierung auf `INFO`, während für Endpunkt- und Verbindungspoolaktivitäten die `DEBUG`-Protokollierung aktiviert wird:

```
import logging

logging.getLogger('boto3').setLevel(logging.INFO)
logging.getLogger('botocore').setLevel(logging.INFO)
logging.getLogger('botocore.endpoint').setLevel(logging.DEBUG)
logging.getLogger('urllib3.connectionpool').setLevel(logging.DEBUG)
```

## Ereignis-Hooks
<a name="programming-with-python-event-hooks"></a>

Botocore gibt während verschiedener Phasen seiner Ausführung Ereignisse aus. Sie können Handler für diese Ereignisse registrieren, sodass Ihr Handler immer dann aufgerufen wird, wenn ein Ereignis ausgelöst wird. Auf diese Weise können Sie das Verhalten von Botocore erweitern, ohne die internen Funktionen ändern zu müssen.

Angenommen, Sie möchten jedes Mal nachverfolgen, wenn in Ihrer Anwendung eine `PutItem`-Operation auf einer beliebigen DynamoDB-Tabelle ausgeführt wird. Dann könnten Sie sich auf das Ereignis `'provide-client-params.dynamodb.PutItem'` registrieren, um jeden Aufruf von `PutItem` innerhalb der zugehörigen Sitzung zu erfassen und zu protokollieren. Hier ein Beispiel:

```
import boto3
import botocore
import logging

def log_put_params(params, **kwargs):
    if 'TableName' in params and 'Item' in params:
        logging.info(f"PutItem on table {params['TableName']}: {params['Item']}")

logging.basicConfig(level=logging.INFO)

session = boto3.Session()
event_system = session.events

# Register our interest in hooking in when the parameters are provided to PutItem
event_system.register('provide-client-params.dynamodb.PutItem', log_put_params)

# Now, every time you use this session to put an item in DynamoDB,
# it will log the table name and item data.
dynamodb = session.resource('dynamodb')
table = dynamodb.Table('YourTableName')
table.put_item(
    Item={
        'pk': '123',
        'sk': 'cart#123',
        'item_data': 'YourItemData',
        # ... more attributes ...
    }
)
```

Innerhalb des Handlers können Sie die Parameter sogar programmatisch verändern, um das Verhalten anzupassen:

```
params['TableName'] = "NewTableName"
```

Weitere Informationen zu Ereignissen finden Sie in der [Botocore-Dokumentation zu Ereignissen](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html) und in der [boto3-Dokumentation zu Ereignissen](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/events.html).

## Paginierung und der Paginator
<a name="programming-with-python-pagination"></a>

Manche Anfragen wie Query und Scan begrenzen die Datenmenge, die mit einer einzelnen Anfrage zurückgegeben wird, und erfordern wiederholte Anfragen, um nachfolgende Seiten abzurufen.

Mit dem `limit`-Parameter können Sie die maximale Anzahl von Elementen steuern, die pro Seite gelesen werden sollen. Beispielsweise können Sie `limit` verwenden, um nur die letzten 10 Elemente abzurufen. Beachten Sie, dass der Grenzwert angibt, wie viel aus der Tabelle gelesen werden sollte, bevor eine Filterung angewendet wird. Es gibt keine Möglichkeit, genau 10  nach dem Filtern anzugeben. Sie können nur die Anzahl der vorgefilterten Filter kontrollieren und clientseitig überprüfen, ob Sie tatsächlich 10 abgerufen haben. Unabhängig vom Grenzwert hat jede Antwort immer eine maximale Größe von 1 MB.

Wenn die Antwort ein `LastEvaluatedKey` enthält, bedeutet dies, dass die Antwort beendet wurde, weil sie eine Anzahl- oder Größenbeschränkung erreicht hat. Dieser Schlüssel ist der letzte Schlüssel, der für diese Antwort ausgewertet wird. Sie können diesen `LastEvaluatedKey` abrufen und an einen Folgeaufruf als `ExclusiveStartKey` weitergeben, um den nächsten Abschnitt von diesem Startpunkt aus zu lesen. Wenn kein `LastEvaluatedKey` zurückgegeben wird, bedeutet das, dass keine weiteren Elemente zu der Abfrage oder dem Scan passen.

Hier ein einfaches Beispiel (unter Verwendung der Ressourcenschnittstelle, jedoch hat die Client-Schnittstelle das gleiche Muster), bei dem maximal 100 Elemente pro Seite gelesen werden und eine Schleife ausgeführt wird, bis alle Elemente gelesen sind.

```
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

query_params = {
    'KeyConditionExpression': Key('pk').eq('123') & Key('sk').gt(1000),
    'Limit': 100
}

while True:
    response = table.query(**query_params)

    # Process the items however you like
    for item in response['Items']:
        print(item)

    # No LastEvaluatedKey means no more items to retrieve
    if 'LastEvaluatedKey' not in response:
        break

    # If there are possibly more items, update the start key for the next page
    query_params['ExclusiveStartKey'] = response['LastEvaluatedKey']
```

Der Einfachheit halber kann boto3 dies mit Paginatoren für Sie erledigen. Das funktioniert jedoch nur mit der Client-Schnittstelle. Hier ist der Code, der für die Verwendung von Paginatoren neu geschrieben wurde:

```
import boto3

dynamodb = boto3.client('dynamodb')

paginator = dynamodb.get_paginator('query')

query_params = {
    'TableName': 'YourTableName',
    'KeyConditionExpression': 'pk = :pk_val AND sk > :sk_val',
    'ExpressionAttributeValues': {
        ':pk_val': {'S': '123'},
        ':sk_val': {'N': '1000'},
    },
    'Limit': 100
}

page_iterator = paginator.paginate(**query_params)

for page in page_iterator:
    # Process the items however you like
    for item in page['Items']:
        print(item)
```

Weitere Informationen finden Sie im [Leitfaden zu Paginatoren](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html) und in der [API-Referenz für DynamoDB.Paginator.Query](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/paginator/Query.html).

**Anmerkung**  
Paginatoren haben auch ihre eigenen Konfigurationseinstellungen: `MaxItems`, `StartingToken` und `PageSize`. Für die Paginierung mit DynamoDB sollten Sie diese Einstellungen ignorieren.

## Waiter
<a name="programming-with-python-waiters"></a>

Waiter bieten die Möglichkeit, auf den Abschluss eines Vorgangs zu warten, bevor der nächste Schritt ausgeführt wird. Derzeit unterstützen sie nur das Warten auf die Erstellung oder Löschung einer Tabelle. Im Hintergrund prüft der Waiter alle 20 Sekunden, bis zu 25 Mal, ob der gewünschte Zustand erreicht wurde. Zwar könnten Sie diese Prüfung selbst implementieren, aber die Verwendung eines Waiters ist eine elegante Lösung beim Schreiben von Automatisierungsskripten.

Hier ist ein Beispielcode, der zeigt, wie Sie darauf warten können, dass eine bestimmte Tabelle erstellt wurde:

```
# Create a table, wait until it exists, and print its ARN
response = client.create_table(...)
waiter = client.get_waiter('table_exists')
waiter.wait(TableName='YourTableName')
print('Table created:', response['TableDescription']['TableArn']
```

Weitere Informationen finden Sie im [Waiter-Leitfaden](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#waiters) und in der [Waiter-Referenz](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#waiters).

# Programmieren von Amazon DynamoDB mit JavaScript
<a name="programming-with-javascript"></a>

Dieses Handbuch bietet Programmierern, die Amazon DynamoDB mit verwenden möchten, eine Orientierung. JavaScript Erfahren Sie mehr über die verfügbaren Abstraktionsebenen AWS SDK für JavaScript, die Konfiguration von Verbindungen, den Umgang mit Fehlern, die Definition von Wiederholungsrichtlinien, die Verwaltung von Keep-Alive und mehr.

**Topics**
+ [

## Über AWS SDK für JavaScript
](#programming-with-javascript-about)
+ [

## Verwenden von AWS SDK für JavaScript V3
](#programming-with-javascript-using-the-sdk)
+ [

## Zugriff auf die JavaScript Dokumentation
](#programming-with-javascript-documentation)
+ [

## Abstraktionsebenen
](#programming-with-javascript-abstraction-layers)
+ [

## Verwenden der Hilfsfunktion Marshall
](#programming-with-javascript-using-marshall-utility)
+ [

## Lesen von Elementen
](#programming-with-javascript-reading-items)
+ [

## Bedingte Schreibvorgänge
](#programming-with-javascript-conditional-writes)
+ [

## Paginierung
](#programming-with-javascript-pagination)
+ [

## Angeben der Konfiguration
](#programming-with-javascript-config)
+ [

## Waiter
](#programming-with-javascript-waiters)
+ [

## Fehlerbehandlung
](#programming-with-javascript-error-handling)
+ [

## Protokollierung
](#programming-with-javascript-logging)
+ [

## Überlegungen
](#programming-with-javascript-considerations)

## Über AWS SDK für JavaScript
<a name="programming-with-javascript-about"></a>

Das AWS SDK für JavaScript bietet Zugriff auf die AWS-Services Verwendung von Browserskripten oder Node.js. Diese Dokumentation konzentriert sich auf die neueste SDK-Version (V3). Die AWS SDK für JavaScript Version 3 wird von AWS als [Open-Source-Projekt verwaltet, das auf GitHub gehostet wird](https://github.com/aws/aws-sdk-js-v3). Probleme und Funktionsanfragen sind öffentlich und Sie können auf der Problemseite des GitHub Repositorys darauf zugreifen.

JavaScript V2 ähnelt V3, enthält jedoch Syntaxunterschiede. V3 ist modularer aufgebaut, was es einfacher macht, kleinere Abhängigkeiten zu versenden, und bietet erstklassigen TypeScript Support. Wir empfehlen die neueste SDK-Version zu verwenden.

## Verwenden von AWS SDK für JavaScript V3
<a name="programming-with-javascript-using-the-sdk"></a>

Mit dem Node Package Manager können Sie das SDK zu Ihrer Node.js-Anwendung hinzufügen. Die folgenden Beispiele zeigen, wie Sie die gängigsten SDK-Pakete für die Arbeit mit DynamoDB hinzufügen.
+ `npm install @aws-sdk/client-dynamodb`
+ `npm install @aws-sdk/lib-dynamodb`
+ `npm install @aws-sdk/util-dynamodb`

Die Installation von Paketen fügt Verweise im Abschnitt „Abhängigkeiten“ zu Ihrer package.json-Projektdatei hinzu. Sie haben die Möglichkeit, die neuere ECMAScript Modulsyntax zu verwenden. Weitere Informationen zu diesen beiden Ansätzen finden Sie im Abschnitt „Überlegungen“.

## Zugriff auf die JavaScript Dokumentation
<a name="programming-with-javascript-documentation"></a>

Beginnen Sie mit der JavaScript Dokumentation mit den folgenden Ressourcen:
+ Die JavaScript Kerndokumentation finden Sie im [Entwicklerhandbuch](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html). Installationsanweisungen finden Sie im Abschnitt **Einrichtung**.
+ In der [API-Referenzdokumentation](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) können Sie sich mit allen verfügbaren Klassen und Methoden vertraut machen.
+ Das SDK für JavaScript unterstützt viele AWS-Services andere als DynamoDB. Gehen Sie wie folgt vor, um eine spezifische API-Abdeckung für DynamoDB zu finden:

  1. Wählen Sie unter **Services** die Option **DynamoDB und Bibliotheken** aus. Hier wird der Low-Level-Client dokumentiert.

  1. Wählen Sie **lib-dynamodb** aus. Hier wird der High-Level-Client dokumentiert. Die beiden Clients stellen zwei verschiedene Abstraktionsebenen dar, die Sie verwenden können. Weitere Informationen zu Abstraktionsebenen finden Sie im folgenden Abschnitt.

## Abstraktionsebenen
<a name="programming-with-javascript-abstraction-layers"></a>

Das SDK für JavaScript V3 hat einen Low-Level-Client (`DynamoDBClient`) und einen High-Level-Client (). `DynamoDBDocumentClient`

**Topics**
+ [

### Low-Level-Client (`DynamoDBClient`)
](#programming-with-javascript-low-level-client)
+ [

### High-Level-Client (`DynamoDBDocumentClient`)
](#programming-with-javascript-high-level-client)

### Low-Level-Client (`DynamoDBClient`)
<a name="programming-with-javascript-low-level-client"></a>

Der Low-Level-Client bietet keine zusätzlichen Abstraktionen gegenüber dem zugrunde liegenden Wire-Protokoll. Es bietet Ihnen volle Kontrolle über alle Aspekte der Kommunikation, aber da keine Abstraktionen vorhanden sind, müssen Sie beispielsweise Elementdefinitionen im DynamoDB-JSON-Format bereitstellen. 

Wie das folgende Beispiel zeigt, müssen bei diesem Format die Datentypen explizit angegeben werden. Ein *S* steht für einen Zeichenkettenwert und ein *N* steht für einen Zahlenwert. Zahlen werden beim Übertragen stets als Zeichenketten gesendet, die als Zahlentypen gekennzeichnet sind, um einen Präzisionsverlust zu vermeiden. Low-Level-API-Aufrufe haben ein Benennungsmuster wie `PutItemCommand` und `GetItemCommand`.

Im folgenden Beispiel wird der Low-Level-Client mit einem `Item` verwendet, das im DynamoDB-JSON-Format definiert ist:

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      "id": { S: "Product01" },
      "description": { S: "Hiking Boots" },
      "category": { S: "footwear" },
      "sku": { S: "hiking-sku-01" },
      "size": { N: "9" }
    }
  };

  try {
    const data = await client.send(new PutItemCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

### High-Level-Client (`DynamoDBDocumentClient`)
<a name="programming-with-javascript-high-level-client"></a>

Der DynamoDB-Dokumentenclient auf hoher Ebene bietet integrierte Komfortfunktionen, z. B. macht das manuelle Marshalling von Daten überflüssig und ermöglicht direkte Lese- und Schreibvorgänge mithilfe von Standardobjekten. JavaScript Die [Dokumentation zu `lib-dynamodb`](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-lib-dynamodb/) enthält eine Liste der Vorteile.

Um den `DynamoDBDocumentClient` zu instanziieren, erstellen Sie zunächst einen Low-Level-`DynamoDBClient` und umschließen ihn anschließend mit einem `DynamoDBDocumentClient`. Die Namenskonventionen der Funktionen unterscheiden sich leicht zwischen den beiden Paketen. Der Low-Level-Client verwendet beispielsweise `PutItemCommand`, während der High-Level-Client `PutCommand` verwendet. Durch die unterschiedlichen Namen können beide Funktionssets im selben Kontext koexistieren, sodass Sie sie innerhalb desselben Skripts kombinieren können.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    },
  };

  try {
    const data = await docClient.send(new PutCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

addProduct();
```

Das Verwendungsmuster ist konsistent, wenn Sie Elemente mithilfe von API-Operationen wie `GetItem`, `Query` oder `Scan` lesen.

## Verwenden der Hilfsfunktion Marshall
<a name="programming-with-javascript-using-marshall-utility"></a>

Sie können den Low-Level-Client verwenden und die Datentypen selbst mit marshall oder unmarshall konvertieren. Das Hilfspaket [util-dynamodb](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-util-dynamodb/) enthält eine `marshall()`-Hilfsfunktion, die JSON entgegennimmt und DynamoDB-JSON erzeugt, sowie eine `unmarshall()`-Funktion, die den umgekehrten Vorgang ausführt. Im folgenden Beispiel wird der Low-Level-Client verwendet, wobei die Datenkonvertierung durch den Aufruf von `marshall()` erfolgt.

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");
const { marshall } = require("@aws-sdk/util-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: marshall({
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    }),
  };

  try {
    const data = await client.send(new PutItemCommand(params));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

## Lesen von Elementen
<a name="programming-with-javascript-reading-items"></a>

Um ein einzelnes Element aus DynamoDB zu lesen, verwenden Sie die API-Operation `GetItem`. Ähnlich wie beim `PutItem`-Befehl haben Sie die Wahl zwischen dem Low-Level-Client und dem High-Level-Dokument-Client. Das folgende Beispiel zeigt, wie Sie mit dem High-Level-Dokument-Client ein Element abrufen.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, GetCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function getProduct() {
  const params = {
    TableName: "products",
    Key: {
      id: "Product01",
    },
  };

  try {
    const data = await docClient.send(new GetCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

getProduct();
```

Verwenden Sie die `Query`-API-Operation, um mehrere Elemente zu lesen. Sie können den Low-Level-Client oder den Dokument-Client verwenden. Im folgenden Beispiel wird der High-Level-Dokument-Client verwendet.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
  DynamoDBDocumentClient,
  QueryCommand,
} = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function productSearch() {
  const params = {
    TableName: "products",
    IndexName: "GSI1",
    KeyConditionExpression: "#category = :category and begins_with(#sku, :sku)",
    ExpressionAttributeNames: {
      "#category": "category",
      "#sku": "sku",
    },
    ExpressionAttributeValues: {
      ":category": "footwear",
      ":sku": "hiking",
    },
  };

  try {
    const data = await docClient.send(new QueryCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

productSearch();
```

## Bedingte Schreibvorgänge
<a name="programming-with-javascript-conditional-writes"></a>

DynamoDB-Schreibvorgänge können eine logische Bedingungsausdruck angeben, der als true ausgewertet werden muss, damit der Schreibvorgang ausgeführt wird. Wenn die Bedingung nicht als wahr ausgewertet wird, erzeugt die Schreiboperation eine Ausnahme. Der Bedingungsausdruck kann überprüfen, ob das Element bereits existiert oder ob seine Attribute bestimmten Beschränkungen entsprechen.

`ConditionExpression = "version = :ver AND size(VideoClip) < :maxsize" `

Wenn der Bedingungsausdruck fehlschlägt, können Sie `ReturnValuesOnConditionCheckFailure` verwenden, um anzufordern, dass die Fehlermeldung das Element enthält, das die Bedingungen nicht erfüllt hat. So können Sie leichter nachvollziehen, worin das Problem bestand. Weitere Informationen finden Sie unter [Behandeln von bedingten Schreibfehlern in Szenarien mit hoher Parallelität mit Amazon DynamoDB](https://aws.amazon.com/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/).

```
try {
      const response = await client.send(new PutCommand({
          TableName: "YourTableName",
          Item: item,
          ConditionExpression: "attribute_not_exists(pk)",
          ReturnValuesOnConditionCheckFailure: "ALL_OLD"
      }));
  } catch (e) {
      if (e.name === 'ConditionalCheckFailedException') {
          console.log('Item already exists:', e.Item);
      } else {
          throw e;
      }
  }
```

[Zusätzliche Codebeispiele, die andere Aspekte der Verwendung von JavsScript SDK V3 zeigen, sind in der [JavaScript SDK V3-Dokumentation](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_dynamodb_code_examples.html) und im Repository verfügbar. DynamoDB-SDK-Examples GitHub ](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/node.js)

## Paginierung
<a name="programming-with-javascript-pagination"></a>

**Topics**
+ [

### Verwenden der `paginateScan`-Komfortmethode
](#using-the-paginatescan-convenience-method)

Leseanfragen wie `Scan` oder `Query` geben wahrscheinlich mehrere Elemente in einem Datensatz zurück. Wenn Sie einen `Scan` oder eine `Query` mit einem `Limit`-Parameter durchführen, sendet das System nach dem Lesen dieser Anzahl von Elementen eine Teilantwort, und Sie müssen die Ergebnisse paginieren, um weitere Elemente abzurufen.

Das System liest pro Anfrage maximal 1 Megabyte an Daten. Wenn Sie einen `Filter`-Ausdruck verwenden, liest das System weiterhin maximal ein Megabyte von der Festplatte, gibt jedoch nur die Elemente dieses Megabytes zurück, die dem Filter entsprechen. Die Filteroperation kann für eine Seite null Elemente zurückgeben, erfordert aber dennoch eine weitere Paginierung, bevor die Suche abgeschlossen ist.

Sie sollten im Antwortobjekt nach dem `LastEvaluatedKey` suchen und diesen als `ExclusiveStartKey`-Parameter in einer nachfolgenden Anfrage verwenden, um die Datenabfrage fortzusetzen. Dies dient als eine Art Lesezeichen, wie im folgenden Beispiel gezeigt.

**Anmerkung**  
Im Beispiel wird beim ersten Durchlauf ein null-Wert für `lastEvaluatedKey` als `ExclusiveStartKey` übergeben, und das ist zulässig.

Beispiel - Verwenden des `LastEvaluatedKey`:

```
const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScan() {
  let lastEvaluatedKey;
  let pageCount = 0;

  do {
    const params = {
      TableName: "products",
      ExclusiveStartKey: lastEvaluatedKey,
    };

    const response = await client.send(new ScanCommand(params));
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, response.Items);
    lastEvaluatedKey = response.LastEvaluatedKey;
  } while (lastEvaluatedKey);
}

paginatedScan().catch((err) => {
  console.error(err);
});
```

### Verwenden der `paginateScan`-Komfortmethode
<a name="using-the-paginatescan-convenience-method"></a>



Das SDK stellt Komfortmethoden namens `paginateScan` und `paginateQuery` bereit, die diese Arbeit für Sie übernehmen und die wiederholten Anfragen im Hintergrund ausführen. Die maximale Anzahl der pro Anfrage zu lesenden Elemente geben Sie über den Standardparameter `Limit` an.

```
const { DynamoDBClient, paginateScan } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScanUsingPaginator() {
  const params = {
    TableName: "products",
    Limit: 100
  };

  const paginator = paginateScan({client}, params);

  let pageCount = 0;

  for await (const page of paginator) {
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, page.Items);
  }
}

paginatedScanUsingPaginator().catch((err) => {
  console.error(err);
});
```

**Anmerkung**  
Regelmäßige vollständige Tabellenscans sind kein empfohlenes Zugriffsmuster, es sei denn, die Tabelle ist klein.

## Angeben der Konfiguration
<a name="programming-with-javascript-config"></a>

**Topics**
+ [

### Config für Timeouts
](#programming-with-javascript-config-timeouts)
+ [

### Config für Keepalive
](#programming-with-javascript-config-keep-alive)
+ [

### Config für Wiederholungsversuche
](#programming-with-javascript-config-retries)

Beim Einrichten des `DynamoDBClient` können Sie verschiedene Konfigurationsüberschreibungen festlegen, indem Sie ein Konfigurationsobjekt an den Konstruktor übergeben. Beispielsweise können Sie die Region angeben, mit der eine Verbindung hergestellt werden soll, falls sie dem aufrufenden Kontext nicht bereits bekannt ist, oder die zu verwendende Endpunkt-URL. Dies ist besonders nützlich, wenn Sie eine lokale DynamoDB-Instance für Entwicklungszwecke ansprechen möchten.

```
const client = new DynamoDBClient({
  region: "eu-west-1",
  endpoint: "http://localhost:8000",
});
```

### Config für Timeouts
<a name="programming-with-javascript-config-timeouts"></a>

DynamoDB verwendet HTTPS für die Client-Server-Kommunikation. Sie können einige Aspekte der HTTP-Ebene steuern, indem Sie ein `NodeHttpHandler`-Objekt bereitstellen. Beispielsweise können Sie die wichtigsten Timeout-Werte `connectionTimeout` und `requestTimeout` anpassen. `connectionTimeout` ist die maximale Dauer in Millisekunden, die der Client beim Versuch, eine Verbindung herzustellen, wartet, bevor er aufgibt.

`requestTimeout` legt fest, wie lange der Client nach dem Senden einer Anfrage auf eine Antwort wartet, ebenfalls in Millisekunden. Die Standardwerte für beide Parameter sind null, was bedeutet, dass kein Timeout aktiviert ist und der Client unbegrenzt auf eine Antwort wartet, falls diese nicht eintrifft. Es ist empfehlenswert, sinnvolle Timeout-Werte zu setzen, damit bei Netzwerkproblemen ein Fehler ausgelöst wird und eine neue Anfrage gestartet werden kann. Beispiel:

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";

const requestHandler = new NodeHttpHandler({
  connectionTimeout: 2000,
  requestTimeout: 2000,
});

const client = new DynamoDBClient({
  requestHandler
});
```

**Anmerkung**  
Im bereitgestellten Beispiel wird der [Smithy](https://smithy.io/2.0/index.html)-Import verwendet. Smithy ist eine Sprache zur Definition von Diensten und ist eine Open-Source-Sprache SDKs, die von verwaltet wird. AWS

Zusätzlich zur Konfiguration von Timeout-Werten können Sie die maximale Anzahl von Sockets festlegen, was eine höhere Anzahl gleichzeitiger Verbindungen pro Ursprung ermöglicht. Der Entwicklerleitfaden enthält [Details zur Konfiguration des Parameters `maxSockets`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html).

### Config für Keepalive
<a name="programming-with-javascript-config-keep-alive"></a>

Bei der Verwendung von HTTPS erfordert die erste Anfrage immer eine gewisse back-and-forth Kommunikation, um eine sichere Verbindung herzustellen. HTTP Keepalive ermöglicht es, dass nachfolgende Anfragen die bereits aufgebaute Verbindung wiederverwenden, wodurch die Effizienz steigt und die Latenz sinkt. HTTP Keep-Alive ist standardmäßig mit JavaScript V3 aktiviert. 

Es gibt jedoch eine Begrenzung, wie lange eine inaktive Verbindung aufrechterhalten werden kann. Wenn Sie eine Verbindung im Leerlauf haben, die für die nächste Anfrage wiederverwendet werden soll, sollten Sie in Erwägung ziehen, regelmäßig Anfragen zu senden, z. B. einmal pro Minute.

**Anmerkung**  
Beachten Sie, dass in der älteren V2-Version des SDK Keepalive standardmäßig deaktiviert war, was bedeutet, dass jede Verbindung unmittelbar nach der Nutzung geschlossen wurde. Wenn Sie V2 verwenden, können Sie diese Einstellung überschreiben.

### Config für Wiederholungsversuche
<a name="programming-with-javascript-config-retries"></a>

Wenn das SDK eine Fehlermeldung erhält und der Fehler laut SDK als wiederholbar gilt, z. B. bei einer Drosselungsausnahme oder einem temporären Service-Ausnahmefehler, wird automatisch ein erneuter Versuch gestartet. Dies geschieht für den Aufrufer unsichtbar, außer dass die Anfrage möglicherweise etwas länger dauert, bis sie erfolgreich ist.

Das SDK für JavaScript V3 stellt standardmäßig insgesamt 3 Anfragen, bevor es aufgibt und den Fehler an den aufrufenden Kontext weitergibt. Sie können sowohl die Anzahl als auch die Frequenz dieser Wiederholungen anpassen.

Der Konstruktor des `DynamoDBClient` akzeptiert die Einstellung `maxAttempts`, mit der Sie die maximale Anzahl von Versuchen festlegen können. Im folgenden Beispiel wird der Wert von standardmäßig 3 auf insgesamt 5 erhöht. Wenn Sie ihn auf 0 oder 1 setzen, bedeutet das, dass Sie keine automatischen Wiederholungen wünschen und wiederholbare Fehler selbst im catch-Block behandeln möchten.

```
const client = new DynamoDBClient({
  maxAttempts: 5,
});
```

Sie können das Timing der Wiederholungen mit einer benutzerdefinierten Wiederholungsstrategie steuern. Dazu importieren Sie das Hilfspaket `util-retry` und erstellen eine benutzerdefinierte Backoff-Funktion, die die Wartezeit zwischen den Wiederholungen basierend auf der aktuellen Anzahl der Versuche berechnet.

Im folgenden Beispiel sind maximal 5 Versuche vorgesehen, mit Verzögerungen von 15, 30, 90 und 360 Millisekunden, falls der erste Versuch fehlschlägt. Die benutzerdefinierte Backoff-Funktion ` calculateRetryBackoff` nimmt die Nummer des Wiederholungsversuchs entgegen (beginnend mit 1 für den ersten Wiederholungsversuch) und gibt die Anzahl der Millisekunden zurück, die vor dem nächsten Versuch gewartet werden sollen.

```
const { ConfiguredRetryStrategy } = require("@aws-sdk/util-retry");

const calculateRetryBackoff = (attempt) => {
  const backoffTimes = [15, 30, 90, 360];
  return backoffTimes[attempt - 1] || 0;
};

const client = new DynamoDBClient({
  retryStrategy: new ConfiguredRetryStrategy(
    5, // max attempts.
    calculateRetryBackoff // backoff function.
  ),
});
```

## Waiter
<a name="programming-with-javascript-waiters"></a>

Der DynamoDB-Client enthält außerdem zwei nützliche [Waiter-Funktionen](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/wait/index.html#cli-aws-dynamodb-wait), die beim Erstellen, Ändern oder Löschen von Tabellen verwendet werden können, wenn der Code erst fortfahren soll, nachdem die Tabellenoperation abgeschlossen ist. Beispielsweise können Sie eine Tabelle bereitstellen, die Funktion `waitUntilTableExists` aufrufen, und der Code blockiert dann, bis die Tabelle in den Status **ACTIVE** wechselt. Der Waiter fragt den DynamoDB-Service alle 20 Sekunden intern über `describe-table` ab.

```
import {waitUntilTableExists, waitUntilTableNotExists} from "@aws-sdk/client-dynamodb";

… <create table details>

const results = await waitUntilTableExists({client: client, maxWaitTime: 180}, {TableName: "products"});
if (results.state == 'SUCCESS') {
  return results.reason.Table
}
console.error(`${results.state} ${results.reason}`);
```

Die Funktion `waitUntilTableExists` gibt die Kontrolle erst dann zurück, wenn ein `describe-table`-Befehl erfolgreich ausgeführt werden kann, der den Tabellenstatus als **ACTIVE** bestätigt. Dadurch können Sie `waitUntilTableExists` nicht nur verwenden, um auf die vollständige Erstellung einer Tabelle zu warten, sondern auch auf Änderungen wie das Hinzufügen eines GSI-Index, dessen Anwendung einige Zeit in Anspruch nehmen kann, bevor die Tabelle wieder den Status **ACTIVE** erreicht.

## Fehlerbehandlung
<a name="programming-with-javascript-error-handling"></a>

In den bisherigen Beispielen wurden alle Fehler pauschal abgefangen. In praktischen Anwendungen ist es jedoch wichtig, zwischen verschiedenen Fehlertypen zu unterscheiden und eine präzisere Fehlerbehandlung zu implementieren.

Fehlermeldungen von DynamoDB enthalten Metadaten, darunter den Namen des Fehlers. Sie können Fehler abfangen und anhand der möglichen Fehlerbezeichnungen entscheiden, wie weiter vorzugehen ist. Bei serverseitigen Fehlern können Sie den Operator `instanceof` zusammen mit den im Paket `@aws-sdk/client-dynamodb` exportierten Fehlertypen verwenden, um die Fehlerbehandlung effizient zu gestalten.

Beachten Sie, dass diese Fehler erst auftreten, nachdem alle Wiederholungsversuche ausgeschöpft wurden. Wenn ein Fehler erneut versucht und schließlich erfolgreich abgeschlossen wird, erscheint aus Sicht des Codes kein Fehler, sondern nur eine leicht erhöhte Latenz. Wiederholungen werden in den CloudWatch Amazon-Diagrammen als erfolglose Anfragen angezeigt, z. B. Drosselungs- oder Fehleranfragen. Wenn der Client die maximale Anzahl an Wiederholungen erreicht, gibt er auf und löst eine Ausnahme aus. Dies signalisiert, dass keine weiteren Wiederholungen erfolgen werden.

Im Folgenden sehen Sie einen Codeausschnitt, der zeigt, wie Sie einen Fehler abfangen und je nach Fehlertyp entsprechend reagieren können.

```
import {
  ResourceNotFoundException
  ProvisionedThroughputExceededException,
  DynamoDBServiceException,
} from "@aws-sdk/client-dynamodb";

try {
  await client.send(someCommand);
} catch (e) {
    if (e instanceof ResourceNotFoundException) {
      // Handle ResourceNotFoundException
    } else if (e instanceof ProvisionedThroughputExceededException) {
      // Handle ProvisionedThroughputExceededException
    } else if (e instanceof DynamoDBServiceException) {
      // Handle DynamoDBServiceException
    } else {
      // Other errors such as those from the SDK
      if (e.name === "TimeoutError") {
        // Handle SDK TimeoutError.
      } else {
        // Handle other errors.
      }
    }
}
```

Allgemeine Fehlerzeichenfolgen finden Sie unter [Fehlerbehandlung mit DynamoDB](Programming.Errors.md) im *DynamoDB-Entwicklerhandbuch*. Die genauen Fehler, die bei einem bestimmten API-Aufruf auftreten können, finden Sie in der Dokumentation zu diesem API-Aufruf, z. B. in den [Abfrage-API-Dokumenten](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html).

Die Metadaten von Fehlern enthalten je nach Fehler zusätzliche Eigenschaften. Bei einem ` TimeoutError` enthält die Fehlermeldung Metadaten wie die Anzahl der durchgeführten Versuche und die `totalRetryDelay`, wie im Folgenden gezeigt.

```
{
  "name": "TimeoutError",
  "$metadata": {
    "attempts": 3,
    "totalRetryDelay": 199
  }
}
```

Wenn Sie Ihre eigene Wiederholungsrichtlinie verwalten, sollten Sie zwischen Drosselungen und Fehlern unterscheiden:
+ Eine **Drosselung** (gekennzeichnet durch ` ProvisionedThroughputExceededException` oder `ThrottlingException`) weist auf einen fehlerfreien Service hin, der Sie darüber informiert, dass Sie Ihre Lese- oder Schreibkapazität in einer DynamoDB-Tabelle oder Partition überschritten haben. Mit jeder Millisekunde, die vergeht, wird etwas mehr Lese- oder Schreibkapazität zur Verfügung gestellt, sodass Sie schnell, z. B. alle 50 ms, erneut versuchen können, auf die neu freigegebene Kapazität zuzugreifen.

   Bei Drosselungen ist kein exponentieller Backoff erforderlich, da Drosselungen für DynamoDB leichtgewichtig sind und keine Gebühren pro Anfrage anfallen. Exponentielles Backoff weist längere Wartezeiten jenen Client-Threads zu, die bereits am längsten gewartet haben, wodurch sich die statistischen Kennzahlen p50 und p99 weiter nach außen verschieben.
+ Ein **Fehler** (z. B. ` InternalServerError` oder `ServiceUnavailable`) weist auf ein vorübergehendes Problem mit dem Service, möglicherweise der gesamten Tabelle oder nur mit der Partition hin, aus der Sie lesen oder in die Sie schreiben. Bei Fehlern sollten Sie längere Pausen zwischen den Wiederholungsversuchen einlegen (etwa 250 ms oder 500 ms) und Jitter verwenden, um die Wiederholungen zeitlich zu staffeln.

## Protokollierung
<a name="programming-with-javascript-logging"></a>

Aktivieren Sie die Protokollierung, um mehr Details darüber zu erhalten, was das SDK im Hintergrund tut. Sie können dazu einen Parameter im `DynamoDBClient` setzen, wie im folgenden Beispiel gezeigt. Zusätzliche Protokollinformationen erscheinen in der Konsole und enthalten Metadaten wie den Statuscode und die verbrauchte Kapazität. Wenn Sie den Code lokal in einem Terminalfenster ausführen, erscheinen die Protokolle dort. Wenn Sie den Code ausführen und CloudWatch Amazon-Logs eingerichtet haben, wird die Konsolenausgabe dort geschrieben. AWS Lambda

```
const client = new DynamoDBClient({
  logger: console
});
```

Sie können auch in die internen Aktivitäten des SDK eingreifen und benutzerdefinierte Protokollierung durchführen, sobald bestimmte Ereignisse eintreten. Das folgende Beispiel verwendet den `middlewareStack` des Clients, um jede Anfrage abzufangen, während sie vom SDK gesendet wird, und sie in Echtzeit zu protokollieren.

```
const client = new DynamoDBClient({});

client.middlewareStack.add(
  (next) => async (args) => {
    console.log("Sending request from AWS SDK", { request: args.request });
    return next(args);
  },
  {
    step: "build",
    name: "log-ddb-calls",
  }
);
```

Der `MiddlewareStack` bietet eine leistungsstarke Schnittstelle, um das Verhalten des SDK zu beobachten und zu steuern. Weitere Informationen finden Sie im Blog [Introducing Middleware Stack in Modular AWS SDK für JavaScript](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/).

## Überlegungen
<a name="programming-with-javascript-considerations"></a>

Bei der Implementierung AWS SDK für JavaScript in Ihrem Projekt sollten Sie folgende weitere Faktoren berücksichtigen.

**Modulsysteme**  
Das SDK unterstützt zwei Modulsysteme, CommonJS und ES (ECMAScript). CommonJS verwendet die `require`-Funktion, während ES das `import`-Schlüsselwort verwendet.  

1. **Common JS** – `const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");`

1. **ES (ECMAScript**— `import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";`
Der Projekttyp bestimmt, welches Modulsystem verwendet wird, und wird im Abschnitt Typ Ihrer package.json-Datei angegeben. Standardmäßig ist dies CommonJS. Verwenden Sie `"type": "module"`, um ein ES-Projekt zu kennzeichnen. Wenn Sie ein bestehendes Node.js-Projekt haben, das das CommonJS-Paketformat verwendet, können Sie dennoch Funktionen mit der moderneren Import-Syntax von SDK V3 hinzufügen, indem Sie Ihre Funktionsdateien mit der Endung .mjs benennen. Dadurch kann die Codedatei als ES (ECMAScript) behandelt werden.

**Asynchrone Operationen**  
Viele Codebeispiele verwenden Callbacks und Promises, um die Ergebnisse von DynamoDB-Operationen zu verarbeiten. In der heutigen Zeit wird JavaScript diese Komplexität nicht mehr benötigt und Entwickler können die Vorteile der prägnanteren und lesbareren async/await Syntax für asynchrone Operationen nutzen.

**Laufzeit des Webbrowsers**  
Web- und Mobilentwickler, die mit React oder React Native bauen, können das SDK für ihre JavaScript Projekte verwenden. Mit der früheren Version V2 des SDK mussten Webentwickler das vollständige SDK in den Browser laden und dabei auf ein SDK-Image verweisen, das unter https://sdk.amazonaws.com/js/ gehostet wird.   
Mit V3 ist es möglich, mit Webpack nur die erforderlichen V3-Client-Module und alle erforderlichen JavaScript Funktionen in einer einzigen JavaScript Datei zu bündeln und sie in einem Skript-Tag auf Ihren HTML-Seiten hinzuzufügen, wie im Abschnitt [Erste Schritte in einem Browserskript](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/getting-started-browser.html) der SDK-Dokumentation beschrieben. `<head>`

**DAX-Operationen auf Datenebene**  
Die Datenebenenoperationen von Amazon DynamoDB Streams Accelerator (DAX) werden vom SDK für JavaScript V3 unterstützt.

# Programmieren von DynamoDB mit dem AWS SDK for Java 2.x
<a name="ProgrammingWithJava"></a>

Dieser Programmierleitfaden bietet eine Einführung für Entwickler, die Amazon DynamoDB mit Java verwenden möchten. Es werden verschiedene Konzepte wie Abstraktionsschichten, Konfigurationsmanagement, Fehlerbehandlung, Steuerung von Wiederholungsrichtlinien und Verwaltung von Keepalive-Verbindungen behandelt.

**Topics**
+ [

## Über die AWS SDK for Java 2.x
](#AboutProgrammingWithJavaSDK)
+ [Erste Schritte](#GetStartedProgrammingWithJavaSDK)
+ [SDK for Java-2.x-Dokumentation](#ProgrammingWithJavaUseDoc)
+ [

## Unterstützte Schnittstellen
](#JavaInterfaces)
+ [

## Weitere Codebeispiele
](#AdditionalCodeEx)
+ [Synchrone und asynchrone Programmierung](#SyncAsyncProgramming)
+ [

## HTTP-Clients
](#HttpClients)
+ [Config](#ConfigHttpClient)
+ [

## Fehlerbehandlung
](#JavaErrorHandling)
+ [

## AWS Anforderungs-ID
](#JavaRequestID)
+ [

## Protokollierung
](#JavaLogging)
+ [

## Paginierung
](#JavaPagination)
+ [

## Annotationen für Datenklassen
](#JavaDataClassAnnotation)

## Über die AWS SDK for Java 2.x
<a name="AboutProgrammingWithJavaSDK"></a>

Sie können von Java aus mit dem offiziellen auf DynamoDB zugreifen. AWS SDK für Java Das SDK für Java ist in zwei Versionen verfügbar: 1.x und 2.x. Das end-of-support für 1.x wurde am 12. Januar 2024 [angekündigt](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/). Es wird am 31. Juli 2024 in den Wartungsmodus wechseln und end-of-support ist am 31. Dezember 2025 fällig. Für neue Entwicklungen wird dringend empfohlen, Version 2.x zu verwenden, die erstmals 2018 veröffentlicht wurde. Dieses Handbuch richtet sich ausschließlich an Version 2.x und konzentriert sich auf die für DynamoDB relevanten Teile des SDK.

Informationen zu Wartung und Support für finden Sie in den AWS SDKs [Wartungsrichtlinien für AWS SDK und Tools sowie](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) in der [Matrix zur Unterstützung der Tools-Versionen](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) im Referenzhandbuch *AWS SDKs und im Tools-Referenzhandbuch*.AWS SDKs 

Das AWS SDK for Java 2.x ist eine grundlegende Neufassung der 1.x-Codebasis. Das SDK for Java 2.x unterstützt moderne Java-Funktionen, wie z. B. das in Java 8 I/O eingeführte Non-Blocking. Das SDK for Java 2.x bietet auch Unterstützung für steckbare HTTP-Client-Implementierungen, um mehr Flexibilität bei Netzwerkverbindungen und Konfigurationsoptionen zu bieten.

Eine bemerkenswerte Änderung zwischen dem SDK for Java 1.x und dem SDK for Java 2.x ist die Verwendung eines neuen Paketnamens. Das Java 1.x SDK verwendet den `com.amazonaws`-Paketnamen, während das Java 2.x SDK `software.amazon.awssdk` verwendet. In ähnlicher Weise verwenden Maven-Artefakte für das Java 1.x-SDK die `com.amazonaws`-`groupId`, während Java 2.x-SDK-Artefakte die `software.amazon.awssdk`-`groupId` verwenden.

**Wichtig**  
Die Version AWS SDK für Java 1.x hat ein DynamoDB-Paket namens. `com.amazonaws.dynamodbv2` Die „v2“ im Paketnamen bedeutet nicht, dass es für Java 2 (J2SE) ist. Vielmehr gibt „v2“ an, dass das Paket die [zweite Version](CurrentAPI.md) der DynamoDB-Low-Level-API anstelle der [ursprünglichen Version](Appendix.APIv20111205.md) der Low-Level-API unterstützt.

### Support für Java-Versionen
<a name="SupportedJavaVersions"></a>

[Das AWS SDK for Java 2.x bietet volle Unterstützung für Java-Releases mit langfristigem Support (LTS).](https://github.com/aws/aws-sdk-java-v2?tab=readme-ov-file#maintenance-and-support-for-java-versions)

## Erste Schritte mit dem AWS SDK for Java 2.x
<a name="GetStartedProgrammingWithJavaSDK"></a>

Das folgende Tutorial zeigt Ihnen, wie Sie [Apache Maven](https://maven.apache.org/) verwenden, um Abhängigkeiten für das SDK für Java 2.x zu definieren. Dieses Tutorial zeigt Ihnen auch, wie Sie den Code schreiben, der eine Verbindung zu DynamoDB herstellt, um die verfügbaren DynamoDB-Tabellen aufzulisten. Das Tutorial in diesem Handbuch basiert auf dem Tutorial [Erste Schritte mit dem AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*. Wir haben dieses Tutorial so überbearbeitet, dass DynamoDB statt Amazon S3 aufgerufen wird.

**Topics**
+ [

### Schritt 1: Einrichtung für dieses Tutorial
](#GetStartedJavaSetup)
+ [

### Schritt 2: Erstellen des Projekts
](#GetStartedJavaProjectSetup)
+ [

### Schritt 3: Schreiben des Codes
](#GetStartedJavaCode)
+ [

### Schritt 4: Anwendung erstellen und ausführen
](#GetStartedRunJava)

### Schritt 1: Einrichtung für dieses Tutorial
<a name="GetStartedJavaSetup"></a>

Bevor Sie mit diesem Tutorial beginnen, brauchen Sie Folgendes:
+ Berechtigung zum Zugriff auf DynamoDB.
+ Eine Java-Entwicklungsumgebung, die mit Single Sign-On-Zugriff für die AWS-Services AWS-Zugangsportal Verwendung von konfiguriert ist.

Folgen Sie zur Einrichtung dieses Tutorials den Anleitungen in der [Übersicht über die Einrichtung](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-overview) im *AWS SDK for Java 2.x -Entwicklerhandbuch*. Nachdem Sie [Ihre Entwicklungsumgebung mit Single Sign-On-Zugriff für das Java SDK konfiguriert](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials) haben und eine [aktive AWS -Access-Portal-Sitzung eingerichtet](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso) haben, fahren Sie mit [Schritt 2](#GetStartedJavaProjectSetup) dieses Tutorials fort.

### Schritt 2: Erstellen des Projekts
<a name="GetStartedJavaProjectSetup"></a>

Um das Projekt für dieses Tutorial zu erstellen, führen Sie einen Maven-Befehl aus, der Sie zur Eingabe der Konfiguration des Projekts auffordert. Nachdem alle Daten eingegeben und bestätigt wurden, beendet Maven den Aufbau des Projekts, indem es eine `pom.xml`-Datei und Stub-Java-Dateien erstellt.

1. Öffnen Sie ein Terminal oder ein Befehlszeilenfenster und navigieren Sie zu einem Verzeichnis Ihrer Wahl, z. B. zu Ihrem Ordner `Desktop` oder `Home`.

1. Geben Sie im Terminal folgenden Befehl ein und drücken Sie anschließend die **Eingabetaste**.

   ```
   mvn archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-app-quickstart \
      -DarchetypeVersion=2.22.0
   ```

1. Geben Sie für jede Prompt den in der zweiten Spalte aufgeführten Wert ein.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/ProgrammingWithJava.html)

1. Nachdem Sie den letzten Wert eingegeben haben, listet Maven die von Ihnen getroffenen Entscheidungen auf. Geben Sie zur Bestätigung **Y** ein. Oder geben Sie **N** ein und geben Sie dann Ihre Auswahl erneut ein.

Maven erstellt einen Projektordner namens `getstarted`, der auf dem von Ihnen eingegebenen `artifactId`-Wert basiert. Suchen Sie im `getstarted`-Ordners nach einer Datei namens `README.md`, die Sie überprüfen können, nach einer `pom.xml`-Datei und einem `src`-Verzeichnis.

Maven erstellt den folgenden Verzeichnisbaum.

```
getstarted
 ├── README.md
 ├── pom.xml
 └── src
     ├── main
     │   ├── java
     │   │   └── org
     │   │       └── example
     │   │           ├── App.java
     │   │           ├── DependencyFactory.java
     │   │           └── Handler.java
     │   └── resources
     │       └── simplelogger.properties
     └── test
         └── java
             └── org
                 └── example
                     └── HandlerTest.java
 
 10 directories, 7 files
```

Unten sehen Sie die Inhalte der `pom.xml`-Projektdatei.

#### `pom.xml`
<a name="ProjectSetupCollapse2"></a>

Der `dependencyManagement`-Abschnitt enthält eine Abhängigkeit von AWS SDK for Java 2.x, und der `dependencies`-Abschnitt enthält eine Abhängigkeit für DynamoDB. Die Angabe dieser Abhängigkeiten zwingt Maven, die entsprechenden `.jar`-Dateien in Ihren Java-Klassenpfad aufzunehmen. Standardmäßig enthält das AWS SDK nicht alle Klassen für alle AWS-Services. Wenn Sie die Low-Level-Schnittstelle für DynamoDB verwenden, sollte eine Abhängigkeit vom `dynamodb`-Artefakt vorhanden sein. Wenn Sie die High-Level-Schnittstelle verwenden, eine Abhängigkeit für den `dynamodb-enhanced`-Artefakt. Sollten Sie die relevanten Abhängigkeiten nicht angeben, kann Ihr Code nicht kompiliert werden. Das Projekt verwendet Java 1.8 aufgrund des `1.8`-Werts in den `maven.compiler.source`- und `maven.compiler.target`-Eigenschaften.

```
<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.example</groupId>
     <artifactId>getstarted</artifactId>
     <version>1.0-SNAPSHOT</version>
     <packaging>jar</packaging>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
         <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
         <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
         <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
         <aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version.
         <slf4j.version>1.7.28</slf4j.version>
         <junit5.version>5.8.1</junit5.version>
     </properties>
 
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>software.amazon.awssdk</groupId>
                 <artifactId>bom</artifactId>
                 <version>${aws.java.sdk.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>
 
     <dependencies>
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>dynamodb</artifactId>  <-------- DynamoDB dependency
             <exclusions>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>netty-nio-client</artifactId>
                 </exclusion>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>apache-client</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>sso</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>apache-client</artifactId> <-------- HTTP client specified.
             <exclusions>
                 <exclusion>
                     <groupId>commons-logging</groupId>
                     <artifactId>commons-logging</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
         ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>jcl-over-slf4j</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Test Dependencies -->
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <version>${junit5.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>${maven.compiler.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
 
 </project>
```

### Schritt 3: Schreiben des Codes
<a name="GetStartedJavaCode"></a>

Der folgende Code zeigt die `App`-Klasse, die von Maven erstellt wird. Die `main`-Methode ist der Einstiegspunkt in die Anwendung, die eine Instance der `Handler`-Klasse erstellt und dann ihre `sendRequest`-Methode aufruft.

#### `App`-Klasse
<a name="projectsetup-collapse2"></a>

```
package org.example;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class App {
     private static final Logger logger = LoggerFactory.getLogger(App.class);
 
     public static void main(String... args) {
         logger.info("Application starts");
 
         Handler handler = new Handler();
         handler.sendRequest();
 
         logger.info("Application ends");
     }
 }
```

Die `DependencyFactory`-Klasse, die Maven erstellt, enthält die `dynamoDbClient`-Factory-Methode, die eine [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)-Instance erstellt und zurückgibt. Die `DynamoDbClient`-Instance verwendet eine Instance des Apache-basierten HTTP-Clients. Dies liegt daran, dass Sie `apache-client` angegeben haben, als Maven Sie nach dem zu verwendenden HTTP-Client gefragt hat.

Der folgende Code zeigt die Klasse `DependencyFactory`.

#### DependencyFactory Klasse
<a name="code-collapse2"></a>

```
package org.example;
 
 import software.amazon.awssdk.http.apache.ApacheHttpClient;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 /**
  * The module containing all dependencies required by the {@link Handler}.
  */
 public class DependencyFactory {
 
     private DependencyFactory() {}
 
     /**
      * @return an instance of DynamoDbClient
      */
     public static DynamoDbClient dynamoDbClient() {
         return DynamoDbClient.builder()
                        .httpClientBuilder(ApacheHttpClient.builder())
                        .build();
     }
 }
```

Die `Handler`-Klasse enthält die Hauptlogik Ihres Programms. Wenn eine Instance von `Handler` in der Klasse `App` erstellt wird, stellt `DependencyFactory` den Service-Client für `DynamoDbClient` bereit. Ihr Code verwendet die `DynamoDbClient`-Instance, um DynamoDB aufzurufen.

Maven generiert die folgende `Handler`-Klasse mit einem `TODO`-Kommentar. Der nächste Schritt im Tutorial ersetzt den *`TODO`*-Kommentar durch Code.

#### `Handler`-Klasse, von Maven generiert
<a name="code-collapsible3"></a>

```
package org.example;
 
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         // TODO: invoking the API calls using dynamoDbClient.
     }
 }
```

Um die Logik zu ergänzen, ersetzen Sie den gesamten Inhalt der Klasse `Handler` durch den folgenden Code: Die Methode `sendRequest` ist vollständig implementiert, und die erforderlichen Importe werden hinzugefügt.

#### `Handler`-Klasse, implementiert
<a name="code-collapse4"></a>

Der folgende Code verwendet die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)-Instance, um eine Liste vorhandener Tabellen abzurufen. Wenn Tabellen für ein bestimmtes Konto und eine bestimmte AWS-Region vorhanden sind, verwendet der Code die `Logger`-Instance, um die Namen dieser Tabellen zu protokollieren.

```
package org.example;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         Logger logger = LoggerFactory.getLogger(Handler.class);
 
         logger.info("calling the DynamoDB API to get a list of existing tables");
         ListTablesResponse response = dynamoDbClient.listTables();
 
         if (!response.hasTableNames()) {
             logger.info("No existing tables found for the configured account & region");
         } else {
             response.tableNames().forEach(tableName -> logger.info("Table: " + tableName));
         }
     }
 }
```

### Schritt 4: Anwendung erstellen und ausführen
<a name="GetStartedRunJava"></a>

Nachdem Sie das Projekt erstellt haben und es die komplette `Handler`-Klasse enthält, erstellen Sie die Anwendung und führen Sie sie aus.

1. Stellen Sie sicher, dass Sie eine aktive AWS IAM Identity Center Sitzung haben. Zur Bestätigung führen Sie den AWS Command Line Interface (AWS CLI)-Befehl `aws sts get-caller-identity` aus und prüfen das Ergebnis: Wenn Sie keine aktive Sitzung haben, finden Sie weitere Anleitungen unter [Anmelden mit dem AWS CLI](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso).

1. Öffnen Sie ein Terminal- oder ein Befehlszeilenfenster und navigieren Sie zu Ihrem Projektverzeichnis `getstarted`.

1. Mit dem folgenden Befehl erstellen Sie nun Ihr Projekt:

   ```
   mvn clean package
   ```

1. Um die Anwendung auszuführen, führen Sie den folgenden Befehl aus:

   ```
   mvn exec:java -Dexec.mainClass="org.example.App"
   ```

Nachdem Sie die Datei angezeigt haben, löschen Sie das Objekt und anschließend den Bucket.

#### Herzlichen Glückwunsch
<a name="GetStartedSuccessJava"></a>

Wenn Ihr Maven-Projekt ohne Fehler erstellt und ausgeführt wurde, dann herzlichen Glückwunsch\$1 Sie haben erfolgreich Ihre erste Java-Anwendung mit dem SDK for Java 2.x erstellt.

#### Bereinigen
<a name="GetStartedCleanupJava"></a>

Um die während dieses Tutorials erstellten Ressourcen zu bereinigen, löschen Sie den Projektordner `getstarted`.

## Überprüfung der AWS SDK for Java 2.x Dokumentation
<a name="ProgrammingWithJavaUseDoc"></a>

Das [AWS SDK for Java 2.x -Entwicklerhandbuch](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) deckt alle Aspekte des SDK in allen AWS-Services ab. Wir empfehlen, dass Sie sich mit den folgenden Themen vertraut machen:
+ [Migration von Version 1.x auf 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) – Enthält eine ausführliche Erläuterung der Unterschiede zwischen 1.x und 2.x. Dieses Thema enthält auch Anweisungen zur Verwendung der beiden Hauptversionen side-by-side.
+ [DynamoDB-Handbuch für Java 2.x SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb.html) – Zeigt Ihnen, wie Sie grundlegende DynamoDB-Operationen ausführen: Erstellen einer Tabelle, Bearbeiten von Elementen und Abrufen von Elementen. In diesen Beispielen hier verwenden wir die Low-Level-Schnittstelle. Java hat mehrere Schnittstellen, wie im folgenden Abschnitt erläutert werden: [Unterstützte Schnittstellen](#JavaInterfaces).

**Tipp**  
Nachdem Sie sich mit diesen Themen befasst haben, setzen Sie ein Lesezeichen für die [AWS SDK for Java 2.x API-Referenz](https://sdk.amazonaws.com/java/api/latest/). Es deckt alles ab AWS-Services, und wir empfehlen, dass Sie es als Haupt-API-Referenz verwenden.

## Unterstützte Schnittstellen
<a name="JavaInterfaces"></a>

Die AWS SDK for Java 2.x unterstützt die folgenden Schnittstellen, abhängig von der gewünschten Abstraktionsebene.

**Topics**
+ [

### Low-Level-Schnittstelle
](#LowLevelInterface)
+ [

### High-Level-Schnittstelle
](#HighLevelInterface)
+ [

### Dokumentschnittstelle
](#DocumentInterface)
+ [

### Vergleichen von Schnittstellen anhand eines `Query`-Beispiels
](#CompareJavaInterfacesQueryEx)

### Low-Level-Schnittstelle
<a name="LowLevelInterface"></a>

Die Low-Level-Schnittstelle bietet eine one-to-one Zuordnung zur zugrunde liegenden Service-API. Jede DynamoDB-API ist über diese Schnittstelle verfügbar. Das bedeutet, dass die Low-Level-Schnittstelle vollständige Funktionalität bieten kann, aber häufig ausführlicher und komplexer in der Anwendung ist. Beispielsweise müssen Sie die `.s()`-Funktionen zum Speichern von Zeichenketten, und die `.n()`-Funktionen zum Speichern von Zahlen verwenden. Im folgenden Beispiel wird ein Element mithilfe der Low-Level-Schnittstelle [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)eingefügt.

```
import org.slf4j.*;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class PutItem {

    // Create a DynamoDB client with the default settings connected to the DynamoDB
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.create();
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemResponse response = DYNAMODB_CLIENT.putItem(PutItemRequest.builder()
                .item(Map.of(
                        "pk", AttributeValue.builder().s("123").build(),
                        "sk", AttributeValue.builder().s("cart#123").build(),
                        "item_data", AttributeValue.builder().s("YourItemData").build(),
                        "inventory", AttributeValue.builder().n("500").build()
                        // ... more attributes ...
                ))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .tableName("YourTableName")
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

### High-Level-Schnittstelle
<a name="HighLevelInterface"></a>

Die High-Level-Schnittstelle im AWS SDK for Java 2.x wird als DynamoDB Enhanced Client bezeichnet. Diese Schnittstelle ermöglicht eine idiomatischere und natürlichere Programmerfahrung.

Der erweiterte Client bietet eine Möglichkeit, clientseitige Datenklassen mit den dafür vorgesehenen DynamoDB-Tabellen zu verknüpfen. Sie definieren die Beziehungen zwischen Tabellen und ihren jeweiligen Modellklassen im Code. Anschließend können Sie sich darauf verlassen, dass das SDK die Umwandlung der Datentypen übernimmt. Weitere Informationen zum erweiterten Client finden Sie unter [API für den erweiterten DynamoDB-Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

Im folgenden Beispiel wird die High-Level-Schnittstelle [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)verwendet. In diesem Beispiel erstellt die `DynamoDbBean` mit dem Namen `YourItem` ein `TableSchema`, das ihre direkte Verwendung als Eingabe für den `putItem()`-Aufruf ermöglicht.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourItem.class)
                .item(new YourItem("123", "cart#123", "YourItemData", 500))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String itemData, int inventory) {
            this.pk = pk;
            this.sk = sk;
            this.itemData = itemData;
            this.inventory = inventory;
        }

        private String pk;
        private String sk;
        private String itemData;

        private int inventory;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

        public void setItemData(String itemData) {
            this.itemData = itemData;
        }

        public String getItemData() {
            return itemData;
        }

        public void setInventory(int inventory) {
            this.inventory = inventory;
        }

        public int getInventory() {
            return inventory;
        }
    }
}
```

Die AWS SDK für Java Version 1.x hat ihre eigene High-Level-Schnittstelle, die oft mit ihrer Hauptklasse `DynamoDBMapper` bezeichnet wird. Das AWS SDK for Java 2.x wird in einem separaten Paket (und einem Maven-Artefakt) mit dem Namen veröffentlicht. `software.amazon.awssdk.enhanced.dynamodb` Das Java SDK 2.x wird oft über seine Hauptklasse `DynamoDbEnhancedClient` referenziert.

#### High-Level-Schnittstelle mit unveränderlichen Datenklassen
<a name="HighLevelInterfaceImmutableDataClasses"></a>

Die Mapping-Funktion der erweiterten DynamoDB-Client-API funktioniert auch mit unveränderlichen Datenklassen. Eine unveränderliche Klasse hat nur Getter und erfordert eine Builder-Klasse, die das SDK verwendet, um Instances der Klasse zu erstellen. Unveränderlichkeit ist ein in Java häufig verwendeter Programmierstil, mit dem Entwickler Klassen erstellen können, die keine Nebeneffekte verursachen. Solche Klassen verhalten sich in komplexen, nebenläufigen Anwendungen vorhersehbarer. Anstelle der Annotation `@DynamoDbBean`, wie im Beispiel zur [High-level interface example](#highleveleg) gezeigt, verwenden unveränderliche Klassen die `@DynamoDbImmutable`-Annotation, die die zugehörige Builder-Klasse als Eingabe erhält.

Im folgenden Beispiel wird die Builder-Klasse `DynamoDbEnhancedClientImmutablePutItem` als Eingabe verwendet, um ein Tabellenschema zu erstellen. Das Beispiel stellt dann das Schema als Eingabe für den [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)API-Aufruf bereit.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutablePutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutablePutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableItem.class)
                .item(YourImmutableItem.builder()
                                        .pk("123")
                                        .sk("cart#123")
                                        .itemData("YourItemData")
                                        .inventory(500)
                                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

Im folgenden Beispiel wird die unveränderliche Datenklasse gezeigt.

```
@DynamoDbImmutable(builder = YourImmutableItem.YourImmutableItemBuilder.class)
class YourImmutableItem {
    private final String pk;
    private final String sk;
    private final String itemData;
    private final int inventory;
    public YourImmutableItem(YourImmutableItemBuilder builder) {
        this.pk = builder.pk;
        this.sk = builder.sk;
        this.itemData = builder.itemData;
        this.inventory = builder.inventory;
    }

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

    @DynamoDbPartitionKey
    public String getPk() {
        return pk;
    }

    @DynamoDbSortKey
    public String getSk() {
        return sk;
    }

    public String getItemData() {
        return itemData;
    }

    public int getInventory() {
        return inventory;
    }

    static final class YourImmutableItemBuilder {
        private String pk;
        private String sk;
        private String itemData;
        private int inventory;

        private YourImmutableItemBuilder() {}

        public YourImmutableItemBuilder pk(String pk) { this.pk = pk; return this; }
        public YourImmutableItemBuilder sk(String sk) { this.sk = sk; return this; }
        public YourImmutableItemBuilder itemData(String itemData) { this.itemData = itemData; return this; }
        public YourImmutableItemBuilder inventory(int inventory) { this.inventory = inventory; return this; }

        public YourImmutableItem build() { return new YourImmutableItem(this); }
    }
}
```

#### High-Level-Schnittstelle mit unveränderlichen Datenklassen und externen Bibliotheken zur Generierung von Boilerplate-Code
<a name="ImmutableDataClassesThirdPartyBoilerplateGenLib"></a>

Unveränderliche Datenklassen (wie im vorherigen Beispiel gezeigt) erfordern etwas Boilerplate-Code. Beispielsweise die Getter- und Setter-Logik in den Datenklassen sowie zugehörige `Builder`-Klassen. Externe Bibliotheken wie [Project Lombok](https://projectlombok.org/) können dabei helfen, diese Art von Boilerplate-Code zu generieren. Wenn Sie den Großteil des Standardcodes reduzieren, können Sie die Menge an Code einschränken, die für die Arbeit mit unveränderlichen Datenklassen und dem SDK benötigt wird. AWS Dies führt zu höherer Produktivität und verbessert die Lesbarkeit Ihres Codes. Weitere Informationen finden Sie unter [Verwenden von externen Bibliotheken wie Lombok](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-use-immut.html#ddb-en-client-use-immut-lombok) im *-Entwicklerhandbuch.*

Im folgenden Beispiel wird gezeigt, wie Project Lombok den Code vereinfacht, der für die Nutzung der erweiterten DynamoDB-Client-API erforderlich ist.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutableLombokPutItem {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableLombokItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableLombokItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutableLombokPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableLombokItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableLombokItem.class)
                .item(YourImmutableLombokItem.builder()
                        .pk("123")
                        .sk("cart#123")
                        .itemData("YourItemData")
                        .inventory(500)
                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

Das folgende Beispiel zeigt das unveränderliche Datenobjekt der unveränderlichen Datenklasse.

```
import lombok.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;

@Builder
@DynamoDbImmutable(builder = YourImmutableLombokItem.YourImmutableLombokItemBuilder.class)
@Value
public class YourImmutableLombokItem {

    @Getter(onMethod_=@DynamoDbPartitionKey)
    String pk;
    @Getter(onMethod_=@DynamoDbSortKey)
    String sk;
    String itemData;
    int inventory;
}
```

Die `YourImmutableLombokItem` Klasse verwendet die folgenden Anmerkungen, die Project Lombok und das SDK bereitstellen: AWS 
+ [@Builder](https://projectlombok.org/features/Builder) — Produziert einen komplexen Builder APIs für Datenklassen, den Project Lombok bereitstellt.
+ [@ DynamoDbImmutable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/DynamoDbImmutable.html) — Identifiziert die `DynamoDbImmutable` Klasse als eine vom SDK DynamoDB DynamoDB-Annotation für zuordenbare Entitäten. AWS 
+ [@Value](https://projectlombok.org/features/Value) – Die unveränderliche Variante von `@Data`. Standardmäßig sind alle Felder privat und endgültig, und es werden keine Setter generiert. Project Lombok stellt diese Annotation zur Verfügung.

### Dokumentschnittstelle
<a name="DocumentInterface"></a>

Die AWS SDK for Java 2.x Document-Schnittstelle macht die Angabe von Datentypdeskriptoren überflüssig. Die Datentypen ergeben sich aus der Semantik der Daten selbst. Diese Dokumentschnittstelle ähnelt der Dokumentschnittstelle von AWS SDK für Java 1.x, verfügt jedoch über eine neu gestaltete Oberfläche.

Im Folgenden [Document interface example](#DocInterfaceEg) wird der über die Dokumentschnittstelle ausgedrückte `PutItem`-Aufruf dargestellt. Das Beispiel verwendet auch. EnhancedDocument Um Befehle gegen eine DynamoDB-Tabelle mit der erweiterten Dokument-API auszuführen, müssen Sie die Tabelle zunächst mit Ihrem Dokumenttabellenschema verknüpfen, um ein `DynamoDBTable`-Ressourcenobjekt zu erstellen. Der Tabellenschema-Builder für Dokumente erfordert den Primärschlüssel des Indexes sowie Anbieter für Attributkonverter.

Sie können `AttributeConverterProvider.defaultProvider()` verwenden, um Dokumentattribute mit Standardtypen zu konvertieren. Das allgemeine Standardverhalten lässt sich durch eine benutzerdefinierte `AttributeConverterProvider`-Implementierung ändern. Ebenso können Sie den Konverter für ein einzelnes Attribut anpassen. Das [AWS SDKs Referenzhandbuch zu Tools](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) enthält weitere Details und Beispiele zur Verwendung benutzerdefinierter Konverter. Ihr Hauptzweck besteht darin, Attribute Ihrer Domänenklassen zu unterstützen, für die kein Standardkonverter verfügbar ist. Mit einem benutzerdefinierten Konverter können Sie dem SDK die nötigen Informationen bereitstellen, um Daten in DynamoDB zu schreiben oder daraus zu lesen.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedDocumentClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                            .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                            .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                            .build());

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<EnhancedDocument> response = DYNAMODB_TABLE.putItemWithResponse(
                        PutItemEnhancedRequest.builder(EnhancedDocument.class)
                                .item(
                                    EnhancedDocument.builder()
                                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                                            .putString("pk", "123")
                                            .putString("sk", "cart#123")
                                            .putString("item_data", "YourItemData")
                                            .putNumber("inventory", 500)
                                            .build())
                                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

}
```

Um JSON-Dokumente in native Amazon-DynamoDB-Datentypen zu konvertieren und umgekehrt, können Sie die folgenden Hilfsmethoden verwenden:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String))— Erzeugt eine neue EnhancedDocument Instanz aus einer JSON-Zeichenfolge.
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()) – Erstellt eine JSON-Zeichenfolgendarstellung des Dokuments, die Sie in Ihrer Anwendung wie jedes andere JSON-Objekt verwenden können.

### Vergleichen von Schnittstellen anhand eines `Query`-Beispiels
<a name="CompareJavaInterfacesQueryEx"></a>

Dieser Abschnitt zeigt den gleichen [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)-Aufruf, der über die verschiedenen Schnittstellen ausgedrückt wird. Beachten Sie Folgendes, um die Ergebnisse dieser Abfragen zu optimieren:
+ DynamoDB zielt auf einen bestimmten Partitionsschlüsselwert ab; daher müssen Sie den Partitionsschlüssel vollständig angeben.
+ Damit die Abfrage ausschließlich auf Warenkorbelemente abzielt, verwendet der Sortierschlüssel einen Schlüsselbedingungsausdruck mit `begins_with`.
+ Wir verwenden `limit()`, um die Abfrage auf maximal 100 zurückgegebene Elemente zu beschränken.
+ Wir haben das `scanIndexForward` auf false gesetzt. Die Ergebnisse werden in der Reihenfolge der UTF-8-Bytes zurückgegeben, was normalerweise bedeutet, dass das Warenkorbelement mit der niedrigsten Nummer zuerst zurückgegeben wird. Indem wir nun `scanIndexForward` auf false setzen, kehren wir die Reihenfolge um, sodass das Warenkorbelement mit der höchsten Nummer zuerst zurückgegeben wird.
+ Wir wenden einen Filter an, um alle Ergebnisse zu entfernen, die nicht den Kriterien entsprechen. Die gefilterten Daten verbrauchen Lesekapazität, unabhängig davon, ob das Element dem Filter entspricht oder nicht.

**Example `Query` unter Verwendung der Low-Level-Schnittstelle**  
Das folgende Beispiel fragt eine Tabelle mit dem Namen `YourTableName` unter Verwendung eines `keyConditionExpression` ab. Dadurch wird die Abfrage auf einen bestimmten Partition-Key-Wert und einen Sortierschlüsselwert beschränkt, die mit einem bestimmten Präfix beginnen. Diese Schlüsselbedingungen begrenzen die Menge der aus DynamoDB gelesenen Daten. Abschließend wird ein Filter auf die aus DynamoDB abgerufenen Daten angewendet, indem eine `filterExpression` verwendet wird.  

```
import org.slf4j.*;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class Query {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.builder().build();
    private static final Logger LOGGER = LoggerFactory.getLogger(Query.class);

    private static void query() {
        QueryResponse response = DYNAMODB_CLIENT.query(QueryRequest.builder()
                .expressionAttributeNames(Map.of("#name", "name"))
                .expressionAttributeValues(Map.of(
                    ":pk_val", AttributeValue.fromS("id#1"),
                    ":sk_val", AttributeValue.fromS("cart#"),
                    ":name_val", AttributeValue.fromS("SomeName")))
                .filterExpression("#name = :name_val")
                .keyConditionExpression("pk = :pk_val AND begins_with(sk, :sk_val)")
                .limit(100)
                .scanIndexForward(false)
                .tableName("YourTableName")
                .build());

        LOGGER.info("nr of items: " + response.count());
        LOGGER.info("First item pk: " + response.items().get(0).get("pk"));
        LOGGER.info("First item sk: " + response.items().get(0).get("sk"));
    }
}
```

**Example `Query` unter Verwendung der Dokumentschnittstelle**  
Das folgende Beispiel fragt eine Tabelle mit dem Namen `YourTableName` unter Verwendung der Dokumentschnittstelle ab.  

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;

import java.util.Map;

public class DynamoDbEnhancedDocumentClientQuery {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                    .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                    .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                    .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                    .build());
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientQuery.class);

    private void query() {
        PageIterable<EnhancedDocument> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getString("pk"));
        LOGGER.info("First item sk: " + response.items().iterator().next().getString("sk"));

    }
}
```

**Example `Query` unter Verwendung der High-Level-Schnittstelle**  
Im folgenden Beispiel wird eine Abfrage auf einer Tabelle mit dem Namen `YourTableName` unter Verwendung der erweiterten DynamoDB-Client-API durchgeführt.  

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

import java.util.Map;

public class DynamoDbEnhancedClientQuery {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(DynamoDbEnhancedClientQuery.YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientQuery.class);

    private void query() {
        PageIterable<YourItem> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getPk());
        LOGGER.info("First item sk: " + response.items().iterator().next().getSk());
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String name) {
            this.pk = pk;
            this.sk = sk;
            this.name = name;
        }

        private String pk;
        private String sk;
        private String name;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

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

        public String getName() {
            return name;
        }
    }
}
```
**High-Level-Schnittstelle mit unveränderlichen Datenklassen**  
Wenn Sie eine `Query` mit unveränderlichen Datenklassen durchführen, entspricht der Code dem Beispiel für die High-Level-Schnittstelle; die Konstruktion der Entitätsklasse `YourItem` oder `YourImmutableItem` ist jedoch anders. Weitere Informationen finden Sie im [PutItem](#HighLevelImmutableDataClassEg)Beispiel.
**High-Level-Schnittstelle mit unveränderlichen Datenklassen und externen Bibliotheken zur Generierung von Boilerplate-Code**  
Wenn Sie eine `Query` mit unveränderlichen Datenklassen durchführen, entspricht der Code dem Beispiel für die High-Level-Schnittstelle; die Konstruktion der Entitätsklasse `YourItem` oder `YourImmutableLombokItem` ist jedoch anders. Weitere Informationen finden Sie im [PutItem](#HighLevelImmutableDataClassEg)Beispiel.

## Weitere Codebeispiele
<a name="AdditionalCodeEx"></a>

Weitere Beispiele zur Verwendung von DynamoDB mit dem AWS SDK für Java 2.x finden Sie in den folgenden Codebeispiel-Repositories:
+ [Offizielle AWS -Single-Action-Codebeispiele](https://docs.aws.amazon.com/code-library/latest/ug/java_2_dynamodb_code_examples.html)
+ [Von der Community verwaltete Beispiele für Single-Action-Codes](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)
+ [Offizielle AWS szenarioorientierte Codebeispiele](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)

## Synchrone und asynchrone Programmierung
<a name="SyncAsyncProgramming"></a>

Der AWS SDK for Java 2.x bietet sowohl *synchrone* als auch *asynchrone* Clients für AWS-Services, z. B. DynamoDB.

Die Klassen `DynamoDbClient` und `DynamoDbEnhancedClient` bieten synchrone Methoden, die die Ausführung Ihres Threads blockieren, bis der Client eine Antwort vom Service erhält. Dieser Client ist die einfachste Möglichkeit, mit DynamoDB zu arbeiten, wenn Sie keine asynchronen Operationen benötigen.

Die Klassen `DynamoDbAsyncClient` und `DynamoDbEnhancedAsyncClient` bieten asynchrone Methoden, die sofort reagieren und die Kontrolle an den aufrufenden Thread zurückgeben, ohne auf eine Antwort zu warten. Der nicht-blockierende Client hat den Vorteil, dass er bei hoher Parallelität über wenige Threads effizient mit I/O-Anfragen umgehen kann und dabei nur minimale Rechenressourcen benötigt. Dies verbessert den Durchsatz und die Reaktionsfähigkeit.

Der AWS SDK for Java 2.x verwendet die native Unterstützung für nicht blockierende I/O. Die Version AWS SDK für Java 1.x musste nicht blockierende I/O simulieren.

Die synchronen Methoden reagieren, bevor eine Antwort verfügbar ist. Daher benötigen Sie eine Möglichkeit, die Antwort zu erhalten, sobald sie bereitsteht. Die asynchronen Methoden AWS SDK für Java geben ein [https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)Objekt zurück, das die Ergebnisse der asynchronen Operation in der future enthält. Wenn Sie `get()` oder `join()` auf diesen `CompletableFuture`-Objekten aufrufen, blockiert Ihr Code, bis das Ergebnis verfügbar ist. Wenn Sie diese Methoden gleichzeitig mit der Anfrage aufrufen, verhält sich der Code ähnlich wie bei einem normalen synchronen Aufruf.

Weitere Informationen zur asynchronen Programmierung finden Sie unter [Verwenden der asynchronen Programmierung](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

## HTTP-Clients
<a name="HttpClients"></a>

Zur Unterstützung jedes Clients gibt es einen HTTP-Client, der die Kommunikation mit den AWS-Servicesübernimmt. Sie können alternative HTTP-Clients einbinden und dabei denjenigen auswählen, der am besten zu den Anforderungen Ihrer Anwendung passt. Einige sind besonders ressourcenschonend, andere bieten umfangreiche Konfigurationsmöglichkeiten.

Einige HTTP-Clients unterstützen ausschließlich die synchrone Nutzung, während andere nur für die asynchrone Verwendung geeignet sind. Ein Diagramm, das Ihnen bei der Auswahl des optimalen HTTP-Clients für Ihre Workload hilft, finden Sie unter [Empfehlungen zu HTTP-Clients](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html#http-clients-recommend) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

In der folgenden Liste sehen Sie einige der möglichen HTTP-Clients:

**Topics**
+ [

### Apache-basierter HTTP-Client
](#ApacheHttpClient)
+ [

### `URLConnection`-basierter HTTP-Client
](#URLConnHttpClient)
+ [

### Netty-basierter HTTP-Client
](#NettyHttpClient)
+ [

### AWS CRT-basierter HTTP-Client
](#AWSCRTHttpClient)

### Apache-basierter HTTP-Client
<a name="ApacheHttpClient"></a>

Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html)-Klasse unterstützt synchrone Service-Clients. Dies ist der Standard-HTTP-Client für die synchrone Verwendung. Weitere Informationen zum Konfigurieren der `ApacheHttpClient`-Klasse finden Sie unter [Konfigurieren des Apache-basierten HTTP-Clients](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-apache.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

### `URLConnection`-basierter HTTP-Client
<a name="URLConnHttpClient"></a>

Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html)-Klasse ist eine weitere Option für synchrone Clients. Sie lädt schneller als der Apache-basierte HTTP-Client, bietet jedoch weniger Funktionen. Informationen zur Konfiguration der `UrlConnectionHttpClient` Klasse finden [Sie unter Configure the URLConnection -based HTTP-Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-url.html) im *AWS SDK for Java 2.x Developer* Guide.

### Netty-basierter HTTP-Client
<a name="NettyHttpClient"></a>

Die `NettyNioAsyncHttpClient`-Klasse unterstützt asynchrone Clients. Dies ist die Standardauswahl für die asynchrone Verwendung. Weitere Informationen zum Konfigurieren der `NettyNioAsyncHttpClient`-Klasse finden Sie unter [Konfigurieren des Netty-basierten HTTP-Clients](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-netty.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

### AWS CRT-basierter HTTP-Client
<a name="AWSCRTHttpClient"></a>

Die neueren `AwsCrtAsyncHttpClient` Klassen `AwsCrtHttpClient` und Klassen aus den AWS Common Runtime (CRT) -Bibliotheken sind weitere Optionen, die synchrone und asynchrone Clients unterstützen. Im Vergleich zu anderen HTTP-Clients bietet CRT: AWS 
+ Schnellere SDK-Startup-Zeiten
+ Geringeren Speicherbedarf
+ Reduzierte Latenzzeit
+ Verbindungsgesundheitsverwaltung
+ DNS-Load Balancing

*Informationen zur Konfiguration der `AwsCrtAsyncHttpClient` Klassen `AwsCrtHttpClient` und finden [Sie unter Konfiguration der AWS CRT-basierten HTTP-Clients im AWS SDK for Java 2.x Entwicklerhandbuch](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html).*

Der AWS CRT-basierte HTTP-Client ist nicht der Standard, da dies die Abwärtskompatibilität vorhandener Anwendungen beeinträchtigen würde. Für DynamoDB empfehlen wir jedoch, den AWS CRT-basierten HTTP-Client sowohl für synchrone als auch asynchrone Zwecke zu verwenden.

*Eine Einführung in den AWS CRT-basierten HTTP-Client finden Sie unter [Ankündigung der Verfügbarkeit des CRT-HTTP-Clients im Developer AWS Tools-Blog](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/). AWS SDK for Java 2.xAWS *

## Konfigurieren eines HTTP-Clients
<a name="ConfigHttpClient"></a>

Beim Konfigurieren eines Clients können Sie verschiedene Konfigurationsoptionen angeben, darunter:
+ Timeouts für verschiedene Aspekte von API-Aufrufen.
+ Aktivieren des TCP-Keepalives.
+ Steuerung der Wiederholungsrichtlinie bei Fehlern.
+ Festlegen von Ausführungsattributen, die von [Execution Interceptor](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/interceptors.html)-Instances verändert werden können. Execution Interceptors können Code schreiben, der die Ausführung Ihrer API-Anfragen und -Antworten abfängt. Auf diese Weise können Sie Aufgaben wie das Veröffentlichen von Metriken und das Ändern von Anfragen während der Übertragung ausführen.
+ Hinzufügen oder Bearbeiten von HTTP-Headern.
+ Aktivieren der Nachverfolgung von [Leistungskennzahlen auf Client-Seite](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html). Mithilfe dieser Funktion können Sie Metriken über die Service-Clients in Ihrer Anwendung sammeln und die Ergebnisse in Amazon analysieren CloudWatch.
+ Festlegen eines alternativen Executor-Service für die Planung von Aufgaben wie asynchrone Wiederholungsversuche und Timeout.

Sie steuern die Konfiguration, indem Sie der Service-Client-Klasse `Builder` ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html)-Objekt bereitstellen. Sie werden dies in einigen Codebeispielen in den folgenden Abschnitten sehen.

`ClientOverrideConfiguration` bietet Standardkonfigurationsoptionen. Die verschiedenen einsteckbaren HTTP-Clients verfügen zusätzlich über implementierungsspezifische Optionen.

**Topics**
+ [

### Timeout-Konfiguration
](#TimeoutConfig)
+ [

### RetryMode
](#RetryMode)
+ [

### DefaultsMode
](#DefaultsMode)
+ [

### Keepalive-Konfigurierung
](#KeepAliveConfig)

### Timeout-Konfiguration
<a name="TimeoutConfig"></a>

Sie können die Client-Konfiguration anpassen, um verschiedene Timeout-Einstellungen für Serviceaufrufe zu steuern. DynamoDB im Vergleich zu anderen AWS-Services geringere Latenzen. Darum empfiehlt es sich, diese Eigenschaften auf niedrigere Timeout-Werte zu setzen, um bei Netzwerkproblemen schnell zu reagieren.

Das latenzbezogene Verhalten lässt sich entweder über `ClientOverrideConfiguration` am DynamoDB-Client oder durch detaillierte Einstellungen am zugrunde liegenden HTTP-Client vornehmen.

Folgende wichtige Eigenschaften können über `ClientOverrideConfiguration` konfiguriert werden:
+ `apiCallAttemptTimeout` – Die maximale Zeitspanne, die für einen einzelnen Versuch eines HTTP-Requests gewartet wird, bevor abgebrochen und ein Timeout ausgelöst wird.
+ `apiCallTimeout` – Die Gesamtzeit, die dem Client zur Verfügung steht, um einen vollständigen API-Aufruf auszuführen. Dies umfasst die Ausführung des Request-Handlers, der alle HTTP-Anfragen einschließlich Wiederholungsversuchen beinhaltet.

Das AWS SDK for Java 2.x bietet [Standardwerte](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) für einige Timeout-Optionen, wie Verbindungs-Timeout und Socket-Timeouts. Das SDK bietet keine Standardwerte für Timeouts bei API-Aufrufen oder Timeouts für einzelne API-Aufrufversuche. Wenn diese Timeouts nicht explizit in der `ClientOverrideConfiguration` gesetzt werden, verwendet das SDK stattdessen den Socket-Timeout-Wert als Gesamtzeitlimit für den API-Aufruf. Der Standardwert für den Socket-Timeout beträgt 30 Sekunden.

### RetryMode
<a name="RetryMode"></a>

Eine weitere Einstellung im Zusammenhang mit der Timeout-Konfiguration, die Sie berücksichtigen sollten, ist das Konfigurationsobjekt `RetryMode`. Dieses Konfigurationsobjekt enthält eine Sammlung von Wiederholungsverhalten.

Das SDK for Java 2.x unterstützt die folgenden Wiederholungsmodi:
+ `legacy` – Der standardmäßige Wiederholungsmodus, wenn Sie ihn nicht explizit ändern. Dieser Wiederholungsmodus ist spezifisch für das Java SDK. Es zeichnet sich durch bis zu drei Wiederholungen oder mehr für Services wie DynamoDB aus, das bis zu acht Wiederholungen hat.
+ `standard`— Wird als „Standard“ bezeichnet, weil es konsistenter mit anderen ist. AWS SDKs Beim ersten Wiederholungsversuch wartet dieser Modus eine zufällige Zeit zwischen 0 ms und 1 000 ms. Wird ein weiterer Versuch erforderlich, wird erneut eine zufällige Zeit zwischen 0 ms und 1 000 ms gewählt und mit zwei multipliziert. Sollten weitere Wiederholungsversuche erforderlich sein, erfolgt dieselbe zufällige Auswahl, multipliziert mit vier usw. Jede Wartezeit ist auf 20 Sekunden begrenzt. Dieser Modus erkennt mehr Fehlerbedingungen als der `legacy`-Modus. Für DynamoDB sind bis zu drei Gesamtversuche vorgesehen, sofern [numRetries](#numRetries) nicht überschrieben wird.
+ `adaptive` – Baut auf dem `standard`-Modus auf und begrenzt dynamisch die Rate der AWS -Anfragen, um die Erfolgsrate zu maximieren. Dies kann auf Kosten der Latenz der Anfragen gehen. Der adaptive Modus wird nicht empfohlen, wenn eine vorhersehbare Latenz wichtig ist.

Eine erweiterte Definition dieser Wiederholungsmodi finden Sie im Thema [Wiederholungsverhalten im Referenzhandbuch AWS](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) *SDKs und im Tools-Referenzhandbuch*.

#### Wiederholungsrichtlinien
<a name="RetryPolicies"></a>

Alle `RetryMode`-Konfigurationen haben eine [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html), die auf einer oder mehreren [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html)-Konfigurationen basiert. Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html) ist besonders wichtig für das Wiederholungsverhalten der Implementierung des DynamoDB-SDK-Clients. Diese Bedingung begrenzt die Anzahl der Wiederholungen, die das SDK mithilfe eines Token-Bucket-Algorithmus durchführt. Je nach gewähltem Retry-Modus können Drosselungsfehler Token aus dem `TokenBucket` entfernen oder auch nicht.

Wenn ein Client auf einen wiederholbaren Fehler stößt, z B. eine Drosselung oder einen temporären Serverfehler, wiederholt das SDK die Anfrage automatisch. Sie können steuern, wie oft und wie schnell diese Wiederholungen erfolgen.

Bei der Konfiguration eines Clients können Sie eine `RetryPolicy` bereitstellen, die unter anderem die folgenden Parameter unterstützt:
+ `numRetries` – Die maximale Anzahl von Wiederholungsversuchen, bevor eine Anfrage als fehlgeschlagen gilt. Der Standardwert ist 8, unabhängig vom verwendeten Wiederholungsmodus.
**Warnung**  
Sie sollten diesen Standardwert nur nach reiflicher Überlegung ändern.
+ `backoffStrategy` – Die anzuwendende [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html) für Wiederholungsversuche ist standardmäßig die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html). Diese Strategie führt eine exponentielle Verzögerung zwischen den einzelnen Wiederholungen durch, basierend auf der aktuellen Anzahl der Versuche, einer Basisverzögerung und einer maximalen Backoff-Zeit. Dann wird Jitter hinzugefügt, um für ein gewisses Maß an Zufälligkeit zu sorgen. Die bei der exponentiellen Verzögerung verwendete Basisverzögerung beträgt unabhängig vom Wiederholungsmodus 25 ms.
+ `retryCondition` – Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html) bestimmt, ob eine Anfrage überhaupt erneut versucht werden soll. Standardmäßig wird ein bestimmter Satz von HTTP-Statuscodes und Ausnahmen wiederholt, von denen angenommen wird, dass sie erneut versucht werden können. In den meisten Situationen sollte die Standardkonfiguration ausreichend sein.

Der folgende Code bietet eine alternative Wiederholungsrichtlinie. Diese gibt insgesamt fünf Wiederholungen an (insgesamt sechs Anfragen). Die erste Wiederholung sollte nach einer Verzögerung von etwa 100 ms erfolgen, wobei jeder weitere Versuch diese Zeit exponentiell verdoppelt, bis zu einer maximalen Verzögerung von einer Sekunde.

```
DynamoDbClient client = DynamoDbClient.builder()
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .retryPolicy(RetryPolicy.builder()
            .backoffStrategy(FullJitterBackoffStrategy.builder()
                .baseDelay(Duration.ofMillis(100))
                .maxBackoffTime(Duration.ofSeconds(1))
                .build())
            .numRetries(5)
            .build())
        .build())
    .build();
```

### DefaultsMode
<a name="DefaultsMode"></a>

Die Timeout-Eigenschaften, die nicht durch `ClientOverrideConfiguration` oder `RetryMode` gesteuert werden, werden in der Regel implizit über die Angabe eines `DefaultsMode` konfiguriert.

Mit AWS SDK for Java 2.x (Version 2.17.102 oder höher) wurde die Unterstützung für eingeführt. `DefaultsMode` Diese Funktion bietet eine Reihe von Standardwerten für häufig konfigurierbare Einstellungen, wie HTTP-Kommunikationseinstellungen, Wiederholungsverhalten, regionale Endpunkteinstellungen des Dienstes und potenziell jede SDK-bezogene Konfiguration. Wenn Sie dieses Feature verwenden, können Sie neue Konfigurationsstandardwerte abrufen, die auf gängige Nutzungsszenarien zugeschnitten sind.

Die Standardmodi sind für alle standardisiert. AWS SDKs Das SDK for Java 2.x unterstützt die folgenden Wiederholungsmodi:
+ `legacy` – Stellt Standardeinstellungen bereit, die je nach AWS -SDK variieren und die vor der Etablierung von `DefaultsMode` existierten.
+ `standard` – Stellt nicht optimierte Standardeinstellungen für die meisten Szenarien bereit.
+ `in-region`— Baut auf dem Standardmodus auf und umfasst Einstellungen, die auf Anwendungen zugeschnitten sind, die von dort AWS-Services aus aufrufen AWS-Region.
+ `cross-region` – Baut auf dem Standardmodus auf und umfasst Einstellungen mit hohen Timeouts für Anwendungen, die AWS-Services in einer anderen Region anrufen.
+ `mobile` – Baut auf dem Standardmodus auf und umfasst Einstellungen mit hohen Timeouts, die auf mobile Anwendungen mit höheren Latenzen zugeschnitten sind.
+ `auto` – Baut auf dem Standardmodus auf und beinhaltet experimentelle Features. Das SDK versucht, die Laufzeitumgebung zu ermitteln, um die entsprechenden Einstellungen automatisch zu ermitteln. Die automatische Erkennung basiert auf Heuristik und bietet keine hundertprozentige Genauigkeit. Wenn die Laufzeitumgebung nicht bestimmt werden kann, wird der Standardmodus verwendet. Bei der automatischen Erkennung werden möglicherweise [Instance-Metadaten und Benutzerdaten](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) abgefragt, was zu Latenz führen kann. Wenn die Startlatenz für Ihre Anwendung entscheidend ist, empfehlen wir, stattdessen einen expliziten `DefaultsMode` zu wählen.

Sie können den Standardmodus folgendermaßen konfigurieren:
+ Direkt auf einem Client, mithilfe von `AwsClientBuilder.Builder#defaultsMode(DefaultsMode)`.
+ In einem Konfigurationsprofil über die Profildateieigenschaft `defaults_mode`.
+ Global über die `aws.defaultsMode`-Systemeigenschaft.
+ Global über die Umgebungsvariable `AWS_DEFAULTS_MODE`.

**Anmerkung**  
Bei allen Modi außer `legacy` können sich die bereitgestellten Standardwerte im Laufe der Zeit ändern, da sich bewährte Methoden weiterentwickeln. Daher empfehlen wir, bei Verwendung eines anderen Modus als `legacy` entsprechende Tests durchzuführen, wenn Sie das SDK aktualisieren.

Die [Smart-Konfigurationsstandardwerte](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) im Referenzhandbuch *AWS SDKs und im Tools-Referenzhandbuch* enthalten eine Liste der Konfigurationseigenschaften und ihrer Standardwerte in den verschiedenen Standardmodi.

Sie wählen den Standardmoduswert auf der Grundlage der Eigenschaften Ihrer Anwendung und der Art, mit der AWS-Service die Anwendung interagiert.

Bei der Konfiguration dieser Werte wurde eine breite Palette von Faktoren berücksichtigt AWS-Services . Für eine typische DynamoDB-Bereitstellung, bei der sowohl Ihre DynamoDB-Tabellen als auch Ihre Anwendung in derselben Region bereitgestellt sind, ist der Modus `in-region` unter den `standard`-Standardmodi am relevantesten.

**Example Beispielkonfigurierung des DynamoDB SDK-Clients für latenzoptimierte Aufrufe**  
Im folgenden Beispiel werden die Timeout-Werte für erwartete, latenzarme DynamoDB-Aufrufe nach unten angepasst.  

```
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder()
    .defaultsMode(DefaultsMode.IN_REGION)
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder())
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallTimeout(Duration.ofSeconds(3))
        .apiCallAttemptTimeout(Duration.ofMillis(500))
        .build())
    .build();
```
Die jeweilige HTTP-Client-Implementierung kann Ihnen eine noch feinere Kontrolle über das Timeout-Verhalten und die Nutzung von Verbindungen bieten. Für den AWS CRT-basierten Client können Sie beispielsweise die Option aktivieren`ConnectionHealthConfiguration`, sodass der Client den Zustand der verwendeten Verbindungen aktiv überwachen kann. *Weitere Informationen finden Sie unter [Erweiterte Konfiguration von AWS CRT-basierten HTTP-Clients](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html#configuring-the-crt-based-http-client) im Entwicklerhandbuch.AWS SDK for Java 2.x *

### Keepalive-Konfigurierung
<a name="KeepAliveConfig"></a>

Durch die Aktivierung von Keepalive können Latenzen reduziert werden, indem Verbindungen wiederverwendet werden. Es gibt zwei verschiedene Arten von Keepalive: HTTP Keepalive und TCP Keepalive.
+ - HTTP Keep-Alive versucht, die HTTPS-Verbindung zwischen Client und Server aufrechtzuerhalten, sodass spätere Anfragen dieselbe Verbindung wiederverwenden können. Dadurch entfällt die aufwendige HTTPS-Authentifizierung bei späteren Anfragen. HTTP Keepalive ist standardmäßig auf allen Clients aktiviert.
+ TCP Keepalive veranlasst das zugrunde liegende Betriebssystem, kleine Pakete über die Socket-Verbindung zu senden, um sicherzustellen, dass die Verbindung aktiv bleibt und Verbindungsabbrüche sofort erkannt werden. So wird verhindert, dass spätere Anfragen Zeit mit dem Versuch verschwenden, eine bereits getrennte Verbindung zu nutzen. TCP Keepalive ist standardmäßig bei allen Clients deaktiviert. Die folgenden Codebeispiele zeigen, wie Sie es bei den jeweiligen HTTP-Clients aktivieren können. Bei allen nicht-CRT-basierten HTTP-Clients hängt der tatsächliche Keepalive-Mechanismus vom Betriebssystem ab. Daher müssen zusätzliche TCP Keepalive-Werte wie Timeout und Paketanzahl über das Betriebssystem konfiguriert werden. Sie tun dies mithilfe von `sysctl` unter Linux oder macOS oder über Registrierungswerte unter Windows.

**Example So aktivieren Sie TCP Keepalive auf einem Apache-basierten HTTP-Client**  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**`URLConnection`-basierter HTTP-Client**  
Jeder synchrone Client, der den `URLConnection`-basierten HTTP-Client [https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html) verwendet, verfügt nicht über einen [Mechanismus](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html) zur Aktivierung von Keepalive.

**Example So aktivieren Sie TCP Keepalive auf einem Netty-basierten HTTP-Client**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Example um TCP Keep-Alive auf einem CRT-basierten HTTP-Client zu aktivieren AWS**  
Mit dem AWS CRT-basierten HTTP-Client können Sie TCP-Keep-Alive aktivieren und die Dauer steuern.  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(AwsCrtHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```
Wenn Sie den asynchronen DynamoDB-Client verwenden, können Sie TCP Keepalive aktivieren, wie im folgenden Code gezeigt.  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```

## Fehlerbehandlung
<a name="JavaErrorHandling"></a>

Wenn es um die Ausnahmebehandlung geht, werden Laufzeitausnahmen (ungeprüfte) AWS SDK for Java 2.x verwendet.

Die Basisausnahme, die alle SDK-Ausnahmen abdeckt, ist [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html), die von der Java-Laufzeitklasse `RuntimeException` erbt. Wenn Sie diese Ausnahme abfangen, fangen Sie alle vom SDK ausgelösten Ausnahmen ab.

`SdkServiceException` hat eine Unterklasse namens [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html). Diese Unterklasse weist auf Probleme bei der Kommunikation mit dem AWS-Service hin. Eine weitere Unterklasse ist [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html), die auf ein Problem bei der Kommunikation mit DynamoDB hinweist. Wenn Sie diese Ausnahme abfangen, fangen Sie alle DynamoDB-bezogenen Ausnahmen, jedoch keine anderen SDK-Ausnahmen ab.

Unter `DynamoDbException` gibt es noch spezifischere [Ausnahmetypen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html). Einige betreffen Operationen auf Steuerungsebene, z. B. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html). Andere gelten für Operationen auf Datenebene. Ein häufiges Beispiel für eine Ausnahme auf Datenebene ist:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html) – Sie haben eine Bedingung angegeben, die als false ausgewertet wurde. Beispiel: Sie haben versucht, eine bedingte Aktualisierung für ein Element durchzuführen, aber der tatsächliche Wert des Attributs stimmt nicht mit dem erwarteten Wert in der Bedingung überein. Eine Anfrage, die auf diese Weise fehlschlägt, wird nicht wiederholt.

In anderen Situationen ist keine spezifische Ausnahme definiert. Wenn Ihre Anfrage z. B. gedrosselt wird, kann entweder die spezifische `ProvisionedThroughputExceededException` oder die allgemeinere `DynamoDbException` ausgelöst werden. In beiden Fällen können Sie feststellen, ob die Drosselung die Ausnahme verursacht hat, indem Sie überprüfen, ob `isThrottlingException()` den Wert `true` zurückgibt.

Je nach den Anforderungen Ihrer Anwendung können Sie alle Instances von `AwsServiceException` oder `DynamoDbException` abfangen. Oft ist jedoch ein unterschiedliches Verhalten je nach Situation erforderlich. Die Logik zur Behandlung eines Bedingungsfehlers unterscheidet sich von der zur Behandlung einer Drosselung. Definieren Sie, welche Ausnahmepfade Sie behandeln möchten, und testen Sie die Alternativen. So stellen Sie sicher, dass Ihre Anwendung mit allen relevanten Szenarien umgehen kann.

Eine Übersicht häufiger Fehler, auf die Sie stoßen könnten, finden Sie unter [Fehlerbehandlung mit DynamoDB](Programming.Errors.md). Siehe auch [Häufig auftretende Fehler](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html) in der *Amazon DynamoDB-API-Referenz*. Die API-Referenz enthält auch die genauen Fehler, die für jeden API-Vorgang möglich sind, z. B. für die [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)-Operation. Informationen zur Behandlung von Ausnahmen finden Sie unter [Ausnahmebehandlung für die AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/handling-exceptions.html) im *AWS SDK for Java 2.x -Entwicklerhandbuch*.

## AWS Anforderungs-ID
<a name="JavaRequestID"></a>

Jede Anfrage enthält eine Anfrage-ID, die hilfreich sein kann, wenn Sie mit dem AWS Support zusammenarbeiten, um ein Problem zu diagnostizieren. Jede Ausnahme, die von `SdkServiceException` abgeleitet ist, verfügt über die Methode [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()), mit der Sie die Anfrage-ID abrufen können.

## Protokollierung
<a name="JavaLogging"></a>

Die vom SDK bereitgestellte Protokollierung kann sowohl zum Erfassen wichtiger Nachrichten aus den Client-Bibliotheken als auch für tiefgehende Debugging-Zwecke nützlich sein. Logger sind hierarchisch aufgebaut und das SDK verwendet `software.amazon.awssdk` als Root-Logger. Sie können die Protokollierungsebene mit einem der folgenden Werte konfigurieren: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `ALL` oder `OFF`. Die konfigurierte Ebene gilt für diesen Logger und alle untergeordneten Logger in der Hierarchie.

Für die Protokollierung AWS SDK for Java 2.x verwendet der die Simple Logging Façade für Java (SLF4J). Diese dient als Abstraktionsschicht über anderen Loggern, sodass Sie den Logger Ihrer Wahl einbinden können. Anweisungen zum Anschließen von Loggern finden Sie im [SLF4J-Benutzerhandbuch](https://www.slf4j.org/manual.html).

Jeder Logger verhält sich unterschiedlich. Standardmäßig erstellt der Log4j 2.x-Logger einen `ConsoleAppender`, der Protokollereignisse an `System.out` anhängt und die Protokollierungsebene `ERROR` verwendet.

Der in SLF4 J enthaltene SimpleLogger Logger gibt standardmäßig auf Protokollebene aus `System.err` und verwendet diese standardmäßig. `INFO`

Für produktive Umgebungen empfehlen wir, die Ebene für `software.amazon.awssdk` auf `WARN` zu setzen, um wichtige SDK-Meldungen zu erfassen und gleichzeitig die Ausgabemenge zu begrenzen.

Wenn SLF4 J im Klassenpfad keinen unterstützten Logger finden kann (keine SLF4 J-Bindung), wird standardmäßig eine Implementierung [ohne Operation](https://www.slf4j.org/codes.html#noProviders) verwendet. Diese Implementierung führt dazu, dass Meldungen protokolliert werden, die `System.err` erklären SLF4, dass ich im Klassenpfad keine Logger-Implementierung finden konnte. Um diese Situation zu verhindern, müssen Sie eine Logger-Implementierung hinzufügen. Dazu können Sie in Ihrem Apache Maven `pom.xml` eine Abhängigkeit von Artefakten wie `org.slf4j.slf4j-simple` oder `org.apache.logging.log4j.log4j-slf4j2-imp` hinzufügen.

Weitere Informationen zur Konfiguration der Protokollierung im SDK, einschließlich der Einbindung von Logging-Abhängigkeiten in Ihre Anwendungskonfiguration, finden Sie unter [Protokollieren mit dem SDK für Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/logging-slf4j.html) im *AWS SDK für Java -Entwicklerhandbuch*.

Die folgende Konfiguration in der `Log4j2.xml`-Datei zeigt, wie Sie das Protokollierungsverhalten anpassen können, wenn Sie den Apache Log4j 2-Logger verwenden. Diese Konfiguration legt die Root-Logger-Ebene auf `WARN` fest. Alle Logger in der Hierarchie erben diese Protokollebene, einschließlich des `software.amazon.awssdk`-Loggers.

Standardmäßig geht die Ausgabe an `System.out`. Im folgenden Beispiel überschreiben wir noch immer den standardmäßigen Log4j-Appender für die Ausgabe, um ein maßgeschneidertes Log4j-`PatternLayout` anzuwenden.

**Beispiel einer `Log4j2.xml`-Konfigurationsdatei**  
Die folgende Konfiguration protokolliert Meldungen auf der Konsole auf den Ebenen `ERROR` und `WARN` für alle Logger-Hierarchien.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="WARN">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
  </Loggers>
</Configuration>
```

### AWS ID-Protokollierung anfordern
<a name="JavaReqIDLogging"></a>

Wenn etwas schief geht, können Sie die Anfrage IDs innerhalb von Ausnahmen finden. Wenn Sie die Anfrage jedoch IDs für Anfragen verwenden möchten, die keine Ausnahmen generieren, können Sie die Protokollierung verwenden.

Der `software.amazon.awssdk.request` Logger gibt die Anfrage IDs auf der `DEBUG` Ebene aus. Das folgende Beispiel erweitert die vorherige [configuration example](#Log4j2ConfigEg), indem es die Root-Logger-Ebene auf `ERROR`, den `software.amazon.awssdk` auf die Ebene `WARN` und den Logger `software.amazon.awssdk.request` auf `DEBUG` setzt. Das Festlegen dieser Stufen hilft dabei, die Anfrage IDs und andere anforderungsbezogene Details wie den Endpunkt und den Statuscode abzufangen.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
    <Logger name="software.amazon.awssdk" level="WARN" />
    <Logger name="software.amazon.awssdk.request" level="DEBUG" />
  </Loggers>
</Configuration>
```

Hier finden Sie ein Beispiel für die Protokollausgabe:

```
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[])
 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available
```

## Paginierung
<a name="JavaPagination"></a>

Einige Anfragen, wie [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) und [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) begrenzen die Datenmenge, die mit einer einzelnen Anfrage zurückgegeben wird, und erfordern wiederholte Anfragen, um nachfolgende Seiten abzurufen.

Mit dem `Limit`-Parameter können Sie die maximale Anzahl von Elementen steuern, die für jede Seite gelesen werden sollen. Sie können den `Limit`-Parameter beispielsweise verwenden, um nur die letzten 10 Elemente abzurufen. Dieser Grenzwert gibt an, wie viele Elemente aus der Tabelle gelesen werden sollen, bevor eine Filterung angewendet wird. Wenn Sie nach dem Filtern genau 10 Elemente benötigen, können Sie dies nicht angeben. Sie können nur die Anzahl der vorgefilterten Elemente steuern und clientseitig überprüfen, ob Sie tatsächlich 10 Elemente abgerufen haben. Unabhängig vom Grenzwert haben Antworten immer eine maximale Größe von 1 MB.

In der API-Antwort kann ein `LastEvaluatedKey` enthalten sein. Dies weist darauf hin, dass die Antwort beendet wurde, weil sie eine Anzahl- oder Größenbeschränkung erreicht hat. Dieser Schlüssel ist der letzte Schlüssel, der für diese Antwort ausgewertet wurde. Durch direkte Interaktion mit der API können Sie diesen `LastEvaluatedKey` abrufen und an einen Folgeaufruf als `ExclusiveStartKey` weitergeben, um den nächsten Abschnitt von diesem Startpunkt aus zu lesen. Wenn kein `LastEvaluatedKey` zurückgegeben wird, bedeutet das, dass keine weiteren Elemente zum `Query`- oder `Scan`-API-Aufruf passen.

Im folgenden Beispiel wird die Low-Level-Schnittstelle verwendet, um die Anzahl der Elemente auf Basis des `keyConditionExpression`-Parameters auf 100 zu beschränken.

```
QueryRequest.Builder queryRequestBuilder = QueryRequest.builder()
        .expressionAttributeValues(Map.of(
                ":pk_val", AttributeValue.fromS("123"),
                ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName(TABLE_NAME);

while (true) {
    QueryResponse queryResponse = DYNAMODB_CLIENT.query(queryRequestBuilder.build());

    queryResponse.items().forEach(item -> {
        LOGGER.info("item PK: [" + item.get("pk") + "] and SK: [" + item.get("sk") + "]");
    });

    if (!queryResponse.hasLastEvaluatedKey()) {
        break;
    }
    queryRequestBuilder.exclusiveStartKey(queryResponse.lastEvaluatedKey());
}
```

 AWS SDK for Java 2.x Sie können diese Interaktion mit DynamoDB vereinfachen, indem sie automatische Paginierungsmethoden bereitstellen, die mehrere Serviceaufrufe tätigen, um automatisch die nächsten Ergebnisseiten für Sie abzurufen. Dies vereinfacht Ihren Code, nimmt Ihnen jedoch die Kontrolle über die Ressourcennutzung, die Sie beim manuellen Lesen von Seiten behalten würden.

Mithilfe der im DynamoDB-Client verfügbaren `Iterable`-Methoden wie [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)) und [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)) kümmert sich das SDK um die Paginierung. Der Rückgabetyp dieser Methoden ist ein benutzerdefiniertes iterierbares Objekt, mit dem Sie durch alle Seiten iterieren können. Das SDK bearbeitet für Sie Serviceanfragen intern. Mithilfe der Java Stream API können Sie das Ergebnis von `QueryPaginator` wie im folgenden Beispiel gezeigt verarbeiten.

```
QueryPublisher queryPublisher =
    DYNAMODB_CLIENT.queryPaginator(QueryRequest.builder()
        .expressionAttributeValues(Map.of(
            ":pk_val", AttributeValue.fromS("123"),
            ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName("YourTableName")
        .build());

queryPublisher.items().subscribe(item ->
    System.out.println(item.get("itemData"))).join();
```

## Annotationen für Datenklassen
<a name="JavaDataClassAnnotation"></a>

Das Java SDK stellt mehrere Annotationen bereit, die Sie auf die Attribute Ihrer Datenklasse anwenden können. Diese Annotationen beeinflussen, wie das SDK mit den Attributen interagiert. Durch das Hinzufügen einer Annotation kann ein Attribut beispielsweise als impliziter unteilbarer Zähler fungieren, einen automatisch generierten Zeitstempelwert speichern oder eine Versionsnummer eines Elements nachverfolgen. Weitere Informationen finden Sie unter [Annotationen für Datenklassen](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html).

# Fehlerbehandlung mit DynamoDB
<a name="Programming.Errors"></a>

 Dieser Abschnitt beschreibt Laufzeitfehler und wie sie gehandhabt werden können. Es werden auch Fehlermeldungen und Codes beschrieben, die Amazon-DynamoDB-spezifisch sind. [Eine Liste der häufigsten Fehler, die für alle AWS Dienste gelten, finden Sie unter Access Management](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html)

**Topics**
+ [

## Fehlerkomponenten
](#Programming.Errors.Components)
+ [

## Transaktionsfehler
](#Programming.Errors.TransactionalErrors)
+ [

## Fehlermeldungen und Codes
](#Programming.Errors.MessagesAndCodes)
+ [

## Fehlerbehandlung in Ihrer Anwendung
](#Programming.Errors.Handling)
+ [

## Wiederholversuche bei Fehlern und exponentielles Backoff
](#Programming.Errors.RetryAndBackoff)
+ [

## Batchoperationen und Fehlerbehandlung
](#Programming.Errors.BatchOperations)

## Fehlerkomponenten
<a name="Programming.Errors.Components"></a>

Wenn das Programm eine Anforderung sendet, versucht DynamoDB diese zu verarbeiten. Bei einer erfolgreichen Anforderung gibt DynamoDB einen HTTP-Erfolgscode (`200 OK`) sowie die Ergebnisse der angeforderten Operation zurück.

Wenn die Anforderung nicht erfolgreich ist, gibt DynamoDB einen Fehler zurück. Jeder Fehler hat drei Komponenten: 
+ Einen HTTP-Statuscode (z. B. `400`).
+ Einen Ausnahmenamen (z. B. `ResourceNotFoundException`).
+ Eine Fehlermeldung (z. B. `Requested resource not found: Table: tablename not found`).

 AWS SDKs Sie kümmern sich darum, dass Fehler an Ihre Anwendung weitergegeben werden, sodass Sie entsprechende Maßnahmen ergreifen können. Sie können beispielsweise in einem Java-Programm eine `try-catch`-Logik schreiben, um eine `ResourceNotFoundException` zu verarbeiten.

Wenn Sie kein AWS SDK verwenden, müssen Sie den Inhalt der Low-Level-Antwort von DynamoDB analysieren. Nachfolgend finden Sie ein Beispiel einer solchen Antwort.

```
HTTP/1.1 400 Bad Request
x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG
Content-Type: application/x-amz-json-1.0
Content-Length: 240
Date: Thu, 15 Mar 2012 23:56:23 GMT

{"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
"message":"Requested resource not found: Table: tablename not found"}
```

## Transaktionsfehler
<a name="Programming.Errors.TransactionalErrors"></a>

Informationen zu Transaktionsfehlern finden Sie unter [Handhabung von Transaktionskonflikten in DynamoDB](transaction-apis.md#transaction-conflict-handling)

## Fehlermeldungen und Codes
<a name="Programming.Errors.MessagesAndCodes"></a>

Die folgende Liste enthält von DynamoDB zurückgegebene Ausnahmen, gruppiert nach HTTP-Statuscode. Wenn *OK, um es erneut zu versuchen?* * Ja* ist, können Sie die gleiche Anforderung erneut senden. Wenn *OK, um es erneut zu versuchen?* auf *Nein* eingestellt ist, müssen Sie das Problem clientseitig lösen, bevor Sie eine neue Anforderung absenden.

### HTTP-Statuscode 400
<a name="Programming.Errors.MessagesAndCodes.http400"></a>

Der HTTP-Statuscode `400` weist auf ein Problem mit der Anforderung hin, wie z. B. einen Authentifizierungsfehler, fehlende Parameter oder die Überschreitung des bereitgestellten Durchsatzes der Tabelle. Sie müssen das Problem zuerst in der Anwendung beheben, bevor Sie die Anforderung erneut senden.

**AccessDeniedException **  
Meldung: *Access denied.* (Zugriff verweigert.)  
Der Client hat die Anforderung nicht richtig signiert. Wenn Sie ein AWS -SDK verwenden, werden die Anforderungen automatisch für Sie signiert. Rufen Sie andernfalls [Signaturprozess mit Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) in der *Allgemeine AWS-Referenz* auf.  
Erneut versuchen? Nein

**ConditionalCheckFailedException**  
Meldung: *The conditional request failed.* (Die bedingte Anforderung ist fehlgeschlagen.)  
Sie haben eine Bedingung angegeben, die als False ausgewertet wurde. Beispiel: Sie haben versucht, eine bedingte Aktualisierung für ein Element durchzuführen, aber der tatsächliche Wert des Attributs stimmt nicht mit dem erwarteten Wert in der Bedingung überein.  
Erneut versuchen? Nein

**IncompleteSignatureException**  
Meldung: *Die angeforderte Signatur entspricht nicht den AWS Standards. *  
Die Anforderungssignatur enthielt nicht alle erforderlichen Komponenten. Wenn Sie ein AWS SDK verwenden, werden Anfragen automatisch für Sie signiert. Andernfalls fahren Sie mit dem Signaturprozess für [Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) in der fort. *Allgemeine AWS-Referenz*  
Erneut versuchen? Nein

**ItemCollectionSizeLimitExceededException**  
Meldung: *Collection size exceeded.* (Sammlungsgröße überschritten.)  
Für eine Tabelle mit einem lokalen sekundären Index hat eine Gruppe von Elementen mit demselben Partitionsschlüsselwert die maximale Größe von 10 GB überschritten. Weitere Informationen zu Elementsammlungen finden Sie unter [Elementauflistungen in lokalen sekundären Indizes](LSI.md#LSI.ItemCollections).  
Erneut versuchen? Ja

**LimitExceededException**  
Meldung: *Too many operations for a given subscriber.* (Zu viele Operationen für einen bestimmten Abonnenten.)  
Es gibt zu viele gleichzeitige Operationen auf Steuerebene. Die kumulative Anzahl von Tabellen und Indizes im Status `CREATING`, `DELETING` oder `UPDATING` darf 500 nicht überschreiten.  
Erneut versuchen? Ja

**MissingAuthenticationTokenException**  
Meldung: *Anforderung muss eine gültige (registrierte) AWS -Zugriffsschlüssel-ID enthalten.*  
Die Anforderung schloss die erforderliche Autorisierungskopfzeile nicht ein oder sie war falsch formatiert. Siehe [DynamoDB Low-Level-API](Programming.LowLevelAPI.md).  
Erneut versuchen? Nein

**ProvisionedThroughputExceededException**  
Meldung: *Sie haben Ihren maximal erlaubten bereitgestellten Durchsatz für eine Tabelle oder für einen oder mehrere globale sekundäre Indizes überschritten. Um Leistungskennzahlen für den bereitgestellten Durchsatz im Vergleich zum verbrauchten Durchsatz anzuzeigen, öffnen Sie die [ CloudWatchAmazon-Konsole](https://console.aws.amazon.com/cloudwatch/home).*  
Der Fehler enthält eine Liste von `ThrottlingReason`-Feldern, die spezifischen Kontext darüber liefern, warum eine Drosselung aufgetreten ist. Diese folgen dem Format `ResourceType+OperationType+LimitType` (z. B. `TableReadProvisionedThroughputExceeded`) sowie dem ARN der betroffenen Ressource. Dies hilft Ihnen dabei zu erkennen, welche Ressource von der Drosselung betroffen ist (Tabelle oder Index), welcher Operationstyp die Drosselung ausgelöst hat (Lese- oder Schreibvorgang) und welche spezifische Beschränkung überschritten wurde (in diesem Fall: bereitgestellte Kapazität). Weitere Informationen zur Diagnose und Lösung von Drosselungsproblemen finden Sie unter [Drosselungsdiagnose](throttling-diagnosing-workflow.md).  
Beispiel: Die Anforderungsrate ist zu hoch. Die AWS SDKs für DynamoDB wiederholen automatisch Anfragen, die diese Ausnahme erhalten. Die Anforderung ist letztendlich erfolgreich, sofern die Warteschlange für Wiederholungsversuche für das Beenden nicht zu groß ist. Verringern Sie die Häufigkeit der Anforderungen mit [Wiederholversuche bei Fehlern und exponentielles Backoff](#Programming.Errors.RetryAndBackoff).   
Erneut versuchen? Ja

**ReplicatedWriteConflictException**  
Nachricht: *Ein oder mehrere Elemente in dieser Anfrage werden durch eine Anfrage in einer anderen Region geändert.*  
Beispiel: Eine Schreiboperation wurde für ein Element in einer globalen Tabelle mit Multi-Region Strong Consistency (MRSC) angefordert, das derzeit durch eine Anfrage in einer anderen Region geändert wird.   
Erneut versuchen? Ja

**RequestLimitExceeded**  
Meldung: *Throughput exceeds the current throughput limit for your account. (Der Durchsatz überschreitet die aktuelle Durchsatzbegrenzung für Ihr Konto.) Um eine Erhöhung des Limits zu beantragen, wenden Sie sich an den AWS Support unter [https://aws.amazon.com/support](https://aws.amazon.com/support)*.  
Der Fehler enthält eine Liste von `ThrottlingReason`-Feldern, die spezifischen Kontext darüber liefern, warum eine Drosselung aufgetreten ist. Diese folgen dem Format `ResourceType+OperationType+LimitType` (z. B. `TableWriteAccountLimitExceeded` oder `IndexReadAccountLimitExceeded`) sowie dem ARN der betroffenen Ressource. Dies hilft Ihnen zu erkennen, welche Ressource von der Drosselung betroffen ist (Tabelle oder Index), welcher Operationstyp die Drosselung ausgelöst hat (Lese- oder Schreibvorgang) und dass Sie die servicebezogenen Kontingente auf Kontoebene überschritten haben. Weitere Informationen zur Diagnose und Lösung von Drosselungsproblemen finden Sie unter [Drosselungsdiagnose](throttling-diagnosing-workflow.md).   
Beispiel: Die Rate der On-Demand-Anforderungen überschreitet den zulässigen Kontodurchsatz.  
Erneut versuchen? Ja

**ResourceInUseException**  
Meldung: *The resource which you are attempting to change is in use.* (Die Ressource, die Sie verändern möchten, wird gerade benutzt.)  
Beispiel: Sie haben versucht, eine vorhandene Tabelle neu zu erstellen oder eine Tabelle zu löschen, die sich momentan im Status `CREATING` befindet.   
Erneut versuchen? Nein

**ResourceNotFoundException **  
Meldung: *Requested resource not found.* (Angefragte Ressource nicht gefunden.)  
Beispiel: Die Tabelle, die angefordert wird, ist nicht vorhanden oder befindet sich zu früh im Status `CREATING`.  
Erneut versuchen? Nein

**ThrottlingException**  
Meldung: *Rate of requests exceeds the allowed throughput.* (Anforderungsrate überschreitet den erlaubten Durchsatz.)  
Diese Ausnahme wird als AmazonServiceException Antwort mit dem Statuscode THROTTLING\$1EXCEPTION zurückgegeben. Diese Ausnahme wird möglicherweise zurückgegeben, wenn Sie API-Operationen der [Steuerebene](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.ControlPlane) zu schnell ausführen.  
Bei Tabellen, die den On-Demand-Modus verwenden, wird diese Ausnahme möglicherweise für alle API-Operationen der [Datenebene](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.DataPlane) zurückgegeben, wenn Ihre Anforderungsrate zu hoch ist. Weitere Informationen zu On-Demand-Skalierungen finden Sie unter [Anfänglicher Durchsatz und Skalierungseigenschaften](on-demand-capacity-mode.md#on-demand-capacity-mode-initial).   
Der Fehler enthält eine Liste von `ThrottlingReason`-Feldern, die spezifischen Kontext darüber liefern, warum eine Drosselung aufgetreten ist. Diese folgen dem Format `ResourceType+OperationType+LimitType` (z. B. `TableReadKeyRangeThroughputExceeded` oder `IndexWriteMaxOnDemandThroughputExceeded`) sowie dem ARN der betroffenen Ressource. Diese Informationen helfen Ihnen zu erkennen, welche Ressource von der Drosselung betroffen ist (Tabelle oder Index), welcher Operationstyp die Drosselung ausgelöst hat (Lese- oder Schreibvorgang) und welches spezifische Beschränkung überschritten wurde (Partitionsgrenzen oder maximale Durchsatzrate im On-Demand-Modus). Weitere Informationen zur Diagnose und Lösung von Drosselungsproblemen finden Sie unter [Drosselungsdiagnose](throttling-diagnosing-workflow.md).  
Erneut versuchen? Ja

**UnrecognizedClientException**  
Meldung: *The Access Key ID or security token is invalid.* (Die Zugriffsschlüssel-ID oder der Sicherheitstoken ist ungültig.)  
Die Anforderungssignatur ist nicht korrekt. Die wahrscheinlichste Ursache ist eine ungültige AWS Zugriffsschlüssel-ID oder ein ungültiger geheimer Schlüssel.  
Erneut versuchen? Ja

**ValidationException**  
Meldung: Variiert je nach auftretendem spezifischen Fehler(n)  
Dieser Fehler kann aus verschiedenen Gründen auftreten, z. B. wenn ein erforderlicher Parameter fehlt, ein Wert außerhalb des Bereichs liegt oder Datentypen nicht übereinstimmen. Die Fehlermeldung enthält Details zum spezifischen Teil der Anforderung, die den Fehler verursacht hat.  
Erneut versuchen? Nein

### HTTP-Statuscode 5xx
<a name="Programming.Errors.MessagesAndCodes.http5xx"></a>

Der HTTP-Statuscode `5xx` weist auf ein Problem hin, das von AWS behoben werden muss. Dies kann ein vorübergehender Fehler sein. In diesem Fall können Sie Ihre Anforderung wiederholen, bis sie korrekt ausgeführt wird. Andernfalls rufen Sie das [AWS Service Health Dashboard](https://status.aws.amazon.com/) auf, um zu sehen, ob es Betriebsprobleme mit dem Service gibt.

Weitere Informationen finden Sie unter [Wie behebe ich HTTP-5xx-Fehler in Amazon DynamoDB?](https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-http-5xx-errors/)

**InternalServerError (HTTP 500)**  
DynamoDB konnte die Anforderung nicht verarbeiten.  
Erneut versuchen? Ja  
Während der Arbeit mit Elementen können interne Serverfehler auftreten. Diese sind während der Lebensdauer einer Tabelle zu erwarten. Alle fehlgeschlagenen Anforderungen können sofort abgerufen werden.  
Wenn Sie bei einem Schreibvorgang einen Statuscode 500 erhalten, ist der Vorgang entweder erfolgreich oder ist fehlgeschlagen. Wenn der Schreibvorgang eine `TransactWriteItem`-Anforderung ist, dann ist es in Ordnung, den Vorgang erneut zu versuchen. Handelt es sich bei dem Schreibvorgang um eine Schreibanforderung für ein einzelnes Element wie `PutItem``UpdateItem`, oder`DeleteItem`, dann sollte Ihre Anwendung den Status des Elements lesen, bevor Sie den Vorgang erneut versuchen. and/or Verwenden Sie diese Option, [CLI-Beispiel für DynamoDB-Bedingungsausdrücke](Expressions.ConditionExpressions.md) um sicherzustellen, dass das Element nach dem erneuten Versuch in einem korrekten Zustand bleibt, unabhängig davon, ob der vorherige Vorgang erfolgreich war oder nicht. Wenn Idempotenz eine Voraussetzung für die Schreiboperation ist, verwenden Sie bitte [`TransactWriteItem`](transaction-apis.md#transaction-apis-txwriteitems), das idempotente Anfragen durch automatische Angabe eines `ClientRequestToken` unterstützt, um mehrere Versuche zu disambiguieren, dieselbe Aktion auszuführen.

**ServiceUnavailable (HTTP 503)**  
DynamoDB ist derzeit nicht verfügbar. (Dies sollte ein vorübergehender Status sein.)  
Erneut versuchen? Ja

## Fehlerbehandlung in Ihrer Anwendung
<a name="Programming.Errors.Handling"></a>

Damit Ihre Anwendung reibungslos ausgeführt wird, müssen Sie Logik zum Erfassen und Behandeln von Fehlern integrieren. Typische Ansätze umfassen die Verwendung von `try-catch`-Blöcken oder `if-then`-Anweisungen.

 AWS SDKs Sie führen ihre eigenen Wiederholungen und Fehlerprüfungen durch. Wenn Sie bei der Verwendung eines der Geräte auf einen Fehler stoßen AWS SDKs, können Ihnen der Fehlercode und die Beschreibung bei der Behebung helfen.

Sie sollten auch eine `Request ID` in der Antwort sehen. Das `Request ID` kann hilfreich sein, wenn Sie mit dem AWS Support zusammenarbeiten müssen, um ein Problem zu diagnostizieren.

## Wiederholversuche bei Fehlern und exponentielles Backoff
<a name="Programming.Errors.RetryAndBackoff"></a>

Zahlreiche Komponenten im Netzwerk, wie z. B. DNS-Server, Switches und Load Balancer, können irgendwann im Lebenszyklus einer Anforderung Fehler generieren. Die übliche Methode zum Umgang mit diesen Fehlermeldungen in einer vernetzten Umgebung besteht darin, Wiederholversuche in der Client-Anwendung zu implementieren. Diese Methode erhöht die Zuverlässigkeit der Anwendung.

Jedes AWS SDK implementiert die Wiederholungslogik automatisch. Sie können die Parameter für Wiederholversuche an Ihre Bedürfnisse anpassen. Nehmen wir als Beispiel eine Java-Anwendung, die eine Fail-Fast-Strategie erfordert, in der im Falle eines Fehlers keine Wiederholversuche zulässig sind. Mit dem AWS SDK für Java könnten Sie die `ClientConfiguration` Klasse verwenden und den `maxErrorRetry` Wert von angeben, `0` um die Wiederholungsversuche auszuschalten. Weitere Informationen finden Sie in der AWS SDK-Dokumentation für Ihre Programmiersprache.

Wenn Sie kein AWS SDK verwenden, sollten Sie die ursprünglichen Anfragen, bei denen Serverfehler auftreten, erneut versuchen (5xx). Client-Fehler (4xx, außer `ThrottlingException` oder `ProvisionedThroughputExceededException`) weisen hingegen darauf hin, dass die Anforderung selbst geändert werden muss, um das Problem zu beheben. Erst dann sollte sie wiederholt werden. Detaillierte Empfehlungen zur Behandlung bestimmter Drosselungsszenarien finden Sie im Abschnitt [Problembehandlung bei DynamoDB-Drosselung](TroubleshootingThrottling.md).

Zusätzlich zu einfachen Wiederholungsversuchen implementiert jedes AWS SDK einen exponentiellen Backoff-Algorithmus für eine bessere Flusskontrolle. Das Konzept hinter dem exponentiellen Backoff ist die Verwendung von progressiv längeren Wartezeiten zwischen Wiederholversuchen für aufeinanderfolgende Fehlermeldungen. Zum Beispiel bis zu 50 Millisekunden vor dem ersten Wiederholversuch, bis zu 100 Millisekunden vor dem zweiten, bis zu 200 Millisekunden vor dem dritten und so weiter. Wenn die Anforderung hingegen nach einer Minute nicht erfolgreich war, liegt das Problem möglicherweise an der Anforderungsgröße, die den bereitgestellten Durchsatz übersteigt, und nicht an der Anforderungsrate. Grenzen Sie die maximale Anzahl von Wiederholversuchen bis zu etwa einer Minute ein. Wenn die Anforderung nicht erfolgreich ist, untersuchen Sie Ihre bereitgestellten Durchsatzoptionen. 

**Anmerkung**  
Sie AWS SDKs implementieren automatische Wiederholungslogik und exponentiellen Backoff.

Die meisten Algorithmen für das exponentielle Backoff verwenden Jitter (zufällige Verzögerung), um nachfolgende Kollisionen zu verhindern. Da Sie hier nicht versuchen, solche Kollisionen zu verhindern, müssen Sie diese Zufallszahl nicht verwenden. Wenn Sie jedoch gleichzeitige Clients verwenden, kann Jitter dazu beitragen, dass Ihre Anforderungen schneller verarbeitet werden. Weitere Informationen finden Sie im Blogbeitrag zu [Exponentielles Backoff und Jitter](http://www.awsarchitectureblog.com/2015/03/backoff.html).

## Batchoperationen und Fehlerbehandlung
<a name="Programming.Errors.BatchOperations"></a>

Die Low-Level-API von DynamoDB unterstützt Batch-Operationen für Lese- und Schreibvorgänge. `BatchGetItem` liest Elemente aus einzelnen oder mehreren Tabellen und `BatchWriteItem` schreibt Elemente in einzelne oder mehrere Tabellen oder löscht sie daraus. Diese Batchoperationen werden als Wrapper um andere Nicht-Batch-DynamoDB-Operationen herum implementiert. Mit anderen Worten, `BatchGetItem` ruft `GetItem` einmal für jedes Element im Stapel auf. Ebenso ruft `BatchWriteItem` `DeleteItem` oder `PutItem` für jedes Element im Stapel auf, je nachdem.

Eine Stapeloperation kann den Ausfall einzelner Anforderungen im Stapel tolerieren. Nehmen Sie beispielsweise eine `BatchGetItem`-Anforderung für das Lesen von fünf Elementen. Auch wenn einige der zugrunde liegenden `GetItem`-Anforderungen fehlschlagen, führt dies nicht zum Ausfall der gesamten `BatchGetItem`-Operation. Wenn jedoch alle fünf Leseoperationen fehlschlagen, schlägt der gesamte `BatchGetItem`-Vorgang fehl.

Die Stapeloperationen geben Informationen zu ausgefallenen individuellen Anforderungen zurück, sodass Sie das Problem diagnostizieren und die Operation wiederholen können. Für `BatchGetItem` werden die jeweiligen Tabellen und primären Schlüssel in den `UnprocessedKeys`-Wert der Antwort zurückgegeben. Für `BatchWriteItem` werden die gleichen Informationen in `UnprocessedItems` zurückgegeben. 

Vermutlich ist die Ursache für einen fehlgeschlagenen Lese- oder Schreibvorgang eine *Drosselung*. Für `BatchGetItem` steht einer oder mehreren Tabellen in der Stapelanforderung nicht ausreichend Lesekapazität zur Verfügung, um die Operation zu unterstützen. Für `BatchWriteItem` steht einer oder mehreren Tabellen nicht ausreichend Schreibkapazität zur Verfügung.

Wenn DynamoDB unverarbeitete Elemente zurückgibt, sollten Sie die Batchoperation für diese Elemente wiederholen. Jedoch * empfehlen wir dringend, dass Sie einen exponentiellen Backoff-Algorithmus verwenden*. Wenn Sie die Stapeloperation sofort wiederholen, können die zugrunde liegenden Lese- und Schreibanforderungen dennoch aufgrund einer Drosselung der einzelnen Tabellen fehlschlagen. Wenn Sie die Stapeloperation mithilfe des exponentiellen Backoff verzögern, werden die einzelnen Anforderungen in dem Stapel eher erfolgreich sein.

**Anmerkung**  
Einige AWS SDKs bieten Clients auf höherer Ebene, die Wiederholungsversuche für unverarbeitete Elemente automatisch verarbeiten, sodass Sie diese Wiederholungslogik nicht selbst implementieren müssen. Beispiel:  
**Java** — Der [DynamoDB Enhanced Client](DynamoDBEnhanced.md) in AWS SDK für Java Version 2 und [Dynamo DBMapper](DynamoDBMapper.md) in Version 1 versuchen beide automatisch, unverarbeitete Elemente erneut zu versuchen, wenn Batch-Operationen ausgeführt werden.
**Python** — Die Tabellenressource boto3 verarbeitet implizit `batch_writer` Wiederholungen unverarbeiteter Elemente für Batch-Schreibvorgänge. Weitere Informationen finden Sie unter [Verwenden der Tabellenressource batch\$1writer](programming-with-python.md#programming-with-python-batch-writer).
Wenn Sie einen Low-Level-Client oder ein SDK verwenden, das dieses Verhalten nicht bietet, müssen Sie die Wiederholungslogik wie oben beschrieben selbst implementieren.

# DynamoDB mit einem SDK verwenden AWS
<a name="sdk-general-information-section"></a>

AWS Software Development Kits (SDKs) sind für viele beliebte Programmiersprachen verfügbar. Jedes SDK bietet eine API, Codebeispiele und Dokumentation, die es Entwicklern erleichtern, Anwendungen in ihrer bevorzugten Sprache zu erstellen.


| SDK-Dokumentation | Codebeispiele | 
| --- | --- | 
| [AWS SDK für C\$1\$1](https://docs.aws.amazon.com/sdk-for-cpp) | [AWS SDK für C\$1\$1 Codebeispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp) | 
| [AWS CLI](https://docs.aws.amazon.com/cli) | [AWS CLI Code-Beispiele](https://docs.aws.amazon.com/code-library/latest/ug/cli_2_code_examples.html) | 
| [AWS SDK für Go](https://docs.aws.amazon.com/sdk-for-go) | [AWS SDK für Go Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2) | 
| [AWS SDK für Java](https://docs.aws.amazon.com/sdk-for-java) | [AWS SDK für Java Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2) | 
| [AWS SDK für JavaScript](https://docs.aws.amazon.com/sdk-for-javascript) | [AWS SDK für JavaScript Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3) | 
| [AWS SDK für Kotlin](https://docs.aws.amazon.com/sdk-for-kotlin) | [AWS SDK für Kotlin Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin) | 
| [AWS SDK für .NET](https://docs.aws.amazon.com/sdk-for-net) | [AWS SDK für .NET Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3) | 
| [AWS SDK für PHP](https://docs.aws.amazon.com/sdk-for-php) | [AWS SDK für PHP Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php) | 
| [AWS -Tools für PowerShell](https://docs.aws.amazon.com/powershell) | [AWS -Tools für PowerShell Code-Beispiele](https://docs.aws.amazon.com/code-library/latest/ug/powershell_5_code_examples.html) | 
| [AWS SDK für Python (Boto3)](https://docs.aws.amazon.com/pythonsdk) | [AWS SDK für Python (Boto3) Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python) | 
| [AWS SDK für Ruby](https://docs.aws.amazon.com/sdk-for-ruby) | [AWS SDK für Ruby Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/ruby) | 
| [AWS SDK für Rust](https://docs.aws.amazon.com/sdk-for-rust) | [AWS SDK für Rust Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1) | 
| [AWS SDK für SAP ABAP](https://docs.aws.amazon.com/sdk-for-sapabap) | [AWS SDK für SAP ABAP Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap) | 
| [AWS SDK für Swift](https://docs.aws.amazon.com/sdk-for-swift) | [AWS SDK für Swift Code-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift) | 

Spezifische Beispiele zu DynamoDB finden Sie unter [Codebeispiele für DynamoDB mit AWS SDKs](service_code_examples.md).

**Beispiel für die Verfügbarkeit**  
Sie können nicht finden, was Sie brauchen? Fordern Sie ein Codebeispiel an, indem Sie unten den Link **Provide feedback** (Feedback geben) auswählen.