

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.

# Arbeiten mit lokalen sekundären Indizes: Java
<a name="LSIJavaDocumentAPI"></a>

Sie können die AWS SDK für Java Document-API verwenden, um eine Amazon DynamoDB-Tabelle mit einem oder mehreren lokalen Sekundärindizes zu erstellen, die Indizes in der Tabelle zu beschreiben und Abfragen mithilfe der Indizes durchzuführen.

Im Folgenden werden die üblichen Schritte für Tabellenoperationen mit der Document-API beschrieben. AWS SDK für Java 

1. Erstellen Sie eine Instance der `DynamoDB`-Klasse.

1. Stellen Sie den erforderlichen und optionalen Parameter für die Operation bereit, indem Sie die entsprechenden Anforderungsobjekte erstellen. 

1. Rufen Sie die entsprechende Methode auf, die vom Client, den Sie im vorhergehenden Schritt erstellt haben, bereitgestellt wird. 

**Topics**
+ [Erstellen einer Tabelle mit einem lokalen sekundären Index](#LSIJavaDocumentAPI.CreateTableWithIndex)
+ [Beschreiben einer Tabelle mit einem lokalen sekundären Index](#LSIJavaDocumentAPI.DescribeTableWithIndex)
+ [Abfragen eines lokalen sekundären Indexes](#LSIJavaDocumentAPI.QueryAnIndex)
+ [Beispiel: Lokale sekundäre Indizes mit der Java-Dokument-API](LSIJavaDocumentAPI.Example.md)

## Erstellen einer Tabelle mit einem lokalen sekundären Index
<a name="LSIJavaDocumentAPI.CreateTableWithIndex"></a>

Lokale sekundäre Indizes müssen gleichzeitig mit dem Erstellen einer Tabelle erstellt werden. Verwenden Sie dazu die Methode `createTable` und geben Sie Ihre Angaben für einen oder mehrere lokale Sekundärindizes an. Das folgende Java-Codebeispiel erstellt eine Tabelle, die Informationen über Songs in einer Musiksammlung enthält. Der Partitionsschlüssel ist `Artist` und der Sortierschlüssel `SongTitle`. Der sekundäre Index, `AlbumTitleIndex`, vereinfacht Abfragen von Albumtiteln. 

Im Folgenden werden die Schritte zum Erstellen einer Tabelle mit einem lokalen sekundären Index mithilfe der DynamoDB-Dokument-API dargelegt. 

1. Erstellen Sie eine Instance der `DynamoDB`-Klasse.

1. Erstellen Sie eine Instance der `CreateTableRequest`-Klasse, um die Anforderungsinformationen bereitzustellen. 

   Sie müssen den Tabellennamen, seinen zugehörigen Primärschlüssel und die Werte des bereitgestellten Durchsatzes angeben. Für den lokalen sekundären Index müssen Sie den Indexnamen, den Namen und den Datentyp des Indexsortierschlüssels, des Schlüsselschemas für den Index und der Attributprojektion angeben.

1. Rufen Sie die `createTable`-Methode auf, indem das Anforderungsobjekt als Parameter festgelegt wird.

Im folgenden Java-Codebeispiel werden die vorherigen Schritte veranschaulicht. Der Codeerstellt eine Tabelle (`Music`) mit einem sekundären Index auf dem `AlbumTitle`-Attribut. Der Tabellenpartitionsschlüssel und der Sortierschlüssel, sowie der Indexsortierschlüssel sind die einzigen in den Index projizierten Attribute.

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

String tableName = "Music";

CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(tableName);

//ProvisionedThroughput
createTableRequest.setProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits((long)5).withWriteCapacityUnits((long)5));

//AttributeDefinitions
ArrayList<AttributeDefinition> attributeDefinitions= new ArrayList<AttributeDefinition>();
attributeDefinitions.add(new AttributeDefinition().withAttributeName("Artist").withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition().withAttributeName("SongTitle").withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition().withAttributeName("AlbumTitle").withAttributeType("S"));

createTableRequest.setAttributeDefinitions(attributeDefinitions);

//KeySchema
ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>();
tableKeySchema.add(new KeySchemaElement().withAttributeName("Artist").withKeyType(KeyType.HASH));  //Partition key
tableKeySchema.add(new KeySchemaElement().withAttributeName("SongTitle").withKeyType(KeyType.RANGE));  //Sort key

createTableRequest.setKeySchema(tableKeySchema);

ArrayList<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>();
indexKeySchema.add(new KeySchemaElement().withAttributeName("Artist").withKeyType(KeyType.HASH));  //Partition key
indexKeySchema.add(new KeySchemaElement().withAttributeName("AlbumTitle").withKeyType(KeyType.RANGE));  //Sort key

Projection projection = new Projection().withProjectionType(ProjectionType.INCLUDE);
ArrayList<String> nonKeyAttributes = new ArrayList<String>();
nonKeyAttributes.add("Genre");
nonKeyAttributes.add("Year");
projection.setNonKeyAttributes(nonKeyAttributes);

LocalSecondaryIndex localSecondaryIndex = new LocalSecondaryIndex()
    .withIndexName("AlbumTitleIndex").withKeySchema(indexKeySchema).withProjection(projection);

ArrayList<LocalSecondaryIndex> localSecondaryIndexes = new ArrayList<LocalSecondaryIndex>();
localSecondaryIndexes.add(localSecondaryIndex);
createTableRequest.setLocalSecondaryIndexes(localSecondaryIndexes);

Table table = dynamoDB.createTable(createTableRequest);
System.out.println(table.getDescription());
```

Sie müssen warten bis DynamoDB die Tabelle erstellt und den Tabellenstatus auf `ACTIVE` setzt. Im Anschluss können Sie die Daten in der Tabelle ablegen.

## Beschreiben einer Tabelle mit einem lokalen sekundären Index
<a name="LSIJavaDocumentAPI.DescribeTableWithIndex"></a>

Um Informationen zu lokalen sekundären Indizes in einer Tabelle zu erhalten, verwenden Sie die Methode `describeTable`. Sie können auf den Namen, das Schlüsselschema und die projizierten Attribute von jedem Index zugreifen.

Im Folgenden sind die Schritte für den Zugriff auf lokale sekundäre Indexinformationen einer Tabelle mithilfe der AWS SDK für Java -Dokument-API aufgeführt.

1. Erstellen Sie eine Instance der `DynamoDB`-Klasse.

1. Erstellen Sie eine Instance der `Table`-Klasse. Sie müssen den Tabellennamen angeben.

1. Rufen Sie die `describeTable`-Methode für das `Table`-Objekt auf.

Im folgenden Java-Codebeispiel werden die vorherigen Schritte veranschaulicht.

**Example**  

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

String tableName = "Music";

Table table = dynamoDB.getTable(tableName);

TableDescription tableDescription = table.describe();

List<LocalSecondaryIndexDescription> localSecondaryIndexes 
    = tableDescription.getLocalSecondaryIndexes();

// This code snippet will work for multiple indexes, even though
// there is only one index in this example.

Iterator<LocalSecondaryIndexDescription> lsiIter = localSecondaryIndexes.iterator();
while (lsiIter.hasNext()) {

    LocalSecondaryIndexDescription lsiDescription = lsiIter.next();
    System.out.println("Info for index " + lsiDescription.getIndexName() + ":");
    Iterator<KeySchemaElement> kseIter = lsiDescription.getKeySchema().iterator();
    while (kseIter.hasNext()) {
        KeySchemaElement kse = kseIter.next();
        System.out.printf("\t%s: %s\n", kse.getAttributeName(), kse.getKeyType());
    }
    Projection projection = lsiDescription.getProjection();
    System.out.println("\tThe projection type is: " + projection.getProjectionType());
    if (projection.getProjectionType().toString().equals("INCLUDE")) {
        System.out.println("\t\tThe non-key projected attributes are: " + projection.getNonKeyAttributes());
    }
}
```

## Abfragen eines lokalen sekundären Indexes
<a name="LSIJavaDocumentAPI.QueryAnIndex"></a>

Sie können die Operation `Query` für einen lokalen sekundären Index genauso nutzen, wie Sie `Query` für eine Tabelle nutzen. Sie müssen den Indexnamen, die Abfragekriterien für den Indexsortierschlüssel und die Attribute angeben, die Sie zurückgeben möchten. In diesem Beispiel ist der Index `AlbumTitleIndex` und der Indexsortierschlüssel `AlbumTitle`. 

Die einzigen zurückgegebenen Attribute sind die, die in den Index projiziert wurden. Sie könnten diese Abfrage ändern, um auch Nicht-Schlüsselattribute auszuwählen, aber dies würde eine Tabellenabrufaktivität erfordern, die relativ teuer ist. Weitere Informationen zum Abrufen von Tabellen finden Sie unter [Attributprojektionen](LSI.md#LSI.Projections).

Im Folgenden werden die Schritte zum Abfragen eines lokalen sekundären Indexes mithilfe der AWS SDK für Java Dokument-API beschrieben. 

1. Erstellen Sie eine Instance der `DynamoDB`-Klasse.

1. Erstellen Sie eine Instance der `Table`-Klasse. Sie müssen den Tabellennamen angeben.

1. Erstellen Sie eine Instance der `Index`-Klasse. Sie müssen den Indexnamen angeben.

1. Rufen Sie die `query`-Methode für die `Index`-Klasse auf.

Im folgenden Java-Codebeispiel werden die vorherigen Schritte veranschaulicht.

**Example**  

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

String tableName = "Music";

Table table = dynamoDB.getTable(tableName);
Index index = table.getIndex("AlbumTitleIndex");

QuerySpec spec = new QuerySpec()
    .withKeyConditionExpression("Artist = :v_artist and AlbumTitle = :v_title")
    .withValueMap(new ValueMap()
        .withString(":v_artist", "Acme Band")
        .withString(":v_title", "Songs About Life"));

ItemCollection<QueryOutcome> items = index.query(spec);

Iterator<Item> itemsIter = items.iterator();

while (itemsIter.hasNext()) {
    Item item = itemsIter.next();
    System.out.println(item.toJSONPretty());
}
```

### Konsistente Lesevorgänge auf einem lokalen sekundären Index
<a name="LSIJavaDocumentAPI.ConsistentReads"></a>

Im Gegensatz zu globalen Sekundärindizes, die nur eventuell konsistente Lesevorgänge unterstützen, unterstützt ein lokaler sekundärer Index sowohl letztlich konsistente als auch stark konsistente Lesevorgänge. Bei einem Strongly-Consistent-Lesevorgang von einem lokalen sekundären Index werden immer die zuletzt aktualisierten Werte zurückgegeben. Wenn die Abfrage zusätzliche Attribute aus der Basistabelle abrufen muss, sind diese abgerufenen Attribute auch in Bezug auf den Index konsistent.

`Query`Verwendet standardmäßig eventuell konsistente Lesevorgänge. Um einen stark konsistenten Lesevorgang anzufordern, setzen Sie `true` in der `ConsistentRead` auf`QuerySpec`. Im folgenden Beispiel wird für `AlbumTitleIndex` Abfragen ein stark konsistenter Lesevorgang verwendet:

**Example**  

```
QuerySpec spec = new QuerySpec()
    .withKeyConditionExpression("Artist = :v_artist and AlbumTitle = :v_title")
    .withValueMap(new ValueMap()
        .withString(":v_artist", "Acme Band")
        .withString(":v_title", "Songs About Life"))
    .withConsistentRead(true);
```

**Anmerkung**  
Ein stark konsistenter Lesevorgang verbraucht eine Lesekapazitätseinheit pro 4 KB zurückgegebener Daten (aufgerundet), wohingegen ein eventuell konsistenter Lesevorgang die Hälfte davon verbraucht. Beispielsweise verbraucht ein stark konsistenter Lesevorgang, der 9 KB an Daten zurückgibt, 3 Lesekapazitätseinheiten (9 KB/4 KB = 2,25, aufgerundet auf 3), während dieselbe Abfrage, die einen eventuell konsistenten Lesevorgang verwendet, 1,5 Lesekapazitätseinheiten verbraucht. Wenn Ihre Anwendung das Lesen von Daten verträgt, die möglicherweise etwas veraltet sind, verwenden Sie eventuell konsistente Lesevorgänge, um Ihre Lesekapazitätsnutzung zu reduzieren. Weitere Informationen finden Sie unter [Lesekapazitätseinheiten](LSI.md#LSI.ThroughputConsiderations.Reads).

# Beispiel: Lokale sekundäre Indizes mit der Java-Dokument-API
<a name="LSIJavaDocumentAPI.Example"></a>

Das folgende Java-Codebeispiel zeigt, wie Sie mit lokalen sekundären Indizes in Amazon DynamoDB arbeiten. Das Beispiel erstellt eine Tabelle mit dem Namen `CustomerOrders` mit `CustomerId` als Partitionsschlüssel und `OrderId` als Sortierschlüssel. Es gibt zwei lokale sekundäre Indizes in dieser Tabelle:
+ `OrderCreationDateIndex` – der Sortierschlüssel ist `OrderCreationDate` und die folgenden Attribute werden in den Index projiziert:
  + `ProductCategory`
  + `ProductName`
  + `OrderStatus`
  + `ShipmentTrackingId`
+ `IsOpenIndex` – der Sortierschlüssel ist `IsOpen` und alle Tabellenattribute werden in den Index projiziert.

Nachdem die `CustomerOrders`-Tabelle erstellt wurde, lädt das Programm die Tabelle mit Daten, die Kundenaufträge darstellen. Mit If Then werden die Daten unter Verwendung der lokalen sekundären Indizes abgefragt. Schließlich löscht das Programm die `CustomerOrders`-Tabelle.

 step-by-stepAnweisungen zum Testen des folgenden Beispiels finden Sie unter[Java-Codebeispiele](CodeSamples.Java.md).

**Example**  

```
package com.example.dynamodb;

import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter;

import java.util.HashMap;
import java.util.Map;

public class DocumentAPILocalSecondaryIndexExample {

    static DynamoDbClient client = DynamoDbClient.create();
    public static String tableName = "CustomerOrders";

    public static void main(String[] args) {
        createTable();
        loadData();
        query(null);
        query("IsOpenIndex");
        query("OrderCreationDateIndex");
        deleteTable(tableName);
    }

    public static void createTable() {
        CreateTableRequest request = CreateTableRequest.builder()
            .tableName(tableName)
            .provisionedThroughput(ProvisionedThroughput.builder()
                .readCapacityUnits(1L)
                .writeCapacityUnits(1L)
                .build())
            .attributeDefinitions(
                AttributeDefinition.builder().attributeName("CustomerId").attributeType(ScalarAttributeType.S).build(),
                AttributeDefinition.builder().attributeName("OrderId").attributeType(ScalarAttributeType.N).build(),
                AttributeDefinition.builder().attributeName("OrderCreationDate").attributeType(ScalarAttributeType.N).build(),
                AttributeDefinition.builder().attributeName("IsOpen").attributeType(ScalarAttributeType.N).build())
            .keySchema(
                KeySchemaElement.builder().attributeName("CustomerId").keyType(KeyType.HASH).build(),
                KeySchemaElement.builder().attributeName("OrderId").keyType(KeyType.RANGE).build())
            .localSecondaryIndexes(
                LocalSecondaryIndex.builder()
                    .indexName("OrderCreationDateIndex")
                    .keySchema(
                        KeySchemaElement.builder().attributeName("CustomerId").keyType(KeyType.HASH).build(),
                        KeySchemaElement.builder().attributeName("OrderCreationDate").keyType(KeyType.RANGE).build())
                    .projection(Projection.builder()
                        .projectionType(ProjectionType.INCLUDE)
                        .nonKeyAttributes("ProductCategory", "ProductName")
                        .build())
                    .build(),
                LocalSecondaryIndex.builder()
                    .indexName("IsOpenIndex")
                    .keySchema(
                        KeySchemaElement.builder().attributeName("CustomerId").keyType(KeyType.HASH).build(),
                        KeySchemaElement.builder().attributeName("IsOpen").keyType(KeyType.RANGE).build())
                    .projection(Projection.builder()
                        .projectionType(ProjectionType.ALL)
                        .build())
                    .build())
            .build();

        System.out.println("Creating table " + tableName + "...");
        client.createTable(request);

        try (DynamoDbWaiter waiter = client.waiter()) {
            WaiterResponse<DescribeTableResponse> response = waiter.waitUntilTableExists(r -> r.tableName(tableName));
            response.matched().response().ifPresent(System.out::println);
        }
    }

    public static void query(String indexName) {
        System.out.println("\n***********************************************************\n");
        System.out.println("Querying table " + tableName + "...");

        if ("IsOpenIndex".equals(indexName)) {
            System.out.println("\nUsing index: '" + indexName + "': Bob's orders that are open.");
            System.out.println("Only a user-specified list of attributes are returned\n");

            Map<String, AttributeValue> values = new HashMap<>();
            values.put(":v_custid", AttributeValue.builder().s("bob@example.com").build());
            values.put(":v_isopen", AttributeValue.builder().n("1").build());

            QueryRequest request = QueryRequest.builder()
                .tableName(tableName)
                .indexName(indexName)
                .keyConditionExpression("CustomerId = :v_custid and IsOpen = :v_isopen")
                .expressionAttributeValues(values)
                .projectionExpression("OrderCreationDate, ProductCategory, ProductName, OrderStatus")
                .build();

            System.out.println("Query: printing results...");
            client.query(request).items().forEach(System.out::println);

        } else if ("OrderCreationDateIndex".equals(indexName)) {
            System.out.println("\nUsing index: '" + indexName + "': Bob's orders that were placed after 01/31/2015.");
            System.out.println("Only the projected attributes are returned\n");

            Map<String, AttributeValue> values = new HashMap<>();
            values.put(":v_custid", AttributeValue.builder().s("bob@example.com").build());
            values.put(":v_orddate", AttributeValue.builder().n("20150131").build());

            QueryRequest request = QueryRequest.builder()
                .tableName(tableName)
                .indexName(indexName)
                .keyConditionExpression("CustomerId = :v_custid and OrderCreationDate >= :v_orddate")
                .expressionAttributeValues(values)
                .select(Select.ALL_PROJECTED_ATTRIBUTES)
                .build();

            System.out.println("Query: printing results...");
            client.query(request).items().forEach(System.out::println);

        } else {
            System.out.println("\nNo index: All of Bob's orders, by OrderId:\n");

            Map<String, AttributeValue> values = new HashMap<>();
            values.put(":v_custid", AttributeValue.builder().s("bob@example.com").build());

            QueryRequest request = QueryRequest.builder()
                .tableName(tableName)
                .keyConditionExpression("CustomerId = :v_custid")
                .expressionAttributeValues(values)
                .build();

            System.out.println("Query: printing results...");
            client.query(request).items().forEach(System.out::println);
        }
    }

    public static void deleteTable(String tableName) {
        System.out.println("Deleting table " + tableName + "...");
        client.deleteTable(DeleteTableRequest.builder().tableName(tableName).build());

        try (DynamoDbWaiter waiter = client.waiter()) {
            waiter.waitUntilTableNotExists(r -> r.tableName(tableName));
        }
    }

    public static void loadData() {
        System.out.println("Loading data into table " + tableName + "...");

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("alice@example.com").build(),
            "OrderId", AttributeValue.builder().n("1").build(),
            "IsOpen", AttributeValue.builder().n("1").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150101").build(),
            "ProductCategory", AttributeValue.builder().s("Book").build(),
            "ProductName", AttributeValue.builder().s("The Great Outdoors").build(),
            "OrderStatus", AttributeValue.builder().s("PACKING ITEMS").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("alice@example.com").build(),
            "OrderId", AttributeValue.builder().n("2").build(),
            "IsOpen", AttributeValue.builder().n("1").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150221").build(),
            "ProductCategory", AttributeValue.builder().s("Bike").build(),
            "ProductName", AttributeValue.builder().s("Super Mountain").build(),
            "OrderStatus", AttributeValue.builder().s("ORDER RECEIVED").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("alice@example.com").build(),
            "OrderId", AttributeValue.builder().n("3").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150304").build(),
            "ProductCategory", AttributeValue.builder().s("Music").build(),
            "ProductName", AttributeValue.builder().s("A Quiet Interlude").build(),
            "OrderStatus", AttributeValue.builder().s("IN TRANSIT").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("176493").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("1").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150111").build(),
            "ProductCategory", AttributeValue.builder().s("Movie").build(),
            "ProductName", AttributeValue.builder().s("Calm Before The Storm").build(),
            "OrderStatus", AttributeValue.builder().s("SHIPPING DELAY").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("859323").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("2").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150124").build(),
            "ProductCategory", AttributeValue.builder().s("Music").build(),
            "ProductName", AttributeValue.builder().s("E-Z Listening").build(),
            "OrderStatus", AttributeValue.builder().s("DELIVERED").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("756943").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("3").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150221").build(),
            "ProductCategory", AttributeValue.builder().s("Music").build(),
            "ProductName", AttributeValue.builder().s("Symphony 9").build(),
            "OrderStatus", AttributeValue.builder().s("DELIVERED").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("645193").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("4").build(),
            "IsOpen", AttributeValue.builder().n("1").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150222").build(),
            "ProductCategory", AttributeValue.builder().s("Hardware").build(),
            "ProductName", AttributeValue.builder().s("Extra Heavy Hammer").build(),
            "OrderStatus", AttributeValue.builder().s("PACKING ITEMS").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("5").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150309").build(),
            "ProductCategory", AttributeValue.builder().s("Book").build(),
            "ProductName", AttributeValue.builder().s("How To Cook").build(),
            "OrderStatus", AttributeValue.builder().s("IN TRANSIT").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("440185").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("6").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150318").build(),
            "ProductCategory", AttributeValue.builder().s("Luggage").build(),
            "ProductName", AttributeValue.builder().s("Really Big Suitcase").build(),
            "OrderStatus", AttributeValue.builder().s("DELIVERED").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("893927").build()));

        putItem(Map.of(
            "CustomerId", AttributeValue.builder().s("bob@example.com").build(),
            "OrderId", AttributeValue.builder().n("7").build(),
            "OrderCreationDate", AttributeValue.builder().n("20150324").build(),
            "ProductCategory", AttributeValue.builder().s("Golf").build(),
            "ProductName", AttributeValue.builder().s("PGA Pro II").build(),
            "OrderStatus", AttributeValue.builder().s("OUT FOR DELIVERY").build(),
            "ShipmentTrackingId", AttributeValue.builder().s("383283").build()));
    }

    private static void putItem(Map<String, AttributeValue> item) {
        client.putItem(PutItemRequest.builder().tableName(tableName).item(item).build());
    }
}
```