

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

# DynamoDB 的 AWS SDK 支援概觀
<a name="Programming.SDKOverview"></a>

下圖提供使用 AWS SDKs 的 Amazon DynamoDB 應用程式程式設計的高階概觀。

![\[搭配 SDK 使用 DynamoDB 的程式設計模型。 AWS SDKs\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. 您可以使用適用於程式設計語言的 AWS 開發套件撰寫應用程式。

1. 每個 AWS SDK 提供一或多個程式設計界面，以使用 DynamoDB。可用的特定界面取決於您使用的程式設計語言和 AWS SDK。選項包括：
   + [使用 DynamoDB 的低階介面](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [使用 DynamoDB 的文件介面](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [使用 DynamoDB 的物件持久性介面](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [高階介面](HigherLevelInterfaces.md)

1. SDK AWS 建構 HTTP(S) 請求，以搭配低階 DynamoDB API 使用。

1. SDK 會將請求 AWS 傳送至 DynamoDB 端點。

1. DynamoDB 會執行請求。如果請求成功，DynamoDB 會傳回 HTTP 200 回應代碼 (OK)。如果請求不成功，DynamoDB 會傳回 HTTP 錯誤代碼和錯誤訊息。

1.  AWS SDK 會處理回應並將其傳播回您的應用程式。

每個 AWS SDKs都為您的應用程式提供重要的服務，包括下列項目：
+ 格式化 HTTP(S) 請求和序列化請求參數。
+ 為每個請求產生密碼編譯簽章。
+ 將請求轉寄至 DynamoDB 端點，並接收來自 DynamoDB 的回應。
+ 從這些回應中提取結果。
+ 在出現錯誤的情況下實作基本重試邏輯。

您不需要為上述任何任務編寫程式碼。

**注意**  
如需 AWS SDKs的詳細資訊，包括安裝指示和文件，請參閱[適用於 Amazon Web Services 的工具](https://aws.amazon.com/tools)。

## AWS 支援帳戶型端點的 SDK
<a name="Programming.SDKs.endpoints"></a>

AWS 已在 AWS 2024 年 9 月 4 日推出適用於 DynamoDB 帳戶型端點的 SDK 支援，從適用於 Java 的 AWS SDK V1 開始。這些新端點 AWS 有助於確保高效能和可擴展性。更新的 SDK 會自動使用格式為 `https://(account-id).ddb.(region).amazonaws.com` 的新端點。

如果您使用 SDK 用戶端的單一執行個體向多個帳戶提出請求，您的應用程式重複使用連線的機會會較少。 AWS 建議修改您的應用程式，以連接至每個 SDK 用戶端執行個體的較少帳戶。另一種方法是將 SDK 用戶端設定為使用 `ACCOUNT_ID_ENDPOINT_MODE` 設定繼續使用區域端點，如 [https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html)中所述。

# 使用 DynamoDB 的程式設計介面
<a name="Programming.SDKs.Interfaces"></a>

每個 [AWS 軟體開發套件](https://aws.amazon.com/tools)提供一或多個程式化介面，以便與 Amazon DynamoDB 搭配使用。這些介面範圍從簡單的低階 DynamoDB 包裝函式到物件導向的持久性層。可用的界面會根據您使用的 AWS SDK 和程式設計語言而有所不同。

![\[可用於 DynamoDB 的不同 AWS SDKs的程式設計界面。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


下一節會以 適用於 Java 的 AWS SDK 為範例來重點介紹一些可用的介面。(並非全部介面都可用於所有 AWS 軟體開發套件。)

**Topics**
+ [使用 DynamoDB 的低階介面](#Programming.SDKs.Interfaces.LowLevel)
+ [使用 DynamoDB 的文件介面](#Programming.SDKs.Interfaces.Document)
+ [使用 DynamoDB 的物件持久性介面](#Programming.SDKs.Interfaces.Mapper)

## 使用 DynamoDB 的低階介面
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

每個語言特定的 AWS SDK 都為 Amazon DynamoDB 提供低階介面，方法與低階 DynamoDB API 請求非常相似。

在某些情況下，您需要識別使用 [資料類型描述項](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors) 的屬性資料類型，例如，適用於字串的 `S` 或適用於數字的 `N`。

**注意**  
每種語言特定的 AWS 軟體開發套件都提供低階介面。

下列 Java 程式使用 適用於 Java 的 AWS SDK的低階介面。

### 低階介面範例
<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);
        }
    }
}
```

## 使用 DynamoDB 的文件介面
<a name="Programming.SDKs.Interfaces.Document"></a>

 AWS SDKs提供文件界面，可讓您對資料表和索引執行資料平面操作 （建立、讀取、更新、刪除）。使用文件介面時，您不需要指定 [資料類型描述項](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors)。資料類型是由資料本身的語義隱含的。這些 AWS SDKs也提供方法，可輕鬆將 JSON 文件轉換為原生 Amazon DynamoDB 資料類型。

**注意**  
文件界面可在適用於 [ 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) 和 [JavaScript SDK](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/) AWS SDKs 中使用。

下列 Java 程式使用 適用於 Java 的 AWS SDK的文件介面。程式會建立代表 `Music` 資料表的 `Table` 物件，然後要求該物件使用 `GetItem` 來擷取歌曲。然後程式會列印歌曲發行的年份。

`software.amazon.dynamodb.document.DynamoDB` 類別會實作 DynamoDB 文件介面。請注意 `DynamoDB` 作為低階用戶端 (`AmazonDynamoDB`) 包裝函式的方式。

### 文件介面範例
<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);

    }
}
```

## 使用 DynamoDB 的物件持久性介面
<a name="Programming.SDKs.Interfaces.Mapper"></a>

 AWS SDKs提供物件持久性界面，您不會在其中直接執行資料平面操作。反之，您要建立代表 Amazon DynamoDB 資料表和索引中項目的物件，並且僅與這些物件互動。這允許您編寫以物件為中心的程式碼，而不是以資料庫為中心的程式碼。

**注意**  
適用於 Java 和 .NET AWS SDKs 中提供物件持久性界面。如需詳細資訊，請參閱適用於 DynamoDB 的 [適用於 DynamoDB 的更高階程式設計界面](HigherLevelInterfaces.md)。

### 物件持久性介面
<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();
    }
}
```

# 適用於 DynamoDB 的更高階程式設計界面
<a name="HigherLevelInterfaces"></a>

 AWS SDKs 為應用程式提供使用 Amazon DynamoDB 的低階界面。這些用戶端類別和方法直接對應至低階 DynamoDB API。不過，當需要將複雜的資料類型映射至資料庫資料表中的項目時，許多開發人員會遭遇到網路斷線的感覺，或*阻抗不符*。使用低階資料庫界面，開發人員必須撰寫讀取或寫入物件資料至資料庫資料表的方法，反之亦然。物件類型和資料庫表格每個組合所需的額外程式碼數量似乎非常大。

為了簡化開發，適用於 Java 和 .NET AWS SDKs 提供額外的介面，具有更高層級的抽象。DynamoDB 的較高階界面可讓您定義程式中的物件與存放這些物件資料的資料庫表格之間的關係。定義此映射之後，您可以呼叫簡單的物件方法 (例如 `save`、`load` 或 `delete`)，也可以代表您自動叫用基礎低階 DynamoDB 操作。這允許您編寫以物件為中心的程式碼，而不是以資料庫為中心的程式碼。

DynamoDB 的高階程式設計界面可在適用於 Java 和 .NET AWS SDKs 中使用。

**Java**
+ [Java 1.x：DynamoDBMapper](DynamoDBMapper.md)
+ [Java 2.x：DynamoDB 增強型用戶端](DynamoDBEnhanced.md)

**.NET**
+ [在 DynamoDB 中使用 .NET 文件模型](DotNetSDKMidLevel.md)
+ [使用 .NET 物件持久性模型和 DynamoDB](DotNetSDKHighLevel.md)

# Java 1.x：DynamoDBMapper
<a name="DynamoDBMapper"></a>

**注意**  
適用於 Java 的 SDK 有兩個版本：1.x 和 2.x。1.x 版本已於 2024 年 1 月 12 日[宣布](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/)終止支援。該版本將於 2025 年 12 月 31 日到期並終止支援。我們強烈建議您在新的開發作業使用 2.x 版本。

 適用於 Java 的 AWS SDK 提供 `DynamoDBMapper`類別，可讓您將用戶端類別映射至 Amazon DynamoDB 資料表。若要使用 `DynamoDBMapper`，請定義 DynamoDB 資料表中項目與程式碼中其對應物件執行個體之間的關係。`DynamoDBMapper` 類別也讓您執行各種建立、讀取、更新和對項目進行刪除 (CRUD) 操作，以及執行查詢和掃描資料表。

**Topics**
+ [DynamoDBMapper Class](DynamoDBMapper.Methods.md)
+ [適用於 Java 的 DynamoDBMapper 支援的資料類型](DynamoDBMapper.DataTypes.md)
+ [適用於 DynamoDB 的 Java 註釋](DynamoDBMapper.Annotations.md)
+ [DynamoDBMapper 的選用組態設定](DynamoDBMapper.OptionalConfig.md)
+ [含版本編號的 DynamoDB 及樂觀鎖定](DynamoDBMapper.OptimisticLocking.md)
+ [在 DynamoDB 中映射任意資料](DynamoDBMapper.ArbitraryDataMapping.md)
+ [DynamoDBMapper 範例](DynamoDBMapper.Examples.md)

**注意**  
`DynamoDBMapper` 類別不允許您建立、更新或刪除資料表。若要執行這些任務，請改為使用低階適用於 Java 的開發套件介面。

適用於 Java 的開發套件提供一組註釋類型，讓您可以將類別映射至資料表。例如，考量其 `Id` 為分割區索引鍵的 `ProductCatalog` 資料表。

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

您可以將用戶端應用程式中的類別映射至 `ProductCatalog` 資料表，如下列 Java 程式碼所示。此程式碼定義名為 `CatalogItem` 的純舊 Java 物件 (POJO)，而此物件使用註釋將物件欄件映射至 DynamoDB 屬性名稱。

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

在上述程式碼中，`@DynamoDBTable` 註釋會將 `CatalogItem` 類別映射至 `ProductCatalog` 資料表。您可以將個別類別執行個體存放為資料表中的項目。在類別定義中，`@DynamoDBHashKey` 註釋會將 `Id` 屬性映射至主索引鍵。

類別屬性預設會映射至資料表中的相同名稱屬性。`Title` 和 `ISBN` 屬性會映射至資料表中的相同名稱屬性。

DynamoDB 屬性的名稱符合類別中所宣告屬性的名稱時，`@DynamoDBAttribute` 註釋是選用項目。它們不同時，請搭配使用此註釋與 `attributeName` 參數，指定此屬性所對應的 DynamoDB 屬性。

在上述範例中，將 `@DynamoDBAttribute` 註釋新增至每個屬性，確保屬性名稱完全符合前個步驟中所建立的資料表，並與本指南的其他程式碼範例中所使用的屬性名稱一致。

類別定義可以有未映射至資料表中任何屬性的屬性。您可以新增 `@DynamoDBIgnore` 註釋來識別這些屬性。在上述範例中，`SomeProp` 屬性會標上 `@DynamoDBIgnore` 註釋。當您將 `CatalogItem` 執行個體上傳至資料表時，`DynamoDBMapper` 執行個體不會包含 `SomeProp` 屬性。此外，當您從資料表中擷取項目時，映射器不會傳回此屬性。

在您定義映射類別之後，可以使用 `DynamoDBMapper` 方法，將該類別的執行個體寫入至 `Catalog` 資料表中的對應項目。以下程式碼範例會示範此技術。

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

下列程式碼範例示範如何擷取項目以及存取它的一些屬性：

```
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` 提供直觀且自然的方式來處理 Java 內的 DynamoDB 資料。它也提供數項內建功能；例如，樂觀鎖定、ACID 交易、自動產生的分割區索引鍵和排序索引鍵值，以及物件版本控制。

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



`DynamoDBMapper` 類別是 Amazon DynamoDB 的進入點。它提供 DynamoDB 端點的存取，也讓您可以存取多個資料表中的資料。它也讓您執行各種建立、讀取、更新和對項目進行刪除 (CRUD) 操作，以及執行查詢和掃描資料表。此類別提供下列使用 DynamoDB 的方法。

如需對應的 Javadoc 文件，請參閱《適用於 Java 的 AWS SDK API 參考》**中的 [DynamoDBMapper](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html)。

**Topics**
+ [save](#DynamoDBMapper.Methods.save)
+ [load](#DynamoDBMapper.Methods.load)
+ [delete](#DynamoDBMapper.Methods.delete)
+ [query](#DynamoDBMapper.Methods.query)
+ [queryPage](#DynamoDBMapper.Methods.queryPage)
+ [掃描](#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)
+ [generateCreateTableRequest](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [createS3Link](#DynamoDBMapper.Methods.createS3Link)
+ [getS3ClientCache](#DynamoDBMapper.Methods.getS3ClientCache)

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

將指定的物件儲存至資料表。您要儲存的物件是此方法的唯一必要參數。您可以使用 `DynamoDBMapperConfig` 物件來提供選用的組態參數。

如果具有相同主索引鍵的項目不存在，則此方法會在資料表中建立新的項目。如果具有相同主索引鍵的項目存在，則會更新現有項目。如果分割區索引鍵和排序索引鍵的類型是字串，並且標註 `@DynamoDBAutoGeneratedKey`，則會將隨機全域唯一識別符 (UUID) 授予它們 (若未初始化)。標註 `@DynamoDBVersionAttribute` 的版本欄位會遞增一。此外，如果更新版本欄位或產生索引鍵，則會因這項操作而更新傳入的物件。

根據預設，只會更新對應至已映射類別屬性的屬性。項目上的任何其他現有屬性則不受影響。不過，如果您指定 `SaveBehavior.CLOBBER`，則可以強制完全覆寫項目。

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

如果您已啟用版本控制，則用戶端與伺服器端項目版本必須相符。不過，如果使用 `SaveBehavior.CLOBBER` 選項，則版本不需要相符。如需版本控制的詳細資訊，請參閱「[含版本編號的 DynamoDB 及樂觀鎖定](DynamoDBMapper.OptimisticLocking.md)」。

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

從資料表擷取項目。您必須提供要擷取之項目的主索引鍵。您可以使用 `DynamoDBMapperConfig` 物件來提供選用的組態參數。例如，您可以選擇性地請求高度一致性讀取，確保此方法只擷取最新的項目數值，如下列 Java 陳述式所示。

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

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

DynamoDB 預設會傳回數值最終一致的項目。如需 DynamoDB 最終一致性模式的資訊，請參閱 [DynamoDB 讀取一致性](HowItWorks.ReadConsistency.md)。

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

刪除資料表中的項目。您必須傳入已映射類別的物件執行個體。

如果您已啟用版本控制，則用戶端與伺服器端項目版本必須相符。不過，如果使用 `SaveBehavior.CLOBBER` 選項，則版本不需要相符。如需版本控制的詳細資訊，請參閱「[含版本編號的 DynamoDB 及樂觀鎖定](DynamoDBMapper.OptimisticLocking.md)」。

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

查詢資料表或次要索引。

假設您有一個存放論壇主題回覆的 `Reply` 資料表。每個對話主旨都可以有零個以上的回覆。`Reply` 資料表的主索引鍵包含 `Id` 和 `ReplyDateTime` 欄位；其中，`Id` 是分割區索引鍵，而 `ReplyDateTime` 是主索引鍵的排序索引鍵。

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

假設您已建立 `Reply` 類別與 DynamoDB 中對應 `Reply` 資料表之間的映射。下列 Java 程式碼使用 `DynamoDBMapper` 來尋找特定對話主旨在過去兩週的所有回覆。

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

查詢會傳回 `Reply` 物件的集合。

`query` 方法預設會傳回「延遲載入」集合。它一開始只會傳回一頁的結果，然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目，請逐一查看 `latestReplies` 集合。

請注意，在集合上呼叫 `size()` 方法將會載入所有結果，以提供準確的計數。這可能會導致耗用大量已佈建的輸送量，而在非常大型的資料表上可能甚至會耗盡 JVM 中的所有記憶體。

若要查詢索引，您必須先將索引建模為映射器類別。假設 `Reply` 資料表有一個名為 *PostedBy-Message-Index* 的全域次要索引。此索引的分割區索引鍵是 `PostedBy`，而排序索引鍵是 `Message`。索引中項目的類別定義將會如下。

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

`@DynamoDBTable` 註釋指出此索引與 `Reply` 資料表建立關聯。`@DynamoDBIndexHashKey` 註釋表示索引的分割區索引鍵 (*PostedBy*)，而 `@DynamoDBIndexRangeKey` 表示索引的排序索引鍵 (*Message*)。

您現在可以使用 `DynamoDBMapper` 來查詢索引，並擷取特定使用者所張貼的訊息子集。如果資料表和索引之間沒有衝突的映射，且映射器中已建立映射，則不需要指定索引名稱。映射器將根據主索引鍵和排序索引鍵推論。下列程式碼會查詢全域次要索引。因為全域次要索引支援最終一致讀取，但不支援高度一致性讀取，所以必須指定 `withConsistentRead(false)`。

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

查詢會傳回 `PostedByMessage` 物件的集合。

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

查詢資料表或次要索引，並傳回單頁的相符結果。與使用 `query` 方法相同，您必須指定分割區索引鍵值以及套用至排序索引鍵屬性的查詢篩選條件。不過，`queryPage` 只會傳回第一「頁」的資料；亦即，符合 1 MB 的資料量 

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

掃描整個資料表或次要索引。您可以選擇性地指定 `FilterExpression` 來篩選結果集。

假設您有一個存放論壇主題回覆的 `Reply` 資料表。每個對話主旨都可以有零個以上的回覆。`Reply` 資料表的主索引鍵包含 `Id` 和 `ReplyDateTime` 欄位；其中，`Id` 是分割區索引鍵，而 `ReplyDateTime` 是主索引鍵的排序索引鍵。

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

如果您已將 Java 類別映射至 `Reply` 資料表，則可以使用 `DynamoDBMapper` 來掃描資料表。例如，下列 Java 程式碼會掃描整個 `Reply` 資料表，而且只會傳回特定一年的回覆。

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

`scan` 方法預設會傳回「延遲載入」集合。它一開始只會傳回一頁的結果，然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目，請逐一查看 `replies` 集合。

請注意，在集合上呼叫 `size()` 方法將會載入所有結果，以提供準確的計數。這可能會導致耗用大量已佈建的輸送量，而在非常大型的資料表上可能甚至會耗盡 JVM 中的所有記憶體。

若要掃描索引，您必須先將索引建模為映射器類別。假設 `Reply` 資料表有一個名為 `PostedBy-Message-Index` 的全域次要索引。此索引的分割區索引鍵是 `PostedBy`，而排序索引鍵是 `Message`。此索引的映射器類別顯示在 [query](#DynamoDBMapper.Methods.query) 區段。它使用 `@DynamoDBIndexHashKey` 和 `@DynamoDBIndexRangeKey` 註釋來指定索引的分割區索引鍵和排序索引鍵。

下列程式碼範例掃描 `PostedBy-Message-Index`。它不會使用掃描篩選條件，因此會將索引中的所有項目都傳回給您。

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

掃描資料表或次要索引，並傳回單頁的相符結果。與使用 `scan` 方法相同，您可以選擇性地指定 `FilterExpression` 來篩選結果集。不過，`scanPage` 只會傳回第一「頁」的資料；亦即，符合 1 MB 內的資料量。

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

執行整個資料表或次要索引的平行掃描。您可以指定資料表的一些邏輯區段，以及掃描表達式來篩選結果。`parallelScan` 會將掃描任務分到多個工作者 (一個邏輯區段一個工作者)；工作者會平行處理資料，並傳回結果。

下列 Java 程式碼範例會對 `Product` 資料表執行平行掃描。

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

使用 `AmazonDynamoDB.batchWriteItem` 方法的一或多個呼叫，將物件儲存至一或多個資料表。此方法不提供交易保證。

下列 Java 程式碼會將兩個項目 (書籍) 儲存至 `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>

使用一或多個資料表的主索引鍵，以從中擷取多個項目。

下列 Java 程式碼會從兩個不同的資料表擷取兩個項目。

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

使用 `AmazonDynamoDB.batchWriteItem` 方法的一或多個呼叫，刪除一或多個資料表中的物件。此方法不提供交易保證。

下列 Java 程式碼會刪除 `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>

使用 `AmazonDynamoDB.batchWriteItem` 方法的一或多個呼叫，將物件儲存至一或多個資料表，並刪除物件。此方法未提供交易保證或支援版本控制 (條件式放置或刪除)。

下列 Java 程式碼會將新項目寫入至 `Forum` 資料表、將新項目寫入至 `Thread` 資料表，並刪除 `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>

使用 `AmazonDynamoDB.transactWriteItems` 方法的一個呼叫，將物件儲存至一或多個資料表，並從中刪除物件。

如需交易特定例外的清單，請參閱 [TransactWriteItems 錯誤](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors)。

如需 DynamoDB 交易與提供之不可部分完成性、一致性、隔離性和耐久性 (ACID) 保證的相關資訊，請參閱 [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html)。

**注意**  
 此方法不支援下列項目：  
[DynamoDBMapperConfig.SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html)。

以下 Java 程式碼會以交易的方式，將新項目寫入每個 `Forum` 和 `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>

使用 `AmazonDynamoDB.transactGetItems` 方法的一個呼叫，載入一或多個資料表中的物件。

如需交易特定例外的清單，請參閱 [TransactGetItems 錯誤](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors)。

如需 DynamoDB 交易與提供之不可部分完成性、一致性、隔離性和耐久性 (ACID) 保證的相關資訊，請參閱 [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html)。

以下 Java 程式碼會以交易的方式，將從每個 `Forum` 和 `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>

評估指定的掃描表達式，並傳回相符項目的計數。不傳回任何項目資料。

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

剖析代表 DynamoDB 資料表的 POJO 類別，並傳回該資料表的 `CreateTableRequest`。

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

建立 Amazon S3 中物件的連結。您必須指定儲存貯體名稱和索引鍵名稱，以唯一識別儲存貯體中的物件。

若要使用 `createS3Link`，映射器類別必須定義 getter 和 setter 方法。下列程式碼範例透過將新的屬性和 getter/setter 方法新增至 `CatalogItem` 類別來說明這種情況。

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

...
}
```

下列 Java 程式碼定義要寫入至 `Product` 資料表的新項目。此項目包含產品映像的連結；映像資料會上傳至 Amazon S3。

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

`S3Link` 類別提供許多其他方法來操控 Amazon S3 中的物件。如需詳細資訊，請參閱 [Javadocs for `S3Link`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html)。

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

傳回基礎 `S3ClientCache` 來存取 Amazon S3。`S3ClientCache` 是 `AmazonS3Client` 物件的智慧映射。如果您有多個用戶端， `S3ClientCache`可協助您依 AWS 區域整理用戶端，並可隨需建立新的 Amazon S3 用戶端。

# 適用於 Java 的 DynamoDBMapper 支援的資料類型
<a name="DynamoDBMapper.DataTypes"></a>

本節說明 Amazon DynamoDB 中支援的基本 Java 資料類型、集合和任意資料類型。

Amazon DynamoDB 支援下列基本 Java 資料類型和基本包裝函式類別。
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (作為 [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) 毫秒精確性字串，已轉移為 UTC)
+ `Calendar` (作為 [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) 毫秒精確性字串，已轉移為 UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**注意**  
如需有關 DynamoDB 命名規則和各種支援之資料類型的詳細資訊，請參閱 [Amazon DynamoDB 中支援的資料類型和命名規則](HowItWorks.NamingRulesDataTypes.md)。
空白的二進位值由 DynamoDBMapper 支援。
 AWS SDK for Java 2.x支援空白字串值。  
在適用於 Java 的 AWS SDK 1.x 中，DynamoDBMapper 支援讀取空的字串屬性值，但它不會寫入空的字串屬性值，因為這些屬性會從請求中刪除。

DynamoDB 支援 Java [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) 和 [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html) 集合類型。下表摘要說明如何將這些 Java 類型映射至 DynamoDB 類型。


****  

| Java 類型 | DynamoDB 類型 | 
| --- | --- | 
|  所有數字類型  |  `N` (數字類型)  | 
|  Strings  |  `S` (字串類型)   | 
|  Boolean  |  `BOOL` (布林類型)，0 或 1。  | 
|  ByteBuffer  |  `B` (二進位類型)  | 
|  Date  |  `S` (字串類型)。Date 值會以 ISO-8601 格式字串存放。  | 
| [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) 集合類型 |  `SS` (字串集) 類型、`NS` (數字集) 類型或 `BS` (二進位集) 類型。  | 

 `DynamoDBTypeConverter` 介面可讓您將自己的任意資料類型映射至 DynamoDB 原生支援的資料類型。如需詳細資訊，請參閱[在 DynamoDB 中映射任意資料](DynamoDBMapper.ArbitraryDataMapping.md)。

# 適用於 DynamoDB 的 Java 註釋
<a name="DynamoDBMapper.Annotations"></a>

本節說明可用於將類別和屬性映射至 Amazon DynamoDB 中資料表和屬性的註釋。

如需對應的 Javadoc 文件，請參閱《[適用於 Java 的 AWS SDK API 參考](https://docs.aws.amazon.com/sdk-for-java/latest/reference/)》中的[註釋類型摘要](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html)。

**注意**  
在下列註釋中，只需要 `DynamoDBTable` 和 `DynamoDBHashKey`。

**Topics**
+ [DynamoDBAttribute](#DynamoDBMapper.Annotations.DynamoDBAttribute)
+ [DynamoDBAutoGeneratedKey](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey)
+ [DynamoDBAutoGeneratedTimestamp](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp)
+ [DynamoDBDocument](#DynamoDBMapper.Annotations.DynamoDBDocument)
+ [DynamoDBHashKey](#DynamoDBMapper.Annotations.DynamoDBHashKey)
+ [DynamoDBIgnore](#DynamoDBMapper.Annotations.DynamoDBIgnore)
+ [DynamoDBIndexHashKey](#DynamoDBMapper.Annotations.DynamoDBIndexHashKey)
+ [DynamoDBIndexRangeKey](#DynamoDBMapper.Annotations.DynamoDBIndexRangeKey)
+ [DynamoDBRangeKey](#DynamoDBMapper.Annotations.DynamoDBRangeKey)
+ [DynamoDBTable](#DynamoDBMapper.Annotations.DynamoDBTable)
+ [DynamoDBTypeConverted](#DynamoDBMapper.Annotations.DynamoDBTypeConverted)
+ [DynamoDBTyped](#DynamoDBMapper.Annotations.DynamoDBTyped)
+ [DynamoDBVersionAttribute](#DynamoDBMapper.Annotations.DynamoDBVersionAttribute)

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

將屬性映射至資料表屬性。每個類別屬性預設會映射至同名的項目屬性。不過，如果名稱不同，您可以使用此註釋將屬性 (property) 映射至屬性 (attribute)。在下列 Java 程式碼片段中，`DynamoDBAttribute` 會將 `BookAuthors` 屬性映射至資料表中的 `Authors` 屬性名稱。

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

將物件儲存至資料表時，`DynamoDBMapper` 使用 `Authors` 做為屬性名稱。

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

將分割區索引鍵或排序索引鍵屬性標示為自動產生。儲存這些屬性時，`DynamoDBMapper`​ 會產生隨機 [​UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html)。只有字串屬性才能標示為自動產生的索引鍵。

以下是示範使用自動產生索引鍵參數的範例。

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

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

自動產生時間戳記。

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

或者，可以透過提供策略屬性來定義自動產生策略。預設值為 `ALWAYS`。

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

指出類別可以序列化為 Amazon DynamoDB 文件。

例如，假設您要將 JSON 文件映射至 Map (`M`) 類型的 DynamoDB 屬性。下列程式碼範例定義包含 Map 類型之巢狀屬性 (Pictures) 的項目。

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

     }
}
```

然後您就可儲存新的 `ProductCatalog` 項目，並具有 `Pictures`，如下列範例所示。

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

產生的 `ProductCatalog`項目看起來將會如下 (JSON 格式)。

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

## DynamoDBHashKey
<a name="DynamoDBMapper.Annotations.DynamoDBHashKey"></a>

將類別屬性映射至資料表的分割區索引鍵。此屬性必須是純量字串、數字或二進位類型的其中之一。此屬性不能是集合類型。

假設您的 `ProductCatalog` 資料表將 `Id` 作為主索引鍵。下列 Java 程式碼定義 `CatalogItem` 類別，並使用 `@DynamoDBHashKey` 標籤將其 `Id` 屬性映射至 `ProductCatalog` 資料表的主索引鍵。

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

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

指出應該忽略相關聯屬性的 `DynamoDBMapper` 執行個體。將資料儲存至資料表時，`DynamoDBMapper` 不會將此屬性儲存至資料表。

 套用至 getter 方法或非模組化屬性的類別欄位。若該註釋是直接套用至類別欄位，則必須在相同的類別宣告相對應的 getter 和 setter。

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

將類別屬性映射至全域次要索引的分割區索引鍵。此屬性必須是純量字串、數字或二進位類型的其中之一。此屬性不能是集合類型。

如果您需要對全域次要索引進行 `Query`，請使用此註釋。您必須指定索引名稱 (`globalSecondaryIndexName`)。如果類別屬性的名稱與索引的分割區索引鍵不同，您也必須指定該索引屬性的名稱 (`attributeName`)。

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

將類別屬性映射至全域次要索引或本機次要索引的排序索引鍵。此屬性必須是純量字串、數字或二進位類型的其中之一。此屬性不能是集合類型。

如果您需要對本機次要索引或全域次要索引進行 `Query`，並且想要使用索引的排序索引鍵來縮小您結果的範圍，請使用此註釋。您必須指定索引名稱 (`globalSecondaryIndexName` 或 `localSecondaryIndexName`)。如果類別屬性的名稱與索引的排序索引鍵不同，您也必須指定該索引屬性的名稱 (`attributeName`)。

## DynamoDBRangeKey
<a name="DynamoDBMapper.Annotations.DynamoDBRangeKey"></a>

將類別屬性映射至資料表的排序索引鍵。此屬性必須是純量字串、數字或二進位類型的其中之一。它不能是集合類型。

如果主索引鍵是複合 (分割區索引鍵和排序索引鍵)，您可以使用此標籤，將類別欄位映射至排序索引鍵。例如，假設您的 `Reply` 資料表存放論壇主題回覆。每個對話都可以有許多回覆。因此，此資料表的主索引鍵是 `ThreadId` 和 `ReplyDateTime`。分割區索引鍵是 `ThreadId`，而排序索引鍵是 `ReplyDateTime`。

下列 Java 程式碼定義 `Reply` 類別，並將它映射至 `Reply` 資料表。它會使用 `@DynamoDBHashKey` 和 `@DynamoDBRangeKey` 標籤來識別映射至主索引鍵的類別屬性。

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

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

識別 DynamoDB 中的目標資料表。下列 Java 程式碼定義 `Developer` 類別，並將它映射至 DynamoDB 中的 `People` 資料表。

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

`@DynamoDBTable` 註釋可以予以繼承。任何繼承自 `Developer` 類別的新類別也會映射至 `People` 資料表。例如，假設您建立繼承自 `Lead` 類別的 `Developer` 類別。因為您已將 `Developer` 類別映射至 `People` 資料表，所以也會將 `Lead` 類別物件存放至相同的資料表。

`@DynamoDBTable` 也可以予以覆寫。任何繼承自 `Developer` 類別的新類別預設會映射至相同的 `People` 資料表。不過，您可以覆寫此預設映射。例如，如果您建立繼承自 `Developer` 類別的類別，則可以新增 `@DynamoDBTable` 註釋，明確地將它映射至另一個資料表，如下列 Java 程式碼範例所示。

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

## DynamoDBTypeConverted
<a name="DynamoDBMapper.Annotations.DynamoDBTypeConverted"></a>

將屬性標示為使用自訂類型轉換器的註釋。可以標註於使用者定義的註釋，以將其他屬性傳遞給 `DynamoDBTypeConverter`。

 `DynamoDBTypeConverter` 介面可讓您將自己的任意資料類型映射至 DynamoDB 原生支援的資料類型。如需詳細資訊，請參閱[在 DynamoDB 中映射任意資料](DynamoDBMapper.ArbitraryDataMapping.md)。

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

覆寫標準屬性類型繫結的註釋。如果套用標準類型的預設屬性繫結，則該類型不需要註釋。

## DynamoDBVersionAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBVersionAttribute"></a>

識別用於存放樂觀鎖定版本編號的類別屬性。`DynamoDBMapper`​ 在儲存新的項目時會將版本編號指派給此屬性，並在每次您更新項目時予以遞增。僅支援數字純量類型。如需資料類型的詳細資訊，請參閱 [資料類型](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)。如需版本控制的詳細資訊，請參閱「[含版本編號的 DynamoDB 及樂觀鎖定](DynamoDBMapper.OptimisticLocking.md)」。

# DynamoDBMapper 的選用組態設定
<a name="DynamoDBMapper.OptionalConfig"></a>

當您建立 `DynamoDBMapper` 執行個體時，會有特定預設行為；您可以使用 `DynamoDBMapperConfig` 類別來覆寫這些預設值。

下列程式碼片段會使用自訂設定來建立 `DynamoDBMapper`：

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

如需詳細資訊，請參閱《[適用於 Java 的 AWS SDK API 參考](https://docs.aws.amazon.com/sdk-for-java/latest/reference/)》中的 [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)。

您可以針對 `DynamoDBMapperConfig` 執行個體使用下列引數：
+ `DynamoDBMapperConfig.ConsistentReads` 列舉值：
  + `EVENTUAL`：映射器執行個體使用最終一致讀取請求。
  + `CONSISTENT`：映射器執行個體使用高度一致性讀取請求。您可以搭配使用這個選用設定與 `load`、`query` 或 `scan` 操作。高度一致性讀取具有效能和帳單隱憂；如需詳細資訊，請參閱 DynamoDB [產品詳細資訊頁面](https://aws.amazon.com/dynamodb)。

  如果您未指定映射器執行個體的讀取一致性設定，則預設值為 `EVENTUAL`。
**注意**  
此值僅適用於 DynamoDBMapper 的 `query`、`querypage`、`load` 和 `batch load` 操作。
+ `DynamoDBMapperConfig.PaginationLoadingStrategy` 列舉值：控制映射器執行個體如何處理分頁資料清單，例如 `query` 或 `scan` 的結果：
  + `LAZY_LOADING`：映射器執行個體會在可能時載入資料，並將所有載入的結果保留在記憶體中。
  + `EAGER_LOADING`：映射器執行個體會在初始化清單時立即載入資料。
  + `ITERATION_ONLY`：您只能使用從清單中讀取的迭代器。在迭代期間，清單會先清除所有先前的結果，再載入下一頁，因此清單最多會將一頁的已載入結果保留在記憶體中。這也表示清單只能重複使用一次。處理大型項目時，建議使用此策略，以減少記憶體負擔。

  如果您未指定映射器執行個體的分頁載入策略，則預設值為 `LAZY_LOADING`。
+ `DynamoDBMapperConfig.SaveBehavior` 列舉值：指定映射器執行個體在儲存操作期間應該如何處理屬性：
  + `UPDATE`：在儲存操作期間，會更新所有建模屬性，未建模屬性則不受影響。基本數字類型 (byte、int、long) 設定為 0。物件類型設定為 Null。
  + `CLOBBER`：在儲存操作期間，清除和取代所有屬性 (包含未建模屬性)。透過刪除並重新建立項目來完成這項操作。使用版本控制的欄位限制條件也會予以忽略。

   如果您未指定映射器執行個體的儲存行為，則預設值為 `UPDATE`。
**注意**  
DynamoDBMapper 交易操作不支援 `DynamoDBMapperConfig.SaveBehavior` 列舉。
+ `DynamoDBMapperConfig.TableNameOverride` 物件：指示映射器執行個體忽略類別之 `DynamoDBTable` 註釋所指定的資料表名稱，並改為使用您提供的不同資料表名稱。在執行時期將資料分割為多個資料表時，這十分有用。

您可以視需要覆寫每個操作的 `DynamoDBMapper` 預設組態物件。

# 含版本編號的 DynamoDB 及樂觀鎖定
<a name="DynamoDBMapper.OptimisticLocking"></a>

*樂觀鎖定*是一種策略，確保您要更新 (或刪除) 的用戶端項目與 Amazon DynamoDB 中的項目相同。如果您使用此策略，則會保護其他項目的寫入不會覆寫資料庫寫入，反之亦然。

使用樂觀鎖定，每個項目都有做為版本編號的屬性。如果您從資料表中擷取項目，則應用程式會記錄該項目的版本編號。您可以更新項目，但只有在伺服器端的版本編號尚未變更時。若版本不相符，表示已有其他人在您之前進行修改。更新嘗試失敗，因為您有此項目的過期版本。如果發生這種情況，請檢索項目然後嘗試進行更新以重試一次。樂觀鎖定預防您意外覆寫其他人所作的變更。同時也預防其他人意外覆寫您所作的變更。

雖然您可以實作自己的樂觀鎖定策略，但 適用於 Java 的 AWS SDK 提供 `@DynamoDBVersionAttribute`註釋。在資料表的映射類別中，您指定一個屬性來存放版本編號，並使用此註釋進行標示。當您儲存物件時，DynamoDB 資料表中的對應項目會有屬性可存放版本編號。當您第一次儲存物件時，`DynamoDBMapper` 會指派版本編號，並在每次更新項目時自動遞增版本編號。只有在用戶端物件版本與 DynamoDB 資料表中項目的對應版本編號相符時，您的更新或刪除請求才會成功。

 如果發生下列情況，則會擲回 `ConditionalCheckFailedException`：
+  您使用含 `@DynamoDBVersionAttribute` 的樂觀鎖定，而且伺服器上的版本值與用戶端上的值不同。
+  您可以搭配使用 `DynamoDBMapper` 與 `DynamoDBSaveExpression`，以在儲存資料時指定自己的條件式限制條件，而且這些限制條件會失敗。

**注意**  
DynamoDB 全域資料表會在並行更新間使用「最後寫入者獲勝」核對機制。如果您使用的是全域資料表，最後寫入者政策獲勝。因此，在此情況下，鎖定政策不會如預期般運作。
`DynamoDBMapper` 交易寫入操作不支援同一物件的 `@DynamoDBVersionAttribute` 標註和條件表達式。如果交易寫入內的物件以 `@DynamoDBVersionAttribute` 標註，且具有條件表達式，則會拋出 SdkClientException。

例如，下列 Java 程式碼定義有數個屬性的 `CatalogItem` 類別。`Version` 屬性會標上 `@DynamoDBVersionAttribute` 註釋。

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

您可以將 `@DynamoDBVersionAttribute` 註釋套用至基本包裝函式類別所提供的可為 Null 類型，而基本包裝函式類別提供可為 Null 類型 (例如 `Long` 和 `Integer`)。

樂觀鎖定對這些 `DynamoDBMapper` 方法的影響如下：
+ `save`：針對新項目，`DynamoDBMapper` 會指派初始版本編號 1。如果您擷取項目，請更新其一或多個屬性並嘗試儲存變更，只有在用戶端的版本編號與伺服器端的相符時，儲存操作才會成功。`DynamoDBMapper` 會自動遞增版本編號。
+ `delete`：`delete` 方法會採用物件作為參數，而 `DynamoDBMapper` 會在刪除項目之前執行版本檢查。如果請求中指定 `DynamoDBMapperConfig.SaveBehavior.CLOBBER`，則可以停用版本檢查。

  `DynamoDBMapper` 內的樂觀鎖定內部實作，使用 DynamoDB 所提供的條件式更新和條件式刪除支援。
+ `transactionWrite` —
  + `Put`：針對新項目，`DynamoDBMapper` 會指派初始版本編號 1。如果您擷取項目，請更新其一或多個屬性並嘗試儲存變更，只有在用戶端的版本編號與伺服器端的相符時，Put 操作才會成功。`DynamoDBMapper` 會自動遞增版本編號。
  + `Update`：針對新項目，`DynamoDBMapper` 會指派初始版本編號 1。如果您擷取項目，請更新其一或多個屬性並嘗試儲存變更，只有在用戶端的版本編號與伺服器端的相符時，update 操作才會成功。`DynamoDBMapper` 會自動遞增版本編號。
  + `Delete`：`DynamoDBMapper` 會在刪除項目之前執行版本檢查。只有用戶端與伺服器端的版本號碼相符時，delete 操作才會成功。
  + `ConditionCheck`：不支援 `ConditionCheck` 操作的 `@DynamoDBVersionAttribute` 註釋。以 `@DynamoDBVersionAttribute` 標註 `ConditionCheck` 項目時，會拋出 SdkClientException。

## 停用樂觀鎖定
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

若要停用樂觀鎖定，您可以將 `DynamoDBMapperConfig.SaveBehavior` 列舉值從 `UPDATE` 變更為 `CLOBBER`。您可以建立跳過版本檢查的 `DynamoDBMapperConfig` 執行個體來執行這項操作，並將此執行個體用於所有請求。如需 `DynamoDBMapperConfig.SaveBehavior` 和其他選用 `DynamoDBMapper` 參數的資訊，請參閱「[DynamoDBMapper 的選用組態設定](DynamoDBMapper.OptionalConfig.md)」。

您也只能設定特定操作的鎖定行為。例如，下列 Java 程式碼片段使用 `DynamoDBMapper` 來儲存型錄項目。指定 `DynamoDBMapperConfig.SaveBehavior` 的方式是將選用 `DynamoDBMapperConfig` 參數新增至 `save` 方法。

**注意**  
transactionWrite 方法不支援 DynamoDBMapperConfig.SaveBehavior 組態。不支援停用 transactionWrite 的樂觀鎖定。

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

# 在 DynamoDB 中映射任意資料
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

除了支援的 Java 類型之外 (請參閱 [適用於 Java 的 DynamoDBMapper 支援的資料類型](DynamoDBMapper.DataTypes.md))，您還可以使用應用程式中未直接映射至 Amazon DynamoDB 類型的類型。若要映射這些類型，您必須提供將複雜類型轉換為 DynamoDB 支援之類型的實作 (反之亦然)，並使用 `@DynamoDBTypeConverted` 註釋來標註複雜類型存取子方法。轉換器程式碼會在儲存或載入物件時轉換資料。它也用於使用複雜類型的所有操作。請注意，在查詢和掃描操作期間比較資料時，會針對 DynamoDB 中所存放的資料進行比較。

例如，請考慮下列可定義本身為 `CatalogItem` 之 `Dimension` 屬性的 `DimensionType` 類別。此屬性會將項目維度存放為高度、寬度和厚度。假設您決定將這些項目維度存放為 DynamoDB 中的字串 (例如 8.5x11x.05)。下列範例提供轉換器程式碼，以將 `DimensionType` 物件轉換為字串以及將字串轉換為 `DimensionType`。



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

# DynamoDBMapper 範例
<a name="DynamoDBMapper.Examples"></a>

適用於 Java 的 AWS SDK 提供 `DynamoDBMapper` 類別，可讓您將用戶端類別映射至 DynamoDB 資料表。若要使用 `DynamoDBMapper`，請定義 DynamoDB 資料表中項目與程式碼中其對應物件執行個體之間的關係。`DynamoDBMapper` 類別也讓您執行各種建立、讀取、更新和對項目進行刪除 (CRUD) 操作，以及執行查詢和掃描資料表。

若要進一步了解如何使用 `DynamoDBMapper`，請參閱《*適用於 Java 1.x 的 AWS SDK 開發人員指南*》中[使用適用於 Java 的 AWS SDK 的 DynamoDB 範例](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html)。

# Java 2.x：DynamoDB 增強型用戶端
<a name="DynamoDBEnhanced"></a>

DynamoDB 增強型用戶端是適用於 Java 的 AWS SDK 2 (v2) 版中的高階程式庫。提供將客戶端類別映射到 DynamoDB 資料表的直接方式。您要在自己的程式碼中定義資料表及其對應模型類別之間的關係。定義關係之後，您可以直觀地對 DynamoDB 中的資料表或項目執行各種建立、讀取、更新或刪除 (CRUD) 操作。

如需有關如何將增強型用戶端與 DynamoDB 搭配使用的詳細資訊，請參閱[適用於 Java 的 AWS SDK 2.x 中的使用 DynamoDB 增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)。

# 在 DynamoDB 中使用 .NET 文件模型
<a name="DotNetSDKMidLevel"></a>

適用於 .NET 的 AWS SDK 提供文件模型類別，包裝一部分低階 Amazon DynamoDB 操作，可進一步簡化您的程式碼編寫。在文件模型中，主類別為 `Table` 和 `Document`。`Table` 類別提供資料操作方法，例如 `PutItem`、`GetItem` 和 `DeleteItem`。該類別也提供 `Query` 和 `Scan` 方法。`Document` 類別則代表資料表中的單一項目。

上述文件模型類別可在 `Amazon.DynamoDBv2.DocumentModel` 命名空間中取得。

**注意**  
您無法使用文件模型建立、更新和刪除資料表。但文件模型支援大部分的常見資料操作。

**Topics**
+ [支援的資料類型](#MidLevelAPILimitations.SupportedTypes)

## 支援的資料類型
<a name="MidLevelAPILimitations.SupportedTypes"></a>

文件模型會支援一組原始的 .NET 資料類型和集合資料類型。模型目前支援下列基本資料類型。
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

下表摘要說明上述 .NET 類型與 DynamoDB 類型的映射。


****  

| .NET 基本類型 | DynamoDB 類型 | 
| --- | --- | 
|  所有數字類型  |  `N` (數字類型)  | 
|  所有字串類型  |  `S` (字串類型)   | 
|  MemoryStream, byte[]  |  `B` (二進位類型)   | 
| bool | N (數字類型)。0 代表 false，1 代表 true。 | 
| DateTime | S (字串類型)。DateTime 值會以 ISO-8601 格式字串存放。 | 
| Guid | S (字串類型)。 | 
| 集合類型 (List、HashSet 和陣列) | BS (二進位集) 類型、SS (字串集) 類型和 NS (數字集) 類型。 | 

適用於 .NET 的 AWS SDK 會定義將 DynamoDB 的布林值、null 值、清單和映射類型映射到 .NET 文件模型 API 的類型：
+ 使用 `DynamoDBBool` 作為布林類型。
+ 使用 `DynamoDBNull` 作為 null 類型。
+ 使用 `DynamoDBList` 作為清單類型。
+ 使用 `Document` 作為映射類型。

**注意**  
支援空白的二進位值。
支援讀取空白字串值。寫入 DynamoDB 時，字串 Set 類型的屬性值會支援空白字串的屬性值。List 或 Map 類型中包含的字串類型的空白字串屬性值和空白字串值會從寫入請求中捨棄

# 使用 .NET 物件持久性模型和 DynamoDB
<a name="DotNetSDKHighLevel"></a>

 適用於 .NET 的 AWS SDK 提供物件持久性模型，可讓您將用戶端類別映射至 Amazon DynamoDB 資料表。然後每個物件執行個體會映射至相對應資料表中的某個項目。為了將用戶端物件儲存至資料表，物件持久性模型會提供 `DynamoDBContext` 類別 (即 DynamoDB 的進入點)。此類別可讓您連線至 DynamoDB，繼而存取資料表、執行各種 CRUD 操作以及執行查詢。

物件持久性模型提供了一組屬性，可將用戶端類別映射到資料表，並將屬性/欄位映射至資料表屬性。

**注意**  
物件持久性模型不提供用於建立、更新或刪除資料表的 API。它只提供資料操作。您只能使用 適用於 .NET 的 AWS SDK 低階 API 來建立、更新和刪除資料表。

以下範例會示範物件持久性模型的運作方式。它會從 `ProductCatalog` 資料表開始作業。它將 `Id` 作為主索引鍵。

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

假設您的 `Book` 類別具有 `Title`、`ISBN` 以及 `Authors` 屬性。您可以透過新增物件持久性模型所定義的屬性，將 `Book` 類別映射至 `ProductCatalog` 資料表中，如下列 C\$1 程式碼範例所示。

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

在上述範例中，`DynamoDBTable` 屬性會將 `Book` 類別映射至 `ProductCatalog` 資料表。

物件持久性模型支援類別屬性與資料表屬性之間的明確映射和預設映射。
+ **明確映射：**若要將屬性映射至主索引鍵，您必須使用 `DynamoDBHashKey` 和 `DynamoDBRangeKey` 物件持久性模型屬性。此外，對於非主索引鍵屬性，如果類別中的屬性名稱和要對應的資料表屬性不相同，則必須明確新增 `DynamoDBProperty` 屬性來定義映射。

  在上述範例中，`Id` 屬性會映射至具有相同名稱的主索引鍵，`BookAuthors` 屬性則會映射至 `ProductCatalog` 資料表中的 `Authors` 屬性。
+ **預設映射：**依預設，物件持久性模型會將類別屬性映射至資料表中具有相同名稱的屬性。

  在上述範例中，屬性 `Title` 和 `ISBN` 會映射至 `ProductCatalog` 資料表中具有相同名稱的屬性。

您不必映射每個類別屬性。您可以新增 `DynamoDBIgnore` 屬性來識別這些屬性。當您將 `Book` 執行個體儲存至資料表時，`DynamoDBContext` 不會包含 `CoverPage` 屬性。在擷取書籍執行個體時，它也不會傳回此屬性。

您可以映射 .NET 基本類型的屬性，如 int 和字串。只要提供適當的轉換器將任意資料映射至其中一種 DynamoDB 類型，您也可以映射任意資料類型。若要進一步了解如何映射任意類型，請參閱 [使用 適用於 .NET 的 AWS SDK 物件持久性模型使用 DynamoDB 映射任意資料](DynamoDBContext.ArbitraryDataMapping.md)。

物件持久性模型支援樂觀鎖定。在更新操作期間，這可確保您擁有即將更新項目的最新副本。如需詳細資訊，請參閱[使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定](DynamoDBContext.VersionSupport.md)。

如需詳細資訊，請參閱下列主題。

**Topics**
+ [支援的資料類型](#DotNetDynamoDBContext.SupportedTypes)
+ [.NET 物件持久性模型的 DynamoDB 屬性](DeclarativeTagsList.md)
+ [.NET 物件持久性模型的 DynamoDBContext 類別](DotNetDynamoDBContext.md)
+ [使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定](DynamoDBContext.VersionSupport.md)
+ [使用 適用於 .NET 的 AWS SDK 物件持久性模型使用 DynamoDB 映射任意資料](DynamoDBContext.ArbitraryDataMapping.md)

## 支援的資料類型
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

物件持久性模型會支援一組基本的 .NET 資料類型、集合和任意資料類型。模型目前支援下列基本資料類型。
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

物件持久性模型也支援 .NET 集合類型。`DynamoDBContext` 能夠轉換具體的集合類型和簡單的純舊 CLR 物件 (POCO)。

下表摘要說明上述 .NET 類型與 DynamoDB 類型的映射。


****  

| .NET 基本類型 | DynamoDB 類型 | 
| --- | --- | 
|  所有數字類型  |  `N` (數字類型)  | 
|  所有字串類型  |  `S` (字串類型)   | 
|  MemoryStream, byte[]  |  `B` (二進位類型)   | 
| bool | N (數字類型)。0 代表 false，1 代表 true。 | 
| 集合類型 | BS (二進位集) 類型、SS (字串集) 類型和 NS (數字集) 類型。 | 
| DateTime | S (字串類型)。DateTime 值會以 ISO-8601 格式字串存放。 | 

物件持久性模型也支援任意資料類型。不過，您必須提供轉換器程式碼，才能將複雜類型映射至 DynamoDB 類型。

**注意**  
支援空白的二進位值。
支援讀取空白字串值。寫入 DynamoDB 時，字串 Set 類型的屬性值會支援空白字串的屬性值。List 或 Map 類型中包含的字串類型的空白字串屬性值和空白字串值會從寫入請求中捨棄

# .NET 物件持久性模型的 DynamoDB 屬性
<a name="DeclarativeTagsList"></a>

本節說明物件持久性模型所提供的屬性，讓您可以將類別和屬性映射至 DynamoDB 資料表和屬性。

**注意**  
在下列屬性中，只有 `DynamoDBTable` 和 `DynamoDBHashKey` 是必要屬性。

## DynamoDBGlobalSecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

將類別屬性映射至全域次要索引的分割區索引鍵。如果您需要對全域次要索引進行 `Query`，請使用此屬性。

## DynamoDBGlobalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

將類別屬性映射至全域次要索引的排序索引鍵。如果您需要對全域次要索引進行 `Query`，並且想要使用索引的排序索引鍵來縮小您結果的範圍，請使用此屬性。

## DynamoDBHashKey
<a name="w2aac17b9c21c23c37c11"></a>

將類別屬性映射至資料表主索引鍵的分割區索引鍵。主索引鍵屬性不能是集合類型。

下列 C\$1 程式碼範例會映射 `Book` 類別至 `ProductCatalog` 資料表，並映射 `Id` 屬性至資料表主索引鍵的分割區索引鍵。

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

    // Additional properties go here.
}
```

## DynamoDBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

指出應該忽略的相關聯屬性。如果您不想儲存任何類別屬性，可以新增此屬性來指示 `DynamoDBContext` 將物件儲存到資料表時不包含此屬性。

## DynamoDBLocalSecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

將類別屬性映射至本機次要索引的排序索引鍵。如果您需要對本機次要索引進行 `Query`，並且想要使用索引的排序索引鍵來縮小您結果的範圍，請使用此屬性。

## DynamoDBProperty
<a name="w2aac17b9c21c23c37c17"></a>

將類別屬性映射至資料表屬性。如果類別屬性映射至具有相同名稱的資料表屬性，則不需要指定此屬性。不過，如果名稱不同，您可以使用此標籤提供映射。在下列 C\$1 陳述式中，`DynamoDBProperty` 會將 `BookAuthors` 屬性映射至資料表中的 `Authors` 屬性。

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

當儲存物件資料至相應的資料表時，`DynamoDBContext` 會使用此映射資訊來建立 `Authors` 屬性。

## DynamoDBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

指定類別屬性的替代名稱。如果您正在撰寫自訂轉換器，以將任意資料映射至 DynamoDB 資料表 (其中類別屬性的名稱與資料表屬性不同)，則此功能非常有用。

## DynamoDBRangeKey
<a name="w2aac17b9c21c23c37c21"></a>

將類別屬性映射至資料表主索引鍵的排序索引鍵。如果資料表具有複合主鍵 (分割區索引鍵和排序索引鍵)，則必須在類別映射中同時指定 `DynamoDBHashKey` 和 `DynamoDBRangeKey` 屬性。

例如，範例資料表 `Reply` 有一個由 `Id` 分割區索引鍵和 `Replenishment` 排序索引鍵組成的主索引鍵。下列 C\$1 程式碼範例將 `Reply` 類別映射至 `Reply` 資料表。類別定義也會指出其中兩個屬性映射至主索引鍵。

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

## DynamoDBTable
<a name="w2aac17b9c21c23c37c23"></a>

識別 DynamoDB 中類別要映射的目標資料表。例如，下列 C\$1 程式碼範例將 `Developer` 類別映射至 DynamoDB 中的 `People` 資料表。

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

此屬性可被繼承或覆寫。
+ `DynamoDBTable` 屬性可被繼承。在上述範例中，如果新增新從 `Developer` 類別繼承的新類別 `Lead`，它也會映射至 `People` 資料表。`Developer` 和 `Lead` 物件都存放在 `People` 資料表中。
+ `DynamoDBTable` 屬性也可被寫。在下列 C\$1 程式碼範例中，`Manager` 類別繼承自 `Developer` 類別。但是，明確新增 `DynamoDBTable` 屬性會將類別映射到另一個資料表 (`Managers`)。

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

 您可以新增選用參數 `LowerCamelCaseProperties`，以便請求 DynamoDB 在儲存物件至資料表時，將屬性名稱的第一個字母變成小寫，如下列 C\$1 範例所示。

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

在儲存 `Developer` 類別的執行個體時，`DynamoDBContext` 會儲存 `DeveloperName` 屬性作為 `developerName`。

## DynamoDBVersion
<a name="w2aac17b9c21c23c37c25"></a>

標識用於儲存項目版本編號的類別屬性。如需版本控制的詳細資訊，請參閱「[使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定](DynamoDBContext.VersionSupport.md)」。

# .NET 物件持久性模型的 DynamoDBContext 類別
<a name="DotNetDynamoDBContext"></a>

`DynamoDBContext` 類別是 Amazon DynamoDB 資料庫的進入點。它可讓您連線至 DynamoDB，繼而存取各種資料表中的資料、執行各種 CRUD 操作以及執行查詢。此 `DynamoDBContext` 類別提供下列方法。

**Topics**
+ [Create​MultiTable​BatchGet](#w2aac17b9c21c23c39b7)
+ [Create​MultiTable​BatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [刪除](#w2aac17b9c21c23c39c15)
+ [Dispose](#w2aac17b9c21c23c39c17)
+ [Execute​Batch​Get](#w2aac17b9c21c23c39c19)
+ [Execute​Batch​Write](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [Get​Target​Table](#w2aac17b9c21c23c39c29)
+ [Load](#w2aac17b9c21c23c39c31)
+ [Query](#w2aac17b9c21c23c39c33)
+ [Save](#w2aac17b9c21c23c39c35)
+ [Scan](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [指定 DynamoDBContext 的選用參數](#OptionalConfigParams)

## Create​MultiTable​BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

建立由多個個別 `BatchGet` 物件組成的 `MultiTableBatchGet` 物件。其中的每個 `BatchGet` 物件都可用來從單一 DynamoDB 資料表中擷取項目。

若要從資料表擷取項目，請使用 `ExecuteBatchGet` 方法，將 `MultiTableBatchGet` 物件作為參數傳遞。

## Create​MultiTable​BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

建立由多個個別 `BatchWrite` 物件組成的 `MultiTableBatchWrite` 物件。其中的每個 `BatchWrite` 物件可用來寫入或刪除單一 DynamoDB 資料表中的項目。

若要寫入資料表，請使用 `ExecuteBatchWrite` 方法，將 `MultiTableBatchWrite` 物件作為參數傳遞。

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

建立 `BatchGet` 物件，您可以使用該物件從資料表中擷取多個項目。

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

建立 `BatchWrite` 物件，您可以使用該物件將多個項目放入資料表中，或從資料表中刪除多個項目。

## 刪除
<a name="w2aac17b9c21c23c39c15"></a>

刪除資料表中的項目。這個方法需要您希望刪除之項目的主索引鍵。您可以提供主索引鍵值或包含主索引鍵值的用戶端物件，作為此方法的參數。
+ 如果指定用戶端物件作為參數，且已啟用樂觀鎖定，則只有在物件的用戶端和伺服器端版本相符時，才能成功刪除項目。
+ 如果只指定主索引鍵值作為參數，無論您是否已啟用樂觀鎖定，刪除都會成功。

**注意**  
若要在背景執行此操作，請改用 `DeleteAsync` 方法。

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

處置所有受管和非受管的資源。

## Execute​Batch​Get
<a name="w2aac17b9c21c23c39c19"></a>

從一或多個資料表讀取資料，處理 `MultiTableBatchGet` 中的所有 `BatchGet` 物件。

**注意**  
若要在背景執行此操作，請改用 `ExecuteBatchGetAsync` 方法。

## Execute​Batch​Write
<a name="w2aac17b9c21c23c39c21"></a>

在一或多個資料表中寫入或刪除資料，處理 `MultiTableBatchWrite` 中的所有 `BatchWrite` 物件。

**注意**  
若要在背景執行此操作，請改用 `ExecuteBatchWriteAsync` 方法。

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

若為 `Document` 執行個體，`FromDocument` 方法會傳回用戶端類別的執行個體。

如果您想使用文件模型類別以及物件持久性模型來執行任何資料操作，這會很有幫助。如需 提供之文件模型類別的詳細資訊 適用於 .NET 的 AWS SDK，請參閱 [在 DynamoDB 中使用 .NET 文件模型](DotNetSDKMidLevel.md)。

假設您有名為 `doc` 的 `Document` 物件，且其中包含 `Forum` 項目的表示法。(若要查看如何建構此物件，請參閱本主題後續內容中的 `ToDocument` 方法說明。) 您可以使用 `FromDocument` 從 `Document` 擷取 `Forum` 項目，如下列 C\$1 程式碼範例所示。

**Example**  

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

**注意**  
如果您的 `Document` 物件會實作 `IEnumerable` 介面，您可以使用 `FromDocuments` 方法。這允許您逐一查看 `Document` 中的所有類別執行個體。

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

以 `QueryOperationConfig` 物件中定義的查詢參數執行 `Query` 操作。

**注意**  
若要在背景執行此操作，請改用 `FromQueryAsync` 方法。

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

以 `ScanOperationConfig` 物件中定義的掃描參數執行 `Scan` 操作。

**注意**  
若要在背景執行此操作，請改用 `FromScanAsync` 方法。

## Get​Target​Table
<a name="w2aac17b9c21c23c39c29"></a>

擷取指定類型的目標資料表。如果您正在撰寫自訂轉換器，將任意資料映射至 DynamoDB 資料表，而且需要判斷哪個資料表與自訂資料類型相關聯，則此功能非常有用。

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

從資料表擷取項目。這個方法只需要您希望擷取之項目的主索引鍵。

DynamoDB 預設會傳回數值最終一致的項目。如需最終一致性模式的資訊，請參閱 [DynamoDB 讀取一致性](HowItWorks.ReadConsistency.md)。

`Load` 或 `LoadAsync` 方法會呼叫 [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) 操作，這需要您指定資料表的主索引鍵。由於 `GetItem` 會忽略 `IndexName` 參數，您無法使用索引分割區或排序索引鍵載入項目。因此您必須使用資料表主索引鍵來載入項目。

**注意**  
若要在背景執行此操作，請改用 `LoadAsync` 方法。若要檢視使用 `LoadAsync` 方法在 DynamoDB 資料表執行高階 CRUD 操作的範例，請參閱下列範例。

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

根據您提供的查詢參數查詢資料表。

您只能查詢具有複合主鍵 (分割區索引鍵和排序索引鍵) 的資料表。查詢時，必須指定分割區索引鍵和套用至排序索引鍵的條件。

假設您有用戶端 `Reply` 類別映射至 DynamoDB 中的 `Reply` 資料表。下列 C\$1 程式碼範例會查詢 `Reply` 資料表，找出過去 15 天所張貼的論壇主題回覆。`Reply` 資料表的主索引鍵具有 `Id` 分割區索引鍵和 `ReplyDateTime` 排序索引鍵。

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

這會傳回 `Reply` 物件的集合。

`Query` 方法會傳回「延遲載入」`IEnumerable` 集合。它一開始只會傳回一頁的結果，然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目，您只需要逐一查看 `IEnumerable`。

如果資料表具有簡易主索引鍵 (分割區索引鍵)，您便不能使用 `Query` 方法。不過，您可以使用 `Load` 方法並提供分割區索引鍵來擷取項目。

**注意**  
若要在背景執行此操作，請改用 `QueryAsync` 方法。

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

將指定的物件儲存至資料表。如果輸入物件中指定的主索引鍵不存在於資料表中，該方法會將新項目新增至資料表中。如果主索引鍵存在，該方法會更新現有項目。

如果您已設定樂觀鎖定，則只有在用戶端和項目的伺服器端版本相符時才能成功更新項目。如需詳細資訊，請參閱[使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定](DynamoDBContext.VersionSupport.md)。

**注意**  
若要在背景執行此操作，請改用 `SaveAsync` 方法。

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

執行整個資料表掃描。

您可以指定掃描條件來篩選掃描結果。您可以根據資料表中的任何屬性來評估條件。假設您有用戶端 `Book` 類別映射至 DynamoDB 中的 `ProductCatalog` 資料表。下列 C\$1 範例會掃描資料表，並且只會傳回價格低於 0 的所有書籍項目。

**Example**  

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

`Scan` 方法會傳回「延遲載入」`IEnumerable` 集合。它一開始只會傳回一頁的結果，然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目，您只需要逐一查看 `IEnumerable`。

出於效能考量，您應查詢資料表並避免執行資料表掃描。

**注意**  
若要在背景執行此操作，請改用 `ScanAsync` 方法。

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

從類別執行個體傳回 `Document` 文件模型類別的執行個體。

如果您想使用文件模型類別以及物件持久性模型來執行任何資料操作，這會很有幫助。如需 提供之文件模型類別的詳細資訊 適用於 .NET 的 AWS SDK，請參閱 [在 DynamoDB 中使用 .NET 文件模型](DotNetSDKMidLevel.md)。

假設您有用戶端類別映射至範例 `Forum` 資料表。然後，您可以使用 `DynamoDBContext` 從 `Forum` 資料表中獲取項目作為 `Document` 物件，如下列 C\$1 程式碼範例所示。

**Example**  

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

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

## 指定 DynamoDBContext 的選用參數
<a name="OptionalConfigParams"></a>

使用物件持久性模型時，您可以指定 `DynamoDBContext` 的下列選用參數。
+ **`ConsistentRead`：**當使用 `Load`、`Query` 或 `Scan` 操作來擷取資料時，您可以新增此選用參數來請求資料的最新數值。
+ **`IgnoreNullValues`：**此參數會通知 `DynamoDBContext` 在 `Save` 操作期間忽略屬性上的 Null 數值。如果此參數為 false (或未設定)，則會將 Null 數值轉譯為刪除特定屬性的指令。
+ **`SkipVersionCheck`：**此參數會通知 `DynamoDBContext` 不要在儲存或刪除項目時比較版本。如需版本控制的詳細資訊，請參閱「[使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定](DynamoDBContext.VersionSupport.md)」。
+ **`TableNamePrefix`：**使用特定字串作為所有資料表名稱的字首。如果此參數為 null (或未設定)，則不會使用字首。
+ `DynamoDBEntryConversion` – 指定用戶端使用的轉換結構描述。您可以將此參數設定為版本 V1 或 V2。V1 是預設版本。

  根據您設定的版本，此參數的行為會變更。例如：
  + 在 V1 中，`bool` 資料類型會轉換為 `N` 數字類型，其中 0 代表 false，1 代表 true。在 V2 中，`bool` 會轉換為 `BOOL`。
  + 在 V2 中，清單和陣列不會與 HashSet 一起分組。數值、字串類型和二進位類型的清單和陣列會轉換為 `L` (清單) 類型，可以傳送空白清單來更新清單。這與 V1 不同，其中空白清單不會透過線路傳送。

    在 V1 中，清單、HashSet 和陣列等集合類型都視為相同。清單、HashSet 和數值陣列會轉換為 `NS` (數字集) 類型。

  下列範例會將轉換結構描述版本設定為 V2，變更 .NET 類型和 DynamoDB 資料類型之間的轉換行為。

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

下列 C\$1 範例會指定 `ConsistentRead` 和 `SkipVersionCheck` 這兩個上述選用參數來建立新的 `DynamoDBContext`。

**Example**  

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

`DynamoDBContext` 包含這些選用參數，以及您使用此內容傳送的每個請求。

您可以使用 `DynamoDBContext` 為個別操作指定參數，而不是在 `DynamoDBContext` 層級設定這些參數，如下列 C\$1 程式碼範例所示。此範例會載入特定的書籍項目。`DynamoDBContext` 的 `Load` 方法會指定 `ConsistentRead` 和 `SkipVersionCheck` 等選用參數。

**Example**  

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

在此例中，`DynamoDBContext` 只有在傳送 `Get` 請求時才會包含這些參數。

# 使用 DynamoDB 和 適用於 .NET 的 AWS SDK 物件持久性模型的樂觀鎖定
<a name="DynamoDBContext.VersionSupport"></a>

物件持久性模型中的樂觀鎖定支援可確保應用程式的項目版本與伺服器端的項目版本相同，然後再更新或刪除項目。假設您要擷取待更新的項目。不過，在您傳回更新之前，某些其他應用程式會更新相同的項目。現在應用程式的項目有過時的副本。如果沒有樂觀鎖定，您執行的任何更新都會覆寫其他應用程式所做的更新。

物件持久性模型的樂觀鎖定功能提供了 `DynamoDBVersion` 標籤，可讓您用來啟用樂觀鎖定。若要使用此功能，請在類別中新增一項屬性，以便儲存版本編號。您可以將 `DynamoDBVersion` 屬性加入該屬性。當您第一次儲存物件時，`DynamoDBContext` 會指派版本編號，並在每次更新項目時遞增值。

只有在用戶端物件版本與伺服器端項目的對應版本編號相符時，您的更新或刪除請求才會成功。如果應用程式有過時的副本，它必須先從伺服器取得最新版本，才能更新或刪除該項目。

下列 C\$1 程式碼範例會定義 `Book` 類別，該類別具有將其映射至 `ProductCatalog` 資料表的物件持久性屬性。類別中的 `VersionNumber` 屬性裝飾了會儲存版本編號數值的 `DynamoDBVersion` 屬性。

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

**注意**  
您只可將 `DynamoDBVersion` 屬性套用至可為 null 的數字基本類型 (如 `int?`)。

樂觀鎖定對 `DynamoDBContext` 操作的影響如下：
+ 對於新項目，`DynamoDBContext` 會指派初始版本編號 0。如果您擷取現有項目，請更新其一或多個屬性並嘗試儲存變更，只有在用戶端的版本編號與伺服器端的相符時，儲存操作才會成功。`DynamoDBContext` 會遞增版本號碼。您不需要設定版本編號。
+ `Delete` 方法提供可將主索引鍵值或物件作為參數的多載，如下列 C\$1 程式碼範例所示。  
**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);
  ```

  如果提供物件作為參數，則只有在物件版本符合對應的伺服器端項目版本時才能成功刪除。不過，如果提供主索引鍵值作為參數，`DynamoDBContext` 不知道任何版本編號，其會在沒有檢查是哪個版本的情況下刪除項目。

  請注意，物件持久性模型程式碼中的樂觀鎖定內部實作會使用 DynamoDB 中的條件式更新和條件式刪除 API 動作。

## 停用樂觀鎖定
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

若要停用樂觀鎖定，您可以使用 `SkipVersionCheck` 組態屬性。您可以在建立 `DynamoDBContext` 時設定此屬性。在這種情況下，您使用內容發起的任何請求都會停用樂觀鎖定。如需詳細資訊，請參閱[指定 DynamoDBContext 的選用參數](DotNetDynamoDBContext.md#OptionalConfigParams)。

您可以停用特定操作的樂觀鎖定，而不是在內容層級設定屬性，如下列 C\$1 程式碼範例所示。此範例會使用內容來刪除書籍項目。`Delete` 方法可設定選用 `SkipVersionCheck` 屬性為 true，停用版本檢查。

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

# 使用 適用於 .NET 的 AWS SDK 物件持久性模型使用 DynamoDB 映射任意資料
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

除了支援的 .NET 類型之外 (請參閱 [支援的資料類型](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes))，您還可以使用應用程式中未直接映射至 Amazon DynamoDB 類型的類型。只要您提供轉換器將資料從任意類型轉換為 DynamoDB 類型，物件持久性模型就支援儲存任意類型的資料，反之亦然。轉換器程式碼會在物件的儲存和載入期間轉換資料。

您可以在用戶端建立任何類型。不過，存放在資料表中的資料是 DynamoDB 類型之一；在查詢和掃描期間，所做的任何資料比較都會與存放在 DynamoDB 中的資料進行比較。

下列 C\$1 程式碼範例會定義具有 `Id`、`Title`、`ISBN` 以及 `Dimension` 屬性的 `Book` 類別。`Dimension` 屬性具有 `DimensionType`，可說明 `Height`、`Width` 和 `Thickness` 屬性。範例程式碼提供了轉換器方法 `ToEntry` 和 `FromEntry` 來轉換 `DimensionType` 與 DynamoDB 字串類型之間的資料。例如，在儲存 `Book` 執行個體時，轉換器會建立一個書籍 `Dimension` 字串，例如 "8.5x11x.05"。在擷取書籍時，它會將字串轉換為 `DimensionType` 執行個體。

此範例會將 `Book` 類型映射為 `ProductCatalog` 資料表。它儲存了一個範例 `Book` 執行個體、擷取、更新其維度並再次儲存更新的 `Book`。



如需測試下列範例的逐步說明，請參閱 [.NET 程式碼範例](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;
        }
    }
}
```

# 執行此開發人員指南中的程式碼範例
<a name="CodeSamples"></a>

 AWS SDKs 以下列語言為 Amazon DynamoDB 提供廣泛的支援：
+ [Java](https://aws.amazon.com/sdk-for-java)
+ [瀏覽器中的 JavaScript](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/)

此開發人員指南中的程式碼範例使用下列程式設計語言，提供 DynamoDB 操作的更深入說明：
+ [Java 程式碼範例](CodeSamples.Java.md)
+ [.NET 程式碼範例](CodeSamples.DotNet.md)

在開始此練習之前，您需要建立 AWS 帳戶、取得存取金鑰和私密金鑰，並在電腦上設定 AWS Command Line Interface (AWS CLI)。如需詳細資訊，請參閱[設定 DynamoDB (Web 服務)](SettingUp.DynamoWebService.md)。

**注意**  
如果您使用可下載的 DynamoDB 版本，則需要使用 AWS CLI 來建立資料表和範例資料。您也需要使用每個 AWS CLI 命令指定 `--endpoint-url` 參數。如需詳細資訊，請參閱[設定區域端點](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint)。

# 在 DynamoDB 中建立資料表，以及載入程式碼範例的資料
<a name="SampleData"></a>

如需在 DynamoDB 中建立資料表、在範例資料集中載入、查詢資料以及更新資料的基礎知識，請參閱下文。
+ [步驟 1：在 DynamoDB 建立資料表](getting-started-step-1.md)
+ [步驟 2：將資料寫入 DynamoDB 資料表](getting-started-step-2.md)
+ [步驟 3：從 DynamoDB 資料表讀取資料](getting-started-step-3.md)
+ [步驟 4：更新 DynamoDB 資料表中的資料](getting-started-step-4.md)

# Java 程式碼範例
<a name="CodeSamples.Java"></a>

**Topics**
+ [Java：設定您的 AWS 登入資料](#CodeSamples.Java.Credentials)
+ [Java：設定 AWS 區域和端點](#CodeSamples.Java.RegionAndEndpoint)

此開發人員指南包含 Java 程式碼片段及可立即執行的程式。您可以在以下章節中找到這些程式碼範例：
+ [在 DynamoDB 使用項目和屬性](WorkingWithItems.md)
+ [在 DynamoDB 中使用資料表和資料](WorkingWithTables.md)
+ [在 DynamoDB 中查詢資料表](Query.md)
+ [掃描 DynamoDB 中的資料表](Scan.md)
+ [在 DynamoDB 中使用次要索引來改善資料存取](SecondaryIndexes.md)
+ [Java 1.x：DynamoDBMapper](DynamoDBMapper.md)
+ [DynamoDB Streams 的變更資料擷取](Streams.md)

您可以搭配使用 [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/) 與 Eclipse 來快速開始使用。除了功能完整的 IDE 之外，您還可以取得 適用於 Java 的 AWS SDK 具有自動更新的 ，以及用於建置 AWS 應用程式的預先設定範本。

**執行 Java 程式碼範例 (使用 Eclipse)**

1. 下載並安裝 [Eclipse](http://www.eclipse.org) IDE。

1. 下載並安裝 [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/)。

1. 啟動 Eclipse，然後在 **Eclipse** 選單上，選擇 **File (檔案)**、**New (新建)**，再選擇 **Other (其他)**。

1. 在 **Select a wizard** (選取協助程式) 中，選擇 **AWS**，選擇 **AWS Java Project** (AWS Java 專案)，再選擇 **Next** (下一步)。

1. 在**建立 AWS Java 中**，執行下列動作：

   1. 在**專案名稱** 中，輸入您的專案名稱。

   1. 在 **Select Account (選取帳戶)** 中，從清單選擇您的憑證描述檔。

      如果這是您第一次使用 [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/)，請選擇**設定 AWS 帳戶**來設定您的 AWS 登入資料。

1. 選擇 **Finish (完成)** 建立專案。

1. 從 **Eclipse** 選單，選擇 **File (檔案)**、**New (新建)**，再選擇 **Class (類別)**。

1. 在 **Java Class (Java 類別)** 的 **Name (名稱)** 中，輸入您的類別名稱 (使用與您要執行之程式碼範例相同的名稱)，然後選擇 **Finish (完成)** 建立類別。

1. 將程式碼範例從文件頁面複製到 Eclipse 編輯器。

1. 若要執行程式碼，請在 Eclipse 選單上選擇 **Run (執行)**。

Java 軟體開發套件提供可與 DynamoDB 搭配使用的安全執行緒用戶端。根據最佳實務，您的應用程式應該建立一個用戶端，並在執行緒之間重複使用該用戶端。

如需更多資訊，請參閱[適用於 Java 的 AWS SDK](https://aws.amazon.com/sdk-for-java)。

**注意**  
此指南中的程式碼範例適用於最新版的 適用於 Java 的 AWS SDK。  
如果您使用的是 AWS Toolkit for Eclipse，則可以為適用於 Java 的 SDK 設定自動更新。若要在 Eclipse 中執行此作業，請前往 **Preferences** (偏好設定)，然後依次選擇 **AWS 工具組**、**適用於 Java 的 AWS SDK**、**Download new SDK automatically** (自動下載新的開發套件)。

## Java：設定您的 AWS 登入資料
<a name="CodeSamples.Java.Credentials"></a>

適用於 Java 的 SDK 需要您在執行時間提供 AWS 登入資料給應用程式。本指南中的程式碼範例假設您使用的是 AWS 登入資料檔案，如 *適用於 Java 的 AWS SDK 開發人員指南*中的[設定 AWS 登入資料](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html)中所述。

以下是名為 的 AWS 登入資料檔案範例`~/.aws/credentials`，其中波狀符號字元 (`~`) 代表您的主目錄。

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

## Java：設定 AWS 區域和端點
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

依預設，程式碼範例會存取美國西部 (奧勒岡) 區域的 DynamoDB。您可以修改 `AmazonDynamoDB` 屬性來變更區域。

以下程式碼範例會執行個體化新的 `AmazonDynamoDB`。

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

您可以使用 `withRegion` 方法，對任何可用區域中的 DynamoDB 執行程式碼。如需完整清單，請參閱 *Amazon Web Services 一般參考* 中的 [AWS 區域與端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)。

如果您想要使用 DynamoDB 在電腦本機執行程式碼範例，請設定端點如下：

### 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 程式碼範例
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [.NET：設定您的 AWS 登入資料](#CodeSamples.DotNet.Credentials)
+ [.NET：設定 AWS 區域和端點](#CodeSamples.DotNet.RegionAndEndpoint)

此指南包含 .NET 程式碼片段與可立即執行的程式。您可以在以下章節中找到這些程式碼範例：
+ [在 DynamoDB 使用項目和屬性](WorkingWithItems.md)
+ [在 DynamoDB 中使用資料表和資料](WorkingWithTables.md)
+ [在 DynamoDB 中查詢資料表](Query.md)
+ [掃描 DynamoDB 中的資料表](Scan.md)
+ [在 DynamoDB 中使用次要索引來改善資料存取](SecondaryIndexes.md)
+ [在 DynamoDB 中使用 .NET 文件模型](DotNetSDKMidLevel.md)
+ [使用 .NET 物件持久性模型和 DynamoDB](DotNetSDKHighLevel.md)
+ [DynamoDB Streams 的變更資料擷取](Streams.md)

您可以將 適用於 .NET 的 AWS SDK 與 Toolkit for Visual Studio 搭配使用，以快速開始使用。

**執行 .NET 程式碼範例 (使用 Visual Studio)**

1. 下載並安裝 [Microsoft Visual Studio](https://www.visualstudio.com)。

1. （選用） 下載並安裝 [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/)。

1. 設定您的 AWS 登入資料。在共用登入資料檔案 () 中設定 AWS 登入資料設定檔`~/.aws/credentials`。如需詳細資訊，請參閱《適用於 .NET 的 AWS SDK 開發人員指南》**中的[設定 AWS 憑證](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html)。

1. 啟動 Visual Studio。選擇 **File (檔案)**、**New (新增)**、**Project (專案)**。

1. 搜尋**主控台應用程式**，選取以 .NET 為目標的 C\$1 範本，然後選擇**下一步**。設定您的專案名稱和位置，然後選擇**建立**。

1. 將適用於 DynamoDB NuGet 的 AWS SDK 套件新增至您的專案：

   1. 在方案總管中，開啟您專案的內容 (右鍵) 選單，然後選擇 **Manage NuGet Packages (管理 NuGet 套件)**。

   1. 在 NuGet 套件管理員中，選擇 **Browse (瀏覽)**。

   1. 在搜尋方塊中輸入 **AWSSDK.DynamoDBv2**，並等候搜尋完成。

   1. 選擇 **AWSSDK.DynamoDBv2**，然後選擇 **Install (安裝)**。

1. 在您的 Visual Studio 專案中，開啟 `Program.cs`。將內容取代為您要執行的文件頁面中的程式碼範例。

1. 若要執行程式碼，請在 Visual Studio 工具列中選擇 **Start (啟動)**。

 適用於 .NET 的 SDK 提供使用 DynamoDB 的安全執行緒用戶端。根據最佳實務，您的應用程式應該建立一個用戶端，並在執行緒之間重複使用該用戶端。

如需詳細資訊，請參閱[適用於 .NET 的AWS 軟體開發套件](https://aws.amazon.com/sdk-for-net)。

**注意**  
此指南中的程式碼範例適用於最新版的 適用於 .NET 的 AWS SDK。

## .NET：設定您的 AWS 登入資料
<a name="CodeSamples.DotNet.Credentials"></a>

 適用於 .NET 的 SDK 需要您在執行時間提供 AWS 登入資料給應用程式。本指南中的程式碼範例假設您使用 SDK 存放區來管理 AWS 登入資料檔案，如《 *適用於 .NET 的 AWS SDK 開發人員指南*》中的[使用 SDK 存放區](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store)中所述。

Toolkit for Visual Studio 支援來自任意數目帳戶的多組憑證。每個集合都稱為*描述檔*。Visual Studio 會將項目新增至專案的 `App.config` 檔案，讓您的應用程式可以在執行時間找到 AWS 登入資料。

下列範例顯示預設 `App.config` 檔案，當您使用 Toolkit for Visual Studio 建立新的專案時，就會生成此檔案。

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

在執行時間，程式會使用 `AWSProfileName` 項目指定的`default`一組 AWS 登入資料。 AWS 登入資料本身會以加密形式保存在 SDK 存放區中。Toolkit for Visual Studio 提供圖形化使用者介面來管理所有來自於 Visual Studio 的憑證。如需詳細資訊，請參閱《AWS Toolkit for Visual Studio 使用者指南》中的[指定憑證](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds)。

**注意**  
依預設，程式碼範例會存取美國西部 (奧勒岡) 區域的 DynamoDB。您可以修改 App.config 檔案中的 `AWSRegion` 項目來變更區域。您可以將 `AWSRegion` 設定為 DynamoDB 可用的任何區域。如需完整清單，請參閱 *Amazon Web Services 一般參考* 中的 [AWS 區域與端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)。

## .NET：設定 AWS 區域和端點
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

依預設，程式碼範例會存取美國西部 (奧勒岡) 區域的 DynamoDB。您可以修改 `App.config` 檔案中的 `AWSRegion` 項目來變更區域。或者，您亦可以修改 `AmazonDynamoDBClient` 屬性來變更區域。

以下程式碼範例會執行個體化新的 `AmazonDynamoDBClient`。這會修改用戶端，讓程式碼對不同區域中的 DynamoDB 執行。

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

如需區域的完整清單，請參閱 *Amazon Web Services 一般參考* 中的 [AWS 區域與端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)。

如果您想要使用 DynamoDB 在電腦本機執行程式碼範例，請設定端點如下：

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

# DynamoDB 低階 API
<a name="Programming.LowLevelAPI"></a>

Amazon DynamoDB *低階 API* 為 DynamoDB 的協定層級介面。在此層級中，每個 HTTP(S) 要求都必須依照正確的格式，並附上有效的數位簽章。

 AWS SDKs 會代表您建構低階 DynamoDB API 請求，並處理來自 DynamoDB 的回應。您如此即可專注於應用程式的邏輯，而非低階的結節。但您仍可從了解低階 DynamoDB API 運作方式的基本知識中獲益。

如需低階 DynamoDB API 的詳細資訊，請參閱《[Amazon DynamoDB API 參考](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)》。

**注意**  
DynamoDB Streams 有自己的低階 API，與 DynamoDB 的低階 API 不同，且完全由 AWS SDKs 支援。  
如需詳細資訊，請參閱[DynamoDB Streams 的變更資料擷取](Streams.md)。如需低階 DynamoDB Streams API，請參閱《[Amazon DynamoDB Streams API 參考](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html)》。

低階 DynamoDB API 使用 JavaScript 物件表示法 (JSON) 作為接線協定格式。JSON 以階層顯示資料，以便同時傳達資料值和資料結構。名稱/值對以 `name:value` 格式定義。資料階層由成對的巢狀括住之名稱與值加以定義。

DynamoDB 只會使用 JSON 作為傳輸協定，而非儲存格式。 AWS SDKs 使用 JSON 將資料傳送至 DynamoDB，而 DynamoDB 會以 JSON 回應。DynamoDB 不會以 JSON 格式永久存放資料。

**注意**  
如需 JSON 的詳細資訊，請參閱 `JSON.org` 網站上的 [JSON 簡介](http://json.org)。

**Topics**
+ [要求格式](#Programming.LowLevelAPI.RequestFormat)
+ [回應格式](#Programming.LowLevelAPI.ResponseFormat)
+ [資料類型描述項](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [數值資料](#Programming.LowLevelAPI.Numbers)
+ [二進位資料](#Programming.LowLevelAPI.Binary)

![\[DynamoDB 低階 API 和 AWS SDKs處理通訊協定層級請求和回應的方式。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## 要求格式
<a name="Programming.LowLevelAPI.RequestFormat"></a>

DynamoDB 低階 API 接受 HTTP(S) `POST` 請求作為輸入。 AWS 軟體開發套件會為您建構這些請求。

假設您有一個名為 `Pets` 的資料表，其索引鍵結構描述由 `AnimalType` (分割區索引鍵) 及 `Name` (排序索引鍵) 所組成。這些屬性的類型皆為 `string`。若要從 擷取項目`Pets`，軟體 AWS 開發套件會建構下列請求。

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

請注意以下此要求的相關事宜：
+ `Authorization` 標頭包含 DynamoDB 驗證請求所需之資訊。如需詳細資訊，請參閱 中的[簽署 AWS API 請求](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)和[簽署第 4 版簽署程序](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)*Amazon Web Services 一般參考*。
+ `X-Amz-Target` 標頭包含 DynamoDB 操作的名稱：`GetItem`。(此也會同時附上低階 API 版本，在此案例中為 `20120810`。)
+ 要求的承載 (主體) 包含操作的參數 (JSON 格式)。若是 `GetItem` 操作，參數為 `TableName` 與 `Key`。

## 回應格式
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

收到請求時，DynamoDB 會處理該請求並會傳回回應。針對前述的要求，HTTP(S) 回應承載會包含操作的結果，如下列範例中所示。

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

此時， AWS 軟體開發套件會將回應資料傳回至您的應用程式，以供進一步處理。

**注意**  
若 DynamoDB 無法處理請求，其會傳回 HTTP 錯誤碼及訊息。 AWS 軟體開發套件會以例外狀況的形式，將這些傳播到您的應用程式。如需詳細資訊，請參閱[使用 DynamoDB 時發生錯誤](Programming.Errors.md)。

## 資料類型描述項
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

低階 DynamoDB API 協定需要每個屬性都要附有一個資料類型的描述項。*資料類型描述項*是告知 DynamoDB 如何解譯每項屬性的字符。

「[要求格式](#Programming.LowLevelAPI.RequestFormat)」與「[回應格式](#Programming.LowLevelAPI.ResponseFormat)」中的範例，展示如何使用資料類型描述項的範例。`GetItem` 要求指定 `Pets` 索引鍵結構描述屬性 (`AnimalType` 與 `Name`) 為 `S`，即類型為 `string`。`GetItem` 回應包含具有 `string` (`S`)、`number` (`N`)、`map` (`M`) 以及 `list` (`L`) 類型屬性的 *Pets* 項目。

下列為 DynamoDB 資料類型描述項的完整清單：
+ **`S`**：字串
+ **`N`**：數字
+ **`B`**：二進位
+ **`BOOL`**：布林值
+ **`NULL`**：Null
+ **`M`**：映射
+ **`L`**：清單
+ **`SS`**：字串集合
+ **`NS`**：數字集合
+ **`BS`**：二進位集合

下表顯示每個資料類型描述項的正確 JSON 格式。請注意，數字會以字串表示以保留精確度，而布林值和 null 則使用其原生 JSON 類型。


| 描述項 | JSON format (JSON 格式) | 備註 | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | 值是 JSON 字串。 | 
| N | \$1"N": "123.45"\$1 | 值是字串，而不是 JSON 號碼。這可保留跨語言的精確度。 | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | 值是 base64 編碼字串。 | 
| BOOL | \$1"BOOL": true\$1 | 值是 JSON 布林值 (true 或 false)，而不是字串。 | 
| NULL | \$1"NULL": true\$1 | 值是true表示 null 的 JSON 布林值。 | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | 值是屬性名稱值對的 JSON 物件。 | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | 值是屬性值的 JSON 陣列。 | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | 值是字串的 JSON 陣列。 | 
| NS | \$1"NS": ["1", "2.5"]\$1 | 值是數字字串的 JSON 陣列。 | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | 值是 base64 編碼字串的 JSON 陣列。 | 

**注意**  
 如需 DynamoDB 資料類型的詳細說明，請參閱 [資料類型](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)。

## 數值資料
<a name="Programming.LowLevelAPI.Numbers"></a>

不同的程式語言提供不同程度的 JSON 支援。在某些情況下，您可能會決定要使用第三方的程式庫進行 JSON 文件之驗證及剖析。

某些第三方程式庫會依據 JSON 數字類型建置，提供其本身的類型，例如 `int`、`long` 或 `double`。但 DynamoDB 中的原生數字資料類型，無法精確地映射到這些其他資料類型，所以這些類型的差異可能會導致衝突。此外，許多 JSON 程式庫不會處理固定精確度的數值，而是會自動針對包含小數點的數字，推斷為雙精確度資料類型。

為解決這些問題，DynamoDB 提供了不會造成資料遺失的單一數字類型。為避免不必要的隱含轉換為雙精確度值，DynamoDB 使用字串來進行數值資料傳輸。此方法提供了更新屬性值的彈性，同時還能維持適當的排序語意，例如將值 "01"、"2" 及 "03" 依適當的順序排列。

若數字精確度對您的應用程式來說很重要，則應在將其傳遞至 DynamoDB 之前，先將數值轉換為字串。

## 二進位資料
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB 支援二進制屬性。但 JSON 原本並不支援二進位資料的編碼。若要在要求中傳送二進位資料，您必須將其編碼為 Base64 格式。在接收到請求時，DynamoDB 會將 Base64 資料解碼回二進位。

DynamoDB 使用的 base64 編碼結構描述會在 Internet Engineering Task Force (IETF) 網站上的 [RFC 4648](http://tools.ietf.org/html/rfc4648) 說明。