

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

# 開始使用 DynamoDB 增強型用戶端 API
<a name="ddb-en-client-getting-started"></a>

以下教學課程向您介紹使用 DynamoDB 增強型用戶端 API 所需的基本概念。

## 新增相依性
<a name="ddb-en-client-gs-dep"></a>

若要開始在專案中使用 DynamoDB 增強型用戶端 API，請在 `dynamodb-enhanced` Maven 成品上新增相依性。這會顯示在下列範例中。

------
#### [ Maven ]

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version><VERSION></version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>dynamodb-enhanced</artifactId>
    </dependency>
  </dependencies>
  ...
</project>
```

對 Maven 中央儲存庫執行[最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)的搜尋，並以此值取代 *<VERSION>*。

------
#### [ Gradle ]

```
repositories {
    mavenCentral()
}
dependencies {
    implementation(platform("software.amazon.awssdk:bom:<VERSION>"))
    implementation("software.amazon.awssdk:dynamodb-enhanced")
    ...
}
```

對 Maven 中央儲存庫執行[最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)的搜尋，並以此值取代 *<VERSION>*。

------

# `TableSchema` 從資料類別產生
<a name="ddb-en-client-gs-tableschema"></a>

`[TableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableSchema.html)` 可讓增強型用戶端在用戶端類別之間映射 DynamoDB 屬性值。在本教學課程中，您將了解衍生自靜態資料類別並使用建置器從程式碼產生的 `TableSchema`。

## 使用標註的資料類別
<a name="ddb-en-client-gs-tableschema-anno-bean"></a>

適用於 Java 的 SDK 2.x 包含[一組註釋](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html)，您可以搭配資料類別使用，以快速產生 `TableSchema`，將您的類別映射至資料表。

首先建立符合 [JavaBean 規格](https://download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf)的資料類別。規格要求 類別具有無引數的公有建構函數，並具有類別中每個屬性的 getter 和 setter。包含類別層級註釋，表示資料類別是 `DynamoDbBean`。此外，在 getter 或 setter 上至少包含主索引鍵屬性的`DynamoDbPartitionKey`註釋。

您可以將[屬性層級註釋](ddb-en-client-anno-index.md)套用至 getter 或 setter，但不能同時套用兩者。

**注意**  
此術語`property`通常用於封裝在 JavaBean 中的值。不過，本指南會`attribute`改用 一詞，以符合 DynamoDB 所使用的術語。

下列`Customer`類別顯示將類別定義連結至 DynamoDB 資料表的註釋。

### `Customer` 類別
<a name="ddb-en-client-gs-tableschema-anno-bean-cust"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbBean
public class Customer {

    private String id;
    private String name;
    private String email;
    private Instant regDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }

    public void setId(String id) { this.id = id; }

    public String getCustName() { return this.name; }

    public void setCustName(String name) { this.name = name; }

    @DynamoDbSortKey
    public String getEmail() { return this.email; }

    public void setEmail(String email) { this.email = email; }

    public Instant getRegistrationDate() { return this.regDate; }

    public void setRegistrationDate(Instant registrationDate) { this.regDate = registrationDate; }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", email=" + email
                + ", regDate=" + regDate + "]";
    }
}
```

建立註釋的資料類別之後，請使用它來建立 `TableSchema`，如下列程式碼片段所示。

```
static final TableSchema<Customer> customerTableSchema = TableSchema.fromBean(Customer.class);
```

`TableSchema` 的設計是靜態且不變的。您通常可以在類別載入時間將其執行個體化。

靜態`TableSchema.fromBean()`原廠方法會向 Bean 自我檢查，以產生 DynamoDB 屬性之間資料類別屬性 （屬性） 的映射。

如需使用由數個資料類別組成之資料模型的範例，請參閱 [使用 Bean、地圖、清單和集合等屬性](ddb-en-client-adv-features-nested.md)區段中的 `Person`類別。

## 使用建置器
<a name="ddb-en-client-gs-tableschema-builder"></a>

如果您在程式碼中定義資料表結構描述，則可以略過 Bean 自我檢查的成本。如果您編寫結構描述的程式碼，您的類別就不需要遵循 JavaBean 命名標準，也不需要加上註釋。下列範例使用建置器，相當於使用註釋的`Customer`類別範例。

```
static final TableSchema<Customer> customerTableSchema =
                TableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(Customer::getId)
                                .setter(Customer::setId)
                                .tags(StaticAttributeTags.primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("email")
                                .getter(Customer::getEmail)
                                .setter(Customer::setEmail)
                                .tags(StaticAttributeTags.primarySortKey()))
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getCustName)
                                .setter(Customer::setCustName))
                        .addAttribute(Instant.class, a -> a.name("registrationDate")
                                .getter(Customer::getRegistrationDate)
                                .setter(Customer::setRegistrationDate))
                        .build();
```

# 建立增強型用戶端和 `DynamoDbTable`
<a name="ddb-en-client-getting-started-dynamodbTable"></a>

## 建立增強型用戶端
<a name="ddb-en-client-getting-started-dynamodbTable-eclient"></a>

[DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html) 類別或其非同步對應 [DynamoDbEnhancedAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedAsyncClient.html) 是使用 DynamoDB 增強型用戶端 API 的進入點。

增強型用戶端需要標準 `[DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)`才能執行工作。API 提供兩種建立`DynamoDbEnhancedClient`執行個體的方式。下列程式碼片段中顯示的第一個選項會建立標準`DynamoDbClient`，其中包含從組態設定中挑選的預設設定。

```
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();
```

如果您想要設定基礎標準用戶端，您可以將其提供給增強型用戶端的建置器方法，如下列程式碼片段所示。

```
// Configure an instance of the standard DynamoDbClient.
DynamoDbClient standardClient = DynamoDbClient.builder()
    .region(Region.US_EAST_1)
    .credentialsProvider(ProfileCredentialsProvider.create())
    .build();

// Use the configured standard client with the enhanced client.
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
    .dynamoDbClient(standardClient)
    .build();
```

## 建立 `DynamoDbTable` 執行個體
<a name="ddb-en-client-getting-started-dynamodbTable-table"></a>

將 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)視為 DynamoDB 資料表的用戶端表示法，該資料表使用 提供的映射功能`TableSchema`。`DynamoDbTable` 類別提供 CRUD 操作的方法，可讓您與單一 DynamoDB 資料表互動。

`DynamoDbTable<T>` 是採用單一類型引數的一般類別，無論是自訂類別，還是使用文件類型項目`EnhancedDocument`時的 。此引數類型會建立您使用的類別與單一 DynamoDB 資料表之間的關係。

使用 的`table()`原廠方法`DynamoDbEnhancedClient`建立`DynamoDbTable`執行個體，如下列程式碼片段所示。

```
static final DynamoDbTable<Customer> customerTable = 
        enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

`DynamoDbTable` 執行個體是單調的候選項目，因為它們不可變，可用於整個應用程式。

您的程式碼現在具有可使用`Customer`執行個體的 DynamoDB 資料表的記憶體內表示法。實際的 DynamoDB 資料表可能存在，也可能不存在。如果名為 的資料表`Customer`已存在，您可以開始對其執行 CRUD 操作。如果不存在，請使用`DynamoDbTable`執行個體來建立資料表，如下一節所述。

# 視需要建立 DynamoDB 資料表
<a name="ddb-en-client-gs-ddbtable"></a>

建立`DynamoDbTable`執行個體之後，請使用它在 DynamoDB 中執行資料表的*一次性*建立。

## 建立資料表範例程式碼
<a name="ddb-en-client-gs-ddbtable-createex"></a>

下列範例會根據`Customer`資料類別建立 DynamoDB 資料表。

此範例會使用與類別名稱`Customer`相同的名稱建立 DynamoDB 資料表，但資料表名稱可以是其他名稱。無論您如何命名資料表，您都必須在其他應用程式中使用此名稱，才能使用資料表。每當您建立另一個`DynamoDbTable`物件時，請將此名稱提供給 `table()`方法，以便使用基礎 DynamoDB 資料表。

Java lambda 參數 `builder`傳遞至 `createTable`方法可讓您[自訂資料表](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/CreateTableEnhancedRequest.Builder.html)。在此範例中，已設定[佈建輸送量](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual)。如果您想要在建立資料表時使用預設設定，請略過建置器，如下列程式碼片段所示。

```
customerTable.createTable();
```

使用預設設定時，不會設定佈建輸送量的值。而是將資料表的計費模式設定為[隨需](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand)。

此範例也會在嘗試列印回應中收到的資料表名稱`[DynamoDbWaiter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/waiters/DynamoDbWaiter.html)`之前，使用 。建立資料表需要一些時間。因此，使用等待程式表示您不需要撰寫輪詢 DynamoDB 服務的邏輯，即可在使用資料表之前查看資料表是否存在。

### 匯入
<a name="ddb-en-client-gs-ddbtable-imports"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.core.internal.waiters.ResponseOrException;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.CreateTableEnhancedRequest;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter;
```

### Code
<a name="ddb-en-client-gs-ddbtable-code"></a>

```
 public static void createCustomerTable(DynamoDbTable<Customer> customerTable, DynamoDbClient standardClient) {
     // Create the DynamoDB table using the 'customerTable' DynamoDbTable instance.
     customerTable.createTable(builder -> builder
             .provisionedThroughput(b -> b
                     .readCapacityUnits(10L)
                     .writeCapacityUnits(10L)
                     .build())
     );
     // The DynamoDbClient instance (named 'standardClient') passed to the builder for the DynamoDbWaiter is the same instance
     // that was passed to the builder of the DynamoDbEnhancedClient instance that we created previously.
     // By using the same instance, it ensures that the same Region that was configured on the standard DynamoDbClient 
     // instance is used for other service clients that accept a DynamoDbClient during construction.
     try (DynamoDbWaiter waiter = DynamoDbWaiter.builder().client(standardClient).build()) { // DynamoDbWaiter is Autocloseable
         ResponseOrException<DescribeTableResponse> response = waiter
                 .waitUntilTableExists(builder -> builder.tableName("Customer").build())
                 .matched();
         DescribeTableResponse tableDescription = response.response().orElseThrow(
                 () -> new RuntimeException("Customer table was not created."));
         // The actual error can be inspected in response.exception()
         logger.info("Customer table was created.");
     }
 }
```

**注意**  
從資料類別產生資料表時，DynamoDB 資料表的屬性名稱會以小寫字母開頭。如果您希望資料表的屬性名稱以大寫字母開頭，請使用 [`@DynamoDbAttribute(NAME)`註釋](ddb-en-client-adv-features-inex-attr.md)，並提供您想要做為參數的名稱。

# 執行 操作
<a name="ddb-en-client-gs-use"></a>

建立資料表之後，請使用`DynamoDbTable`執行個體對 DynamoDB 資料表執行操作。

在下列範例中，單一項目`DynamoDbTable<Customer>`會與[`Customer`資料類別](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust)執行個體一起做為參數傳遞，以將新項目新增至資料表。

```
    public static void putItemExample(DynamoDbTable<Customer> customerTable, Customer customer){
        logger.info(customer.toString());
        customerTable.putItem(customer);
    }
```

## `Customer` 物件
<a name="perform_ops_create_customer_instatnce"></a>

```
        Customer customer = new Customer();
        customer.setId("1");
        customer.setCustName("Customer Name");
        customer.setEmail("customer@example.com");
        customer.setRegistrationDate(Instant.parse("2023-07-03T10:15:30.00Z"));
```

將`customer`物件傳送至 DynamoDB 服務之前，請記錄物件`toString()`方法的輸出，將其與增強型用戶端傳送的內容進行比較。

```
Customer [id=1, name=Customer Name, email=customer@example.com, regDate=2023-07-03T10:15:30Z]
```

線路層級記錄會顯示所產生請求的承載。增強型用戶端會從資料類別產生低階表示。`regDate` 屬性是 Java 中的`Instant`類型，以 DynamoDB 字串表示。

```
{
  "TableName": "Customer",
  "Item": {
    "registrationDate": {
      "S": "2023-07-03T10:15:30Z"
    },
    "id": {
      "S": "1"
    },
    "custName": {
      "S": "Customer Name"
    },
    "email": {
      "S": "customer@example.com"
    }
  }
}
```

# 使用現有資料表
<a name="ddb-en-client-gs-existingtable"></a>

上一節說明如何從 Java 資料類別開始建立 DynamoDB 資料表。如果您已經有現有的資料表，並想要使用增強型用戶端的功能，您可以建立 Java 資料類別來使用資料表。您需要檢查 DynamoDB 資料表，並將必要的註釋新增至資料類別。

在使用現有資料表之前，請呼叫 `DynamoDbEnhanced.table()`方法。這在上一個範例中使用下列陳述式完成。

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

傳回`DynamoDbTable`執行個體之後，您可以立即開始使用基礎資料表。您不需要透過呼叫 `DynamoDbTable.createTable()`方法重新建立資料表。

下列範例示範如何立即從 DynamoDB 資料表擷取`Customer`執行個體。

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
// The Customer table exists already and has an item with a primary key value of "1" and a sort key value of "customer@example.com".
customerTable.getItem(
        Key.builder().
                partitionValue("1").
                sortValue("customer@example.com").build());
```

**重要**  
`table()` 方法中使用的資料表名稱必須符合現有的 DynamoDB 資料表名稱。