

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用項目：Java
<a name="JavaDocumentAPIItemCRUD"></a>

您可以使用 適用於 Java 的 AWS SDK 文件 API 在資料表中的 Amazon DynamoDB 項目上執行典型的建立、讀取、更新和刪除 (CRUD) 操作。

**注意**  
適用於 Java 的開發套件也提供物件持久性模型，讓您將用戶端類別映射至 DynamoDB 資料表。此方法可以減少您必須撰寫的程式碼數量。如需詳細資訊，請參閱 [Java 1.x：DynamoDBMapper](DynamoDBMapper.md)。

本節包含 Java 範例，執行數個 Java 文件 API 項目動作及數個完整的工作範例。

**Topics**
+ [放入項目](#PutDocumentAPIJava)
+ [取得項目](#JavaDocumentAPIGetItem)
+ [批次寫入：放入和刪除多個項目](#BatchWriteDocumentAPIJava)
+ [批次取得：取得多個項目](#JavaDocumentAPIBatchGetItem)
+ [更新項目](#JavaDocumentAPIItemUpdate)
+ [刪除項目](#DeleteMidLevelJava)
+ [範例：使用 適用於 Java 的 AWS SDK 文件 API 的 CRUD 操作](JavaDocumentAPICRUDExample.md)
+ [範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次操作](batch-operation-document-api-java.md)
+ [範例：使用 適用於 Java 的 AWS SDK 文件 API 處理二進位類型屬性](JavaDocumentAPIBinaryTypeExample.md)

## 放入項目
<a name="PutDocumentAPIJava"></a>

`putItem` 方法會將項目存放在資料表中。若已有該項目，其會取代整個項目。若不希望取代整個項目，而是只想要更新特定的屬性，可以使用 `updateItem` 方法。如需詳細資訊，請參閱 [更新項目](#JavaDocumentAPIItemUpdate)。

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;

/**
 * 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 place items into an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client. See the EnhancedPutItem example.
 */
public class PutItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

                Where:
                    tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
                    key - The key used in the Amazon DynamoDB table (for example, Artist).
                    keyval - The key value that represents the item to get (for example, Famous Band).
                    albumTitle - The Album title (for example, AlbumTitle).
                    AlbumTitleValue - The name of the album (for example, Songs About Life ).
                    Awards - The awards column (for example, Awards).
                    AwardVal - The value of the awards (for example, 10).
                    SongTitle - The song title (for example, SongTitle).
                    SongTitleVal - The value of the song title (for example, Happy Day).
                **Warning** This program will  place an item that you specify into a table!
                """;

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

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        String albumTitle = args[3];
        String albumTitleValue = args[4];
        String awards = args[5];
        String awardVal = args[6];
        String songTitle = args[7];
        String songTitleVal = args[8];

        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle,
                songTitleVal);
        System.out.println("Done!");
        ddb.close();
    }

    public static void putItemInTable(DynamoDbClient ddb,
            String tableName,
            String key,
            String keyVal,
            String albumTitle,
            String albumTitleValue,
            String awards,
            String awardVal,
            String songTitle,
            String songTitleVal) {

        HashMap<String, AttributeValue> itemValues = new HashMap<>();
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            PutItemResponse response = ddb.putItem(request);
            System.out.println(tableName + " was successfully updated. The request id is "
                    + response.responseMetadata().requestId());

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

------
#### [ Java v1 ]

請遵循下列步驟：

1. 建立 `DynamoDB` 類別的執行個體。

1. 建立 `Table` 類別的執行個體，代表您要進行作業的資料表。

1. 建立 `Item` 類別的執行個體，代表新的項目。您必須指定新項目的主索引鍵及其屬性。

1. 使用您在前述步驟中所建立的 `putItem`，呼叫 `Table` 物件的 `Item` 方法。

下列 Java 程式碼範例示範上述工作。程式碼會將新的項目寫入 `ProductCatalog` 表。

**Example**  

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

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

在前述範例中，項目具有的屬性為純量 (`String`、`Number`、`Boolean`、`Null`)、集合 (`String Set`) 及文件類型 (`List`、`Map`)。

------

### 指定選用參數
<a name="PutItemJavaDocumentAPIOptions"></a>

除了必要的參數之外，您也可為 `putItem` 方法指定選用的參數。例如，下列 Java 程式碼範例會使用選用參數來指定上傳項目的條件。如果您指定的條件不符合， 會 適用於 Java 的 AWS SDK 擲回 `ConditionalCheckFailedException`。程式碼範例在 `putItem` 方法中指定了下列選用參數：
+ `ConditionExpression` 會定義要求的條件。程式碼定義的條件是，具有相同主索引鍵的現有項目，只有在其 ISBN 屬性等於特定值時，才會被取代。
+ 用於條件中的 `ExpressionAttributeValues` 映射。在本案例中，只需要一次替換：條件表達式中的預留位置 `:val`，會在執行時期更換為實際要查看的 ISBN 值。

下列範例會使用這些選用參數，新增新的書籍項目。

**Example**  

```
Item item = new Item()
    .withPrimaryKey("Id", 104)
    .withString("Title", "Book 104 Title")
    .withString("ISBN", "444-4444444444")
    .withNumber("Price", 20)
    .withStringSet("Authors",
        new HashSet<String>(Arrays.asList("Author1", "Author2")));

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "444-4444444444");

PutItemOutcome outcome = table.putItem(
    item,
    "ISBN = :val", // ConditionExpression parameter
    null,          // ExpressionAttributeNames parameter - we're not using it for this example
    expressionAttributeValues);
```

### PutItem 與 JSON 文件
<a name="PutItemJavaDocumentAPI.JSON"></a>

您可以將 JSON 文件以屬性形式存放在 DynamoDB 資料表中。若要執行此作業，請使用 `Item` 的 `withJSON` 方法。此方法會剖析 JSON 文件，並將每個元素映射到原生的 DynamoDB 資料類型。

假設您希望存放下列 JSON 文件，其包含可完成特定產品訂單的廠商。

**Example**  

```
{
    "V01": {
        "Name": "Acme Books",
        "Offices": [ "Seattle" ]
    },
    "V02": {
        "Name": "New Publishers, Inc.",
        "Offices": ["London", "New York"
        ]
    },
    "V03": {
        "Name": "Better Buy Books",
        "Offices": [ "Tokyo", "Los Angeles", "Sydney"
        ]
    }
}
```

您可以使用 `withJSON` 方法，將此存放在 `ProductCatalog` 表，放在名為 `VendorInfo` 的 `Map` 屬性中。下列 Java 程式碼範例會示範如何執行此作業。

```
// Convert the document into a String.  Must escape all double-quotes.
String vendorDocument = "{"
    + "    \"V01\": {"
    + "        \"Name\": \"Acme Books\","
    + "        \"Offices\": [ \"Seattle\" ]"
    + "    },"
    + "    \"V02\": {"
    + "        \"Name\": \"New Publishers, Inc.\","
    + "        \"Offices\": [ \"London\", \"New York\"" + "]" + "},"
    + "    \"V03\": {"
    + "        \"Name\": \"Better Buy Books\","
    +          "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\""
    + "            ]"
    + "        }"
    + "    }";

Item item = new Item()
    .withPrimaryKey("Id", 210)
    .withString("Title", "Book 210 Title")
    .withString("ISBN", "210-2102102102")
    .withNumber("Price", 30)
    .withJSON("VendorInfo", vendorDocument);

PutItemOutcome outcome = table.putItem(item);
```

## 取得項目
<a name="JavaDocumentAPIGetItem"></a>

若要擷取單一項目，請使用 `getItem` 物件的 `Table` 方法。請遵循下列步驟：

1. 建立 `DynamoDB` 類別的執行個體。

1. 建立 `Table` 類別的執行個體，代表您要進行作業的資料表。

1. 呼叫 `getItem` 執行個體的 `Table` 方法。您必須指定希望擷取之項目的主索引鍵。

下列 Java 程式碼範例示範上述步驟。程式碼會取得具有指定分割區索引鍵的項目。

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

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### 指定選用參數
<a name="GetItemJavaDocumentAPIOptions"></a>

除了必要的參數之外，您也可為 `getItem` 方法指定選用的參數。例如，下列 Java 程式碼範例使用選用方法，只擷取特定的屬性清單，以及指定高度一致性讀取。(若要進一步了解讀取一致性，請參閱「[DynamoDB 讀取一致性](HowItWorks.ReadConsistency.md)」。)

您可以使用 `ProjectionExpression`，只擷取特定的屬性或元素，而非整個項目。`ProjectionExpression` 可以使用文件路徑，指定最上層或巢狀屬性。如需詳細資訊，請參閱 [在 DynamoDB 中使用投影表達式](Expressions.ProjectionExpressions.md)。

`getItem` 方法的參數不會讓您指定讀取一致性。但您可以建立 `GetItemSpec`，它會提供低階 `GetItem` 操作輸入的完整存取。以下程式碼範例會建立 `GetItemSpec`，然後使用該規格做為 `getItem` 方法的輸入。

**Example**  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 206)
    .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
    .withConsistentRead(true);

Item item = table.getItem(spec);

System.out.println(item.toJSONPretty());
```

 若要將 `Item` 以可供人閱讀的格式印出，請使用 `toJSONPretty` 方法。上個範例的輸出類似這樣。

```
{
  "RelatedItems" : [ 341 ],
  "Reviews" : {
    "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ]
  },
  "Id" : 123,
  "Title" : "20-Bicycle 123"
}
```

### GetItem 與 JSON 文件
<a name="GetItemJavaDocumentAPI.JSON"></a>

在 [PutItem 與 JSON 文件](#PutItemJavaDocumentAPI.JSON) 一節中，您將 JSON 文件存放在名為 `VendorInfo` 的 `Map` 屬性中。您可以使用 `getItem` 方法擷取 JSON 格式的整份文件。或者可以使用文件路徑標記法擷取文件中的部分元素。下列 Java 程式碼範例會示範這些技術。

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210);

System.out.println("All vendor info:");
spec.withProjectionExpression("VendorInfo");
System.out.println(table.getItem(spec).toJSON());

System.out.println("A single vendor:");
spec.withProjectionExpression("VendorInfo.V03");
System.out.println(table.getItem(spec).toJSON());

System.out.println("First office location for this vendor:");
spec.withProjectionExpression("VendorInfo.V03.Offices[0]");
System.out.println(table.getItem(spec).toJSON());
```

上個範例的輸出類似這樣。

```
All vendor info:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}}
A single vendor:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}}
First office location for a single vendor:
{"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
```

**注意**  
您可以使用 `toJSON` 方法，將任一項目 (或其屬性) 轉換為格式化為 JSON 格式的字串。下列程式碼會擷取數個最上層及巢狀屬性，然後將結果以 JSON 印出。  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210)
    .withProjectionExpression("VendorInfo.V01, Title, Price");

Item item = table.getItem(spec);
System.out.println(item.toJSON());
```
輸出看起來如下。  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## 批次寫入：放入和刪除多個項目
<a name="BatchWriteDocumentAPIJava"></a>

*批次寫入*表示在一個批次中放入和刪除多個項目。您可利用 `batchWriteItem` 方法，在單一呼叫中對來自一或多個資料表的多個項目執行放入與刪除操作。以下是使用 適用於 Java 的 AWS SDK 文件 API 放置或刪除多個項目的步驟。

1. 建立 `DynamoDB` 類別的執行個體。

1. 建立 `TableWriteItems` 類別的執行個體，其描述針對資料表所有的寫入與刪除操作。若希望用單一批次寫入操作寫入多份資料表，您必須每份資料表都建立一個 `TableWriteItems` 執行個體。

1. 提供您在前述步驟中建立的 `batchWriteItem` 物件，藉以呼叫 `TableWriteItems` 方法。

1. 處理回應。您應該檢查回應中是否傳回任何未經處理的請求項目。如果您達到佈建輸送量配額或遇到一些其他暫時性錯誤，就可能發生這個狀況。此外，DynamoDB 會限制您在請求中指定的請求大小及操作次數。如果您超出這些限制，DynamoDB 會拒絕此請求。如需詳細資訊，請參閱[Amazon DynamoDB 中的配額](ServiceQuotas.md)。

下列 Java 程式碼範例示範上述步驟。範例會在兩份資料表上執行 `batchWriteItem` 操作：`Forum` 和 `Thread`。對應的 `TableWriteItems` 物件會定義下列動作：
+ 在 `Forum` 表中放入一個項目。
+ 在 `Thread` 表中寫入及刪除一個項目。

該程式碼接著會呼叫 `batchWriteItem` 來執行操作。

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

TableWriteItems forumTableWriteItems = new TableWriteItems("Forum")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("Name", "Amazon RDS")
            .withNumber("Threads", 0));

TableWriteItems threadTableWriteItems = new TableWriteItems("Thread")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1")
    .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value");

BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

// Code for checking unprocessed items is omitted in this example
```

如需運作範例，請參閱 [範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次寫入操作](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite)。

## 批次取得：取得多個項目
<a name="JavaDocumentAPIBatchGetItem"></a>

您可利用 `batchGetItem` 方法，從一或多個資料表擷取多個項目。若要擷取單一項目，可以使用 `getItem` 方法。

請遵循下列步驟：

1. 建立 `DynamoDB` 類別的執行個體。

1. 建立 `TableKeysAndAttributes` 類別的執行個體，其描述要從資料表擷取的主索引鍵值清單。若希望用單一批次擷取操作讀取多份資料表，您必須每份資料表都建立一個 `TableKeysAndAttributes` 執行個體。

1. 提供您在前述步驟中建立的 `batchGetItem` 物件，藉以呼叫 `TableKeysAndAttributes` 方法。

下列 Java 程式碼範例示範上述步驟。本範例會從 `Forum` 表擷取兩個項目，從 `Thread` 表擷取三個項目。

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

    TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
    forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject",
    "Amazon DynamoDB","DynamoDB Thread 1",
    "Amazon DynamoDB","DynamoDB Thread 2",
    "Amazon S3","S3 Thread 1");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(
    forumTableKeysAndAttributes, threadTableKeysAndAttributes);

for (String tableName : outcome.getTableItems().keySet()) {
    System.out.println("Items in table " + tableName);
    List<Item> items = outcome.getTableItems().get(tableName);
    for (Item item : items) {
        System.out.println(item);
    }
}
```

### 指定選用參數
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

除了必要的參數之外，您也可在使用 `batchGetItem` 時指定選用的參數。例如，您可為每個定義的 `ProjectionExpression` 提供 `TableKeysAndAttributes`。您如此即可指定要從資料表擷取的屬性。

下列程式碼範例會從 `Forum` 表擷取兩個項目。`withProjectionExpression` 參數會指定只擷取 `Threads` 屬性。

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## 更新項目
<a name="JavaDocumentAPIItemUpdate"></a>

`updateItem` 物件的 `Table` 方法可更新現有的屬性值、新增新的屬性，或是從現有項目中刪除屬性。

`updateItem` 方法的行為如下：
+ 若某項目不存在 (資料表中沒有具備指定主索引鍵的項目)，則 `updateItem` 會在資料表中新增一個新項目。
+ 若項目存在，`updateItem` 會依 `UpdateExpression` 參數的指定，執行更新。

**注意**  
您也可以使用 `putItem` 來「更新」項目。例如，若呼叫 `putItem` 將項目新增至資料表，但具備指定主索引鍵的項目已存在，則 `putItem` 會取代整個項目。如果輸入內並未指定現有項目中的屬性，`putItem` 就會從項目中移除這些屬性。  
一般而言，建議您在想要修改任何項目屬性時，使用 `updateItem`。`updateItem` 方法只會修改您在輸入內指定的項目屬性，而項目內的其他屬性則保持不變。

請遵循下列步驟：

1. 建立 `Table` 類別的執行個體，代表您要使用的資料表。

1. 呼叫 `updateTable` 執行個體的 `Table` 方法。您必須指定要擷取之項目的主索引鍵，以及描述要修改之屬性及修改方式的 `UpdateExpression`。

下列 Java 程式碼範例示範上述工作。程式碼會更新 `ProductCatalog` 表中的書籍項目。其會將新的作者新增到 `Authors` 集合中，並刪除現有的 `ISBN` 屬性。它也會將價格減一。

`ExpressionAttributeValues` 映射內容會用於 `UpdateExpression` 中。預留位置 `:val1` 與 `:val2`，會於執行時期由 `Authors` 和 `Price` 的實際值取代。

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

Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Authors");
expressionAttributeNames.put("#P", "Price");
expressionAttributeNames.put("#I", "ISBN");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1",
    new HashSet<String>(Arrays.asList("Author YY","Author ZZ")));
expressionAttributeValues.put(":val2", 1);   //Price

UpdateItemOutcome outcome =  table.updateItem(
    "Id",          // key attribute name
    101,           // key attribute value
    "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### 指定選用參數
<a name="UpdateItemJavaDocumentAPIOptions"></a>

除了必要的參數之外，您也可以為 `updateItem` 方法指定選用參數，包括必須滿足才會發生更新的條件。如果您指定的條件不符合， 會 適用於 Java 的 AWS SDK 擲回 `ConditionalCheckFailedException`。例如，下列 Java 程式碼範例會依據條件，將書籍項目的價格更新為 25。其會指定 `ConditionExpression`，指出只有在現有價格為 20 時才更新價格。

**Example**  

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#P", "Price");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", 25);  // update Price to 25...
expressionAttributeValues.put(":val2", 20);  //...but only if existing Price is 20

UpdateItemOutcome outcome = table.updateItem(
    new PrimaryKey("Id",101),
    "set #P = :val1", // UpdateExpression
    "#P = :val2",     // ConditionExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### 原子計數器
<a name="AtomicCounterJavaDocumentAPI"></a>

您可以使用 `updateItem` 來實作原子計數器以增加或減少現有屬性的值，卻不干擾其他寫入請求。若要增加原子計數器，請於使用 `UpdateExpression` 時搭配 `set` 動作，將數值新增到類型為 `Number` 的現有屬性。

下列範例示範這項作業，將 `Quantity` 屬性加 1。其也同時示範在 `ExpressionAttributeNames` 中使用 `UpdateExpression` 參數。

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#p", "PageCount");

Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);

UpdateItemOutcome outcome = table.updateItem(
    "Id", 121,
    "set #p = #p + :val",
    expressionAttributeNames,
    expressionAttributeValues);
```

## 刪除項目
<a name="DeleteMidLevelJava"></a>

`deleteItem` 方法會從資料表刪除項目。您必須提供要刪除項目的主索引鍵。

請遵循下列步驟：

1. 建立 `DynamoDB` 用戶端執行個體。

1. 提供希望刪除之項目的索引鍵，可呼叫 `deleteItem` 方法。

下列 Java 範例示範這些任務。

**Example**  

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

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### 指定選用參數
<a name="DeleteItemJavaDocumentAPIOptions"></a>

您可以為 `deleteItem` 指定選用參數。例如，下列 Java 程式碼範例指定 `ConditionExpression`，指出只有當書籍不再出版時 (`InPublication` 屬性為 false)，才能刪除 `ProductCatalog` 中的書籍項目。

**Example**  

```
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", false);

DeleteItemOutcome outcome = table.deleteItem("Id",103,
    "InPublication = :val",
    null, // ExpressionAttributeNames - not used in this example
    expressionAttributeValues);
```

# 範例：使用 適用於 Java 的 AWS SDK 文件 API 的 CRUD 操作
<a name="JavaDocumentAPICRUDExample"></a>

下列程式碼範例示範對 Amazon DynamoDB 項目執行 CRUD 操作。此範例會建立項目、擷取該項目、執行數次更新，最後刪除該項目。

**注意**  
適用於 Java 的開發套件也提供物件持久性模型，讓您將用戶端類別映射至 DynamoDB 資料表。此方法可以減少您必須撰寫的程式碼數量。如需詳細資訊，請參閱 [Java 1.x：DynamoDBMapper](DynamoDBMapper.md)。

**注意**  
此程式碼範例假設您已根據 [在 DynamoDB 中建立資料表，以及載入程式碼範例的資料](SampleData.md) 一節的說明將資料載入 DynamoDB 的帳戶。  
如需執行下列範例的逐步說明，請參閱「[Java 程式碼範例](CodeSamples.Java.md)」。

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;

public class DocumentAPIItemCRUDExample {

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

    static String tableName = "ProductCatalog";

    public static void main(String[] args) throws IOException {

        createItems();

        retrieveItem();

        // Perform various updates.
        updateMultipleAttributes();
        updateAddNewAttribute();
        updateExistingAttributeConditionally();

        // Delete the item.
        deleteItem();

    }

    private static void createItems() {

        Table table = dynamoDB.getTable(tableName);
        try {

            Item item = new Item().withPrimaryKey("Id", 120).withString("Title", "Book 120 Title")
                    .withString("ISBN", "120-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author12", "Author22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", false).withString("ProductCategory", "Book");
            table.putItem(item);

            item = new Item().withPrimaryKey("Id", 121).withString("Title", "Book 121 Title")
                    .withString("ISBN", "121-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", true).withString("ProductCategory", "Book");
            table.putItem(item);

        } catch (Exception e) {
            System.err.println("Create items failed.");
            System.err.println(e.getMessage());

        }
    }

    private static void retrieveItem() {
        Table table = dynamoDB.getTable(tableName);

        try {

            Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null);

            System.out.println("Printing item after retrieving it....");
            System.out.println(item.toJSONPretty());

        } catch (Exception e) {
            System.err.println("GetItem failed.");
            System.err.println(e.getMessage());
        }

    }

    private static void updateAddNewAttribute() {
        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 121)
                    .withUpdateExpression("set #na = :val1").withNameMap(new NameMap().with("#na", "NewAttribute"))
                    .withValueMap(new ValueMap().withString(":val1", "Some value"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after adding new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to add new attribute in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void updateMultipleAttributes() {

        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withUpdateExpression("add #a :val1 set #na=:val2")
                    .withNameMap(new NameMap().with("#a", "Authors").with("#na", "NewAttribute"))
                    .withValueMap(
                            new ValueMap().withStringSet(":val1", "Author YY", "Author ZZ").withString(":val2",
                                    "someValue"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after multiple attribute update...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to update multiple attributes in " + tableName);
            System.err.println(e.getMessage());

        }
    }

    private static void updateExistingAttributeConditionally() {

        Table table = dynamoDB.getTable(tableName);

        try {

            // Specify the desired price (25.00) and also the condition (price =
            // 20.00)

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withReturnValues(ReturnValue.ALL_NEW).withUpdateExpression("set #p = :val1")
                    .withConditionExpression("#p = :val2").withNameMap(new NameMap().with("#p", "Price"))
                    .withValueMap(new ValueMap().withNumber(":val1", 25).withNumber(":val2", 20));

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after conditional update to new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error updating item in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void deleteItem() {

        Table table = dynamoDB.getTable(tableName);

        try {

            DeleteItemSpec deleteItemSpec = new DeleteItemSpec().withPrimaryKey("Id", 120)
                    .withConditionExpression("#ip = :val").withNameMap(new NameMap().with("#ip", "InPublication"))
                    .withValueMap(new ValueMap().withBoolean(":val", false)).withReturnValues(ReturnValue.ALL_OLD);

            DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec);

            // Check the response.
            System.out.println("Printing item that was deleted...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error deleting item in " + tableName);
            System.err.println(e.getMessage());
        }
    }
}
```

# 範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次操作
<a name="batch-operation-document-api-java"></a>

本節提供使用 適用於 Java 的 AWS SDK 文件 API 在 Amazon DynamoDB 中批次寫入和批次取得操作的範例。

**注意**  
適用於 Java 的開發套件也提供物件持久性模型，讓您將用戶端類別映射至 DynamoDB 資料表。此方法可以減少您必須撰寫的程式碼數量。如需詳細資訊，請參閱[Java 1.x：DynamoDBMapper](DynamoDBMapper.md)。

**Topics**
+ [範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次寫入操作](#JavaDocumentAPIBatchWrite)
+ [範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次取得操作](#JavaDocumentAPIBatchGet)

## 範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次寫入操作
<a name="JavaDocumentAPIBatchWrite"></a>

下列 Java 程式碼範例使用 `batchWriteItem` 方法，執行下列寫入及刪除操作：
+ 在 `Forum` 表中放入一個項目。
+ 在 `Thread` 表中放入一個項目並刪除一個項目。

建立您的批次寫入請求時，您可以對一或多個資料表指定任何次數的放入和刪除請求。但 `batchWriteItem` 對於批次寫入要求的大小，以及單一批次寫入操作中的寫入及刪除操作次數有所限制。如果您的請求超出這些限制，您的請求會被拒絕。如果您的資料表因佈建輸送量不足而無法處理此請求，回應就會傳回未經處理的請求項目。

以下範例會檢查回應，查看它是否有任何未經處理的請求項目。若的確有所限制，其會重頭迴圈並會重新傳送 `batchWriteItem` 請求，同時附上請求中未經處理的項目。如已按照本指南中的範例操作，應已建立 `Forum` 和 `Thread` 資料表。您也可利用程式設計方式，建立這些資料表並上傳範例資料。如需詳細資訊，請參閱 [使用 建立範例資料表和上傳資料 適用於 Java 的 AWS SDK](AppendixSampleDataCodeJava.md)。

如需測試下列範例的逐步說明，請參閱 [Java 程式碼範例](CodeSamples.Java.md)。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableWriteItems;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;

public class DocumentAPIBatchWrite {

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

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {

        writeMultipleItemsBatchWrite();

    }

    private static void writeMultipleItemsBatchWrite() {
        try {

            // Add a new item to Forum
            TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) // Forum
                    .withItemsToPut(new Item().withPrimaryKey("Name", "Amazon RDS").withNumber("Threads", 0));

            // Add a new item, and delete an existing item, from Thread
            // This table has a partition key and range key, so need to specify
            // both of them
            TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName)
                    .withItemsToPut(
                            new Item().withPrimaryKey("ForumName", "Amazon RDS", "Subject", "Amazon RDS Thread 1")
                                    .withString("Message", "ElastiCache Thread 1 message")
                                    .withStringSet("Tags", new HashSet<String>(Arrays.asList("cache", "in-memory"))))
                    .withHashAndRangeKeysToDelete("ForumName", "Subject", "Amazon S3", "S3 Thread 100");

            System.out.println("Making the request.");
            BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

            do {

                // Check for unprocessed keys which could happen if you exceed
                // provisioned throughput

                Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems();

                if (outcome.getUnprocessedItems().size() == 0) {
                    System.out.println("No unprocessed items found");
                } else {
                    System.out.println("Retrieving the unprocessed items");
                    outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems);
                }

            } while (outcome.getUnprocessedItems().size() > 0);

        } catch (Exception e) {
            System.err.println("Failed to retrieve items: ");
            e.printStackTrace(System.err);
        }

    }

}
```

## 範例：使用 適用於 Java 的 AWS SDK 文件 API 的批次取得操作
<a name="JavaDocumentAPIBatchGet"></a>

下列 Java 程式碼範例使用 `batchGetItem` 方法，從 `Forum` 和 `Thread` 表擷取多個項目。`BatchGetItemRequest` 指定每個要擷取之項目的資料表名稱與索引鍵清單。此範例處理回應的方式是列印已擷取的項目。

**注意**  
此程式碼範例假設您已根據 [在 DynamoDB 中建立資料表，以及載入程式碼範例的資料](SampleData.md) 一節的說明將資料載入 DynamoDB 的帳戶。  
如需執行下列範例的逐步說明，請參閱「[Java 程式碼範例](CodeSamples.Java.md)」。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

public class DocumentAPIBatchGet {
    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {
        retrieveMultipleItemsBatchGet();
    }

    private static void retrieveMultipleItemsBatchGet() {

        try {

            TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
            // Add a partition key
            forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB");

            TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
            // Add a partition key and a sort key
            threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB",
                    "DynamoDB Thread 1", "Amazon DynamoDB", "DynamoDB Thread 2", "Amazon S3", "S3 Thread 1");

            System.out.println("Making the request.");

            BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes,
                    threadTableKeysAndAttributes);

            Map<String, KeysAndAttributes> unprocessed = null;

            do {
                for (String tableName : outcome.getTableItems().keySet()) {
                    System.out.println("Items in table " + tableName);
                    List<Item> items = outcome.getTableItems().get(tableName);
                    for (Item item : items) {
                        System.out.println(item.toJSONPretty());
                    }
                }

                // Check for unprocessed keys which could happen if you exceed
                // provisioned
                // throughput or reach the limit on response size.
                unprocessed = outcome.getUnprocessedKeys();

                if (unprocessed.isEmpty()) {
                    System.out.println("No unprocessed keys found");
                } else {
                    System.out.println("Retrieving the unprocessed keys");
                    outcome = dynamoDB.batchGetItemUnprocessed(unprocessed);
                }

            } while (!unprocessed.isEmpty());

        } catch (Exception e) {
            System.err.println("Failed to retrieve items.");
            System.err.println(e.getMessage());
        }

    }

}
```

# 範例：使用 適用於 Java 的 AWS SDK 文件 API 處理二進位類型屬性
<a name="JavaDocumentAPIBinaryTypeExample"></a>

下列 Java 程式碼範例示範二進位類型屬性的處理。範例會將項目新增至 `Reply` 表。該項目包含存放壓縮資料的二進位類型屬性 (`ExtendedMessage`)。範例接著會擷取項目，並列印所有屬性值。為了進行示範，該範例使用 `GZIPOutputStream` 類別來壓縮範例串流，並將其指派給 `ExtendedMessage` 屬性。擷取二進制屬性時，其便會使用 `GZIPInputStream` 類別進行解壓縮。

**注意**  
適用於 Java 的開發套件也提供物件持久性模型，讓您將用戶端類別映射至 DynamoDB 資料表。此方法可以減少您必須撰寫的程式碼數量。如需詳細資訊，請參閱 [Java 1.x：DynamoDBMapper](DynamoDBMapper.md)。

如已完成[在 DynamoDB 中建立資料表，以及載入程式碼範例的資料](SampleData.md)一節，應已建立 `Reply` 表。您也可以透過編寫程式的方式建立此資料表。如需詳細資訊，請參閱 [使用 建立範例資料表和上傳資料 適用於 Java 的 AWS SDK](AppendixSampleDataCodeJava.md)。

如需測試下列範例的逐步說明，請參閱 [Java 程式碼範例](CodeSamples.Java.md)。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec;

public class DocumentAPIItemBinaryExample {

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

    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public static void main(String[] args) throws IOException {
        try {

            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";

            dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            String replyDateTime = dateFormatter.format(new Date());

            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);

            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);

            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);
            e.printStackTrace(System.err);
        }
    }

    public static void createItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";

        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());

        table.putItem(new Item().withPrimaryKey("Id", threadId).withString("ReplyDateTime", replyDateTime)
                .withString("Message", "Long message follows").withBinary("ExtendedMessage", compressedMessage)
                .withString("PostedBy", "User A"));
    }

    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)
                .withConsistentRead(true);

        Item item = table.getItem(spec);

        // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));

        System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: "
                + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n"
                + " Message: "
                + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    }

    public static void deleteItem(String threadId, String replyDateTime) {

        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    }

    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        os.write(input.getBytes("UTF-8"));
        os.close();
        baos.close();
        byte[] compressedBytes = baos.toByteArray();

        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling
        // ByteBuffer.wrap(compressedBytes);
        // However, the longer form below shows the importance of resetting the
        // position of the buffer
        // back to the beginning of the buffer if you are writing bytes directly
        // to it, since the SDK
        // will consider only the bytes after the current position when sending
        // data to DynamoDB.
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer
                            // to the beginning
        return buffer;
    }

    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);

        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length = is.read(buffer, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        }

        String result = new String(baos.toByteArray(), "UTF-8");

        is.close();
        baos.close();
        bais.close();

        return result;
    }
}
```