

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# DynamoDB Enhanced Client API の使用を開始する
<a name="ddb-en-client-getting-started"></a>

次のチュートリアルでは、DynamoDB Enhanced Client API を操作するために必要な基本事項を紹介します。

## 依存関係を追加する
<a name="ddb-en-client-gs-dep"></a>

プロジェクトで DynamoDB Enhanced Client 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 central リポジトリで[最新バージョン](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 central リポジトリで[最新バージョン](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>

SDK for Java 2.x には、データクラスと一緒に使用することで、Java Bean で使用して、クラスをテーブルにマッピングするための `TableSchema` をすばやく生成できる[一連の注釈](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html)が含まれています。

まず、[JavaBean 仕様](https://download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf)に準拠するデータクラスを作成します。この仕様では、クラスには引数のないパブリックコンストラクタが必要であり、クラスの各属性にはゲッターとセッターが必要です。データクラスが `DynamoDbBean` であることを示すクラスレベルの注釈を含めます。また、少なくとも、 getters と setters にはプライマリキー属性の `DynamoDbPartitionKey` 注釈を含めます。

[属性レベルの注釈](ddb-en-client-anno-index.md)はゲッターまたはセッターに適用できますが、両方に適用することはできません。

**注記**  
通常、`property` という用語は JavaBean にカプセル化された値に使用されます。ただし、このガイドでは、DynamoDB で使用されている用語との一貫性を保つため、代わりに `attribute` という用語を使用しています。

次の `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、Map、List、Set の属性を使用する](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>

[DDynamoDbEnhancedClient](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 Enhanced Client API を操作するためのエントリポイントです。

拡張クライアントでは、作業を実行するための標準の `[DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)` が必要です。API には、`DynamoDbEnhancedClient` インスタンスを作成する 2 つの方法があります。以下のスニペットに示す 1 つ目のオプションは、構成設定から選択したデフォルト設定を使用して標準の `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) は、`TableSchema` によって提供されるマッピング機能を使用する DynamoDB テーブルのクライアント側表現と考えます。`DynamoDbTable` クラスには、単一の DynamoDB テーブルを操作できる CRUD オペレーションのメソッドが用意されています。

`DynamoDbTable<T>` は、カスタムクラスでもドキュメントタイプのアイテムを操作するときの `EnhancedDocument` でも、単一の型引数を取る汎用クラスです。この引数タイプは、使用するクラスと単一の DynamoDB テーブルとの関係を確立します。

次のスニペットに示すように、`DynamoDbEnhancedClient` の `table()` ファクトリメソッドを使用して、`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 でテーブルを *1 回*だけ作成します。

## テーブル作成例コード
<a name="ddb-en-client-gs-ddbtable-createex"></a>

次の例では、`Customer` データクラスに基づいて DynamoDB テーブルを作成します。

この例では、クラス名と同じ `Customer` という名前で DynamoDB テーブルを作成しますが、テーブル名は別の名前でもかまいません。テーブルにどのような名前を付けるにしても、テーブルを操作するには他のアプリケーションでもこの名前を使用する必要があります。基になる DynamoDB テーブルを操作するために、別の `DynamoDbTable` オブジェクトを作成するときはいつでも、この名前を `table()` メソッドに指定してください。

`createTable` メソッドに渡される Java lambda パラメータ、`builder`、によって、[テーブルをカスタマイズ](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;
```

### コード
<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 テーブルに対して操作を実行します。

次の例では、[`Customer` データクラス](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust)のインスタンスとともにシングルトン `DynamoDbTable<Customer>` をパラメータとして渡し、テーブルに新しいアイテムを追加します。

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

ワイヤレベルのログ記録には、生成されたリクエストのペイロードが表示されます。拡張クライアントはデータクラスから低レベルの表現を生成しました。Java の `Instant` タイプである `regDate` 属性は、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 テーブル名と一致する必要があります。