

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

# のバージョン 1 とバージョン 2 の DynamoDB マッピング API の違い AWS SDK for Java
<a name="ddb-mapping"></a>

 AWS SDK for Javaのバージョン 1 とバージョン 2 で、DynamoDB マッピング API が大幅に変更されました。バージョン 1 では、 `DynamoDBMapper` を使用して Java POJO を操作します。バージョン 2 では、更新されたメソッド名、拡張されたスキーマ定義オプション、より安全な型を利用できる `DynamoDbEnhancedClient` を使用します。

主な変更点は次のとおりです。
+ 新しいメソッド名 (`getItem` の代わりに `load` など)
+ 明示的なテーブルスキーマの作成
+ 同期オペレーションと非同期オペレーション両方の組み込みサポート
+ 空の文字列と設定の処理方法の変更

このセクションでは、マッピング API の変更、注釈の違い、設定の更新について説明し、v1 `DynamoDBMapper` から v2 `DynamoDbEnhancedClient` への移行に役立つ移行ガイダンスを提供します。

**Contents**
+ [SDK for Java のバージョン 1 からバージョン 2 での、マッピングライブラリ高レベル変更](dynamodb-mapping-high-level.md)
  + [依存関係の差異をインポートする](dynamodb-mapping-high-level.md#dynamodb-mapping-deps)
+ [SDK for Java のバージョン 1 とバージョン 2 での DynamoDB マッピング API の変更](dynamodb-mapping-api-changes.md)
  + [クライアントの作成](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-client)
  + [DynamoDB テーブル/インデックスへのマッピングを確立する](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-mapping)
  + [Table operations](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-tobleops)
  + [クラスとプロパティをマッピングする](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas)
    + [Bean 注釈](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos)
    + [V2 の追加注釈](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos-v2-addnl)
  + [設定](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration)
    + [オペレーションごとの設定](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration-per-op)
  + [条件式](dynamodb-mapping-api-changes.md#dynamodb-mapping-conditionals)
  + [型変換](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv)
    + [デフォルトコンバータ](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-defaults)
    + [属性のカスタムコンバータを設定する](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-anno)
    + [タイプコンバータファクトリまたはプロバイダーを追加する](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-factory)
+ [SDK for Java のバージョン 1 とバージョン 2 の文字列処理の違い](dynamodb-migration-string-handling.md)
+ [SDK for Java のバージョン 1 とバージョン 2 の楽観的ロックの違い](dynamodb-migrate-optimstic-locking.md)
+ [SDK for Java のバージョン 1 とバージョン 2 の Fluent セッターの違い](dynamodb-migrate-fluent-setters.md)

# SDK for Java のバージョン 1 からバージョン 2 での、マッピングライブラリ高レベル変更
<a name="dynamodb-mapping-high-level"></a>

各ライブラリのマッピングクライアントの名前は、V1 と V2 で異なります。
+ V1 - DynamoDBMapper
+ V2 - DynamoDB Enhanced Client

2 つのライブラリの使用方法はほぼ同じです。マッパー/クライアントをインスタンス化し、これらの項目を DynamoDB テーブルに対して読み書きする API に Java POJO を渡します。どちらのライブラリも POJO のクラスに注釈を提供し、クライアントが POJO をどのように処理するかを指示します。

V2 に移行する場合の顕著な違いは次のとおりです。
+ V2 と V1 は、低レベルの DynamoDB オペレーションに異なるメソッド名を使用します。例えば、次のようになります。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-java/latest/developer-guide/dynamodb-mapping-high-level.html)
+ V2 には、テーブルスキーマを定義し、POJO をテーブルにマッピングする複数の方法があります。注釈を使用することも、ビルダーを使用してコードから生成されたスキーマを使用することもできます。V2 は、変更可能なバージョンと変更不可能なバージョンのスキーマも提供します。
+ V2 では、最初のステップの 1 つとしてテーブルスキーマを具体的に作成しますが、V1 では、テーブルスキーマは必要に応じて注釈付きクラスから推測されます。
+ V2 には拡張クライアント API に[ドキュメント API クライアント](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html)が含まれていますが、V1 は[別の API](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/DynamoDB.html) を使用します。
+ V2 では、すべての API が同期バージョンと非同期バージョンで使用できます。

V2 拡張クライアントの詳細については、本ガイドの [「DynamoDB マッピング」セクション](dynamodb-enhanced-client.md)を参照してください。

## 依存関係の差異をインポートする
<a name="dynamodb-mapping-deps"></a>


| V1 | V2 | 
| --- | --- | 
|  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>com.amazonaws</groupId><br />      <artifactId>aws-java-sdk-bom</artifactId><br />      <version>1.X.X</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>com.amazonaws</groupId><br />    <artifactId>aws-java-sdk-dynamodb</artifactId><br />  </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>software.amazon.awssdk</groupId><br />      <artifactId>bom</artifactId><br />      <version>2.X.X*</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>software.amazon.awssdk</groupId><br />    <artifactId>dynamodb-enhanced</artifactId><br />  </dependency><br /></dependencies></pre>  | 

\$1 [最新バージョン](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)

V1 では、1 つの依存関係に低レベルの DynamoDB API とマッピング/ドキュメント API の両方が含まれますが、V2 では、`dynamodb-enhanced` アーティファクト依存関係を使用してマッピング/ドキュメント API にアクセスします。`dynamodb-enhanced` モジュールには、低レベル `dynamodb` モジュールへの推移的な依存関係が含まれています。

# SDK for Java のバージョン 1 とバージョン 2 での DynamoDB マッピング API の変更
<a name="dynamodb-mapping-api-changes"></a>

## クライアントの作成
<a name="dynamodb-mapping-api-changes-client"></a>


****  

| ユースケース | V1 | V2 | 
| --- | --- | --- | 
|   通常のインスタンス化  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard()<br />    .withCredentials(credentialsProvider)<br />    .withRegion(Regions.US_EAST_1)<br />    .build();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbClient standardClient = DynamoDbClient.builder()<br />    .credentialsProvider(ProfileCredentialsProvider.create())<br />    .region(Region.US_EAST_1)<br />    .build();<br />DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .build();</pre>  | 
|   最小限のインスタンス化  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();</pre>  | 
|   属性トランスフォーマーを使用\$1  |  <pre>DynamoDBMapper mapper = new DynamoDBMapper(standardClient, <br />                        attributeTransformerInstance);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .extensions(extensionAInstance, extensionBInstance)<br />    .build();</pre>  | 

\$1V2 の拡張機能は、V1 の属性トランスフォーマーにほぼ対応しています。[拡張機能を使用して DynamoDB 拡張クライアントオペレーションをカスタマイズする](ddb-en-client-extensions.md) セクションには、V2 の拡張機能に関する詳細情報が記載されています。

## DynamoDB テーブル/インデックスへのマッピングを確立する
<a name="dynamodb-mapping-api-changes-mapping"></a>

V1 では、Bean 注釈を使用して DynamoDB テーブル名を指定します。V2 では、ファクトリメソッドである `table()` がリモート DynamoDB テーブルを表す `DynamoDbTable` のインスタンスを生成します。`table()` メソッドの最初のパラメータは、DynamoDB テーブル名です。


****  

| ユースケース | V1 | V2 | 
| --- | --- | --- | 
|   Java POJO クラスを DynamoDB テーブルにマッピングする  |  <pre>@DynamoDBTable(tableName ="Customer")<br />public class Customer {<br />  ...<br />}</pre>  |  <pre>DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer",<br />    TableSchema.fromBean(Customer.class));</pre>  | 
|   DynamoDB セカンダリインデックスへのマッピング  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) [V1 の `query` メソッド](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.query)について説明する DynamoDB デベロッパーガイドのセクションでは、完全な例を示しています。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) 詳細については、このガイドの「[セカンダリインデックスを使用する](ddb-en-client-use-secindex.md)」セクションを参照してください。  | 

## Table operations
<a name="dynamodb-mapping-api-changes-tobleops"></a>

このセクションでは、ほとんどの標準的なユースケースにおいて V1 と V2 で異なるオペレーション API について説明します。

V2 では、単一のテーブルを含むすべてのオペレーションが、拡張クライアントではなく `DynamoDbTable` インスタンスで呼び出されます。拡張クライアントには、複数のテーブルをターゲットにできるメソッドが含まれています。

以下の「*テーブルオペレーション*」という表では、POJO インスタンスは `item` または `customer1` などの特定のタイプとして記載されています。V2 の例の場合、`table` という名前のインスタンスは、`DynamoDbTable` インスタンスへの参照を返す `enhancedClient.table()` を以前に呼び出した結果です。

ほとんどの V2 オペレーションは、表示されていない場合で fluent コンシューマーパターンで呼び出すことができます。例えば、

```
Customer customer = table.getItem(r → r.key(key));
  or
Customer customer = table.getItem(r → r.key(k -> k.partitionValue("id").sortValue("email")))
```

V1 オペレーションの場合、テーブルオペレーション** (以下) には一般的に使用される形式の一部のみが含まれており、すべてのオーバーロードされた形式が含まれているわけではありません。たとえば、 `load()` メソッドには次のオーバーロードがあります。

```
mapper.load(Customer.class, hashKey)
mapper.load(Customer.class, hashKey, rangeKey)
mapper.load(Customer.class, hashKey, config)
mapper.load(Customer.class, hashKey, rangeKey, config)
mapper.load(item)
mapper.load(item, config)
```

テーブルオペレーション* *(以下) は、一般的に使用される形式を示しています。

```
mapper.load(item)
mapper.load(item, config)
```


**Table operations**  

| ユースケース | V1 | V2 | 
| --- | --- | --- | 
|  Java POJO を DynamoDB テーブルに書き込む **DynamoDB オペレーション:**、`PutItem`、`UpdateItem`  |  <pre>mapper.save(item)<br />mapper.save(item, config)<br />mapper.save(item, saveExpression, config)</pre> V1 では、`DynamoDBMapperConfig.SaveBehavior` および注釈によって、呼び出される低レベルの DynamoDB メソッドが決まります。一般的に、`SaveBehavior.CLOBBER` と `SaveBehavior.PUT` を使用する場合を除いて `UpdateItem` が呼び出されます。自動生成されたキーは特殊なユースケースであり、`PutItem` と `UpdateItem` の両方が使用されることもあります。  |  <pre>table.putItem(putItemRequest)<br />table.putItem(item)<br />table.putItemWithResponse(item) //Returns metadata.<br /><br />updateItem(updateItemRequest)<br />table.updateItem(item)<br />table.updateItemWithResponse(item) //Returns metadata.</pre>  | 
|  DynamoDB テーブルから Java POJO に項目を読み込む **DynamoDB オペレーション:** `GetItem`  |  <pre>mapper.load(item)<br />mapper.load(item, config)</pre>  |  <pre>table.getItem(getItemRequest)<br />table.getItem(item)<br />table.getItem(key)<br />table.getItemWithResponse(key) //Returns POJO with metadata.</pre>  | 
|  DynamoDB テーブルから項目を削除します。 **DynamoDB オペレーション:** `DeleteItem`  |  <pre>mapper.delete(item, deleteExpression, config)</pre>  |  <pre>table.deleteItem(deleteItemRequest)<br />table.deleteItem(item)<br />table.deleteItem(key)</pre>  | 
|  DynamoDB テーブルまたはセカンダリインデックスをクエリし、ページ分割されたリストを返します。 **DynamoDB オペレーション:** `Query`  |  <pre>mapper.query(Customer.class, queryExpression)<br />mapper.query(Customer.class, queryExpression, <br />                             mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> 同期レスポンスには返された `PageIterable.stream()` (遅延読み込み) を、非同期レスポンスには `PagePublisher.subscribe()` を使用します。  | 
|  DynamoDB テーブルまたはセカンダリインデックスをクエリしてリストを返します。 **DynamoDB オペレーション:** `Query`  |  <pre>mapper.queryPage(Customer.class, queryExpression)<br />mapper.queryPage(Customer.class, queryExpression, <br />                                 mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> 同期レスポンスには返された `PageIterable.items()` (遅延読み込み) を、非同期レスポンスには `PagePublisher.items.subscribe()` を使用します。  | 
|  DynamoDB テーブルまたはセカンダリインデックスをスキャンしてページ分割されたリストを返します。 **DynamoDB オペレーション:** `Scan`  |  <pre>mapper.scan(Customer.class, scanExpression)<br />mapper.scan(Customer.class, scanExpression, <br />                            mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> 同期レスポンスには返された `PageIterable.stream()` (遅延読み込み) を、非同期レスポンスには `PagePublisher.subscribe()` を使用します。  | 
|  DynamoDB テーブルまたはセカンダリインデックスをスキャンしてリストを返します。 **DynamoDB オペレーション:** `Scan`  |  <pre>mapper.scanPage(Customer.class, scanExpression)<br />mapper.scanPage(Customer.class, scanExpression, <br />                                mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> 同期レスポンスには返された `PageIterable.items()` (遅延読み込み) を、非同期レスポンスには `PagePublisher.items.subscribe()` を使用します。  | 
|  複数のテーブルから複数の項目をバッチで読み取ります。 **DynamoDB オペレーション:** `BatchGetItem`  |  <pre>mapper.batchLoad(Arrays.asList(customer1, <br />                               customer2, <br />                               book1))<br />mapper.batchLoad(itemsToGet) <br />           // itemsToGet: Map<Class<?>, List<KeyPair>></pre>  |  <pre>enhancedClient.batchGetItem(batchGetItemRequest)<br /><br />enhancedClient.batchGetItem(r -> r.readBatches(<br />    ReadBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build(),<br />    ReadBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build()))<br /><br />// Iterate over pages with lazy loading or over all items <br />   from the same table.</pre>  | 
|  複数のテーブルに複数の項目をバッチで書き込みます。 **DynamoDB オペレーション:** `BatchWriteItem`  |  <pre>mapper.batchSave(Arrays.asList(customer1, <br />                               customer2, <br />                               book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(batchWriteItemRequest)<br /><br />enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addPutItem(item2)<br />             .build()))</pre>  | 
|  複数のテーブルから複数の項目をバッチで削除します。 **DynamoDB オペレーション:** `BatchWriteItem`  |  <pre>mapper.batchDelete(Arrays.asList(customer1, <br />                                 customer2, <br />                                 book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addDeleteItem(item1key)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  複数の項目をバッチで書き込み/削除します。 **DynamoDB オペレーション:** `BatchWriteItem`  |  <pre>mapper.batchWrite(Arrays.asList(customer1, book1), <br />                  Arrays.asList(customer2)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  トランザクション書き込みを実行します。 **DynamoDB オペレーション:** `TransactWriteItems`  |  <pre>mapper.transactionWrite(transactionWriteRequest)</pre>  |  <pre>enhancedClient.transactWriteItems(transasctWriteItemsRequest)</pre>  | 
|  トランザクション読み取りを実行します。 **DynamoDB オペレーション:** `TransactGetItems`  |  <pre>mapper.transactionLoad(transactionLoadRequest)</pre>  |  <pre>enhancedClient.transactGetItems(transactGetItemsRequest) </pre>  | 
|  クエリの一致する項目の数を取得します。 **DynamoDB オペレーション:** `Select.COUNT` による`Query`  |  <pre>mapper.count(Customer.class, queryExpression)</pre>  |  <pre>// Get the count from query results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.query(QueryEnhancedRequest.builder()<br />        .queryConditional(queryConditional)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.query(QueryEnhancedRequest.builder()<br />                .queryConditional(queryConditional)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  スキャンの一致する項目の数を取得します。 **DynamoDB オペレーション:** `Select.COUNT` による `Scan`  |  <pre>mapper.count(Customer.class, scanExpression)</pre>  |  <pre>// Get the count from scan results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.scan(ScanEnhancedRequest.builder()<br />        .filterExpression(filterExpression)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.scan(ScanEnhancedRequest.builder()<br />                .filterExpression(filterExpression)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  POJO クラスに対応するテーブルを DynamoDB に作成します。 **DynamoDB オペレーション:** `CreateTable`  |  <pre>mapper.generateCreateTableRequest(Customer.class)</pre> 前のステートメントは、低レベルのテーブル作成リクエストを生成します。ユーザーは DynamoDB クライアントで `createTable` を呼び出す必要があります。  |  <pre>table.createTable(createTableRequest)<br /><br />table.createTable(r -> r.provisionedThroughput(defaultThroughput())<br />    .globalSecondaryIndices(<br />        EnhancedGlobalSecondaryIndex.builder()<br />            .indexName("gsi_1")<br />            .projection(p -> p.projectionType(ProjectionType.ALL))<br />            .provisionedThroughput(defaultThroughput())<br />            .build()));</pre>  | 
|  DynamoDB で並列スキャンを実行します。 **DynamoDB オペレーション:** `Segment` と `TotalSegments` パラメータを使用した `Scan`  |  <pre>mapper.parallelScan(Customer.class, <br />                    scanExpression, <br />                    numTotalSegments)</pre>  |  ユーザーはワーカースレッドを処理し、セグメントごとに `scan` を呼び出す必要があります。 <pre>table.scan(r -> r.segment(0).totalSegments(5))</pre>  | 
|  Amazon S3 と DynamoDB を統合してインテリジェントな S3 リンクを保存します。  |  <pre>mapper.createS3Link(bucket, key)<br />mapper.getS3ClientCache()</pre>  |  Amazon S3 と DynamoDB が結合されるため、サポートされていません。  | 

## クラスとプロパティをマッピングする
<a name="dynamodb-mapping-schemas"></a>

V1 と V2 の両方で、Bean 形式の注釈を使用してクラスをテーブルにマッピングします。V2 には、変更不可能なクラスの使用など、特定のユースケースの[スキーマを定義する他の方法](ddb-en-client-adv-features.md#ddb-en-client-adv-features-schm-overview)もあります。

### Bean 注釈
<a name="dynamodb-mapping-schemas-annos"></a>

次の表は、V1 および V2 で使用される、特定のユースケースにおける同等の Bean 注釈を示しています。`Customer` クラスシナリオは、パラメータを説明するために使用されます。

V2 の注釈、クラス、列挙はキャメルケース規則に従い、「DynamoDB」ではなく「DynamoDb」を使用します。


| ユースケース | V1 | V2 | 
| --- | --- | --- | 
| クラスをテーブルにマップする |  <pre>@DynamoDBTable (tableName ="CustomerTable")</pre>  | <pre>@DynamoDbBean<br />@DynamoDbBean(converterProviders = {...})</pre>テーブル名は、DynamoDbEnhancedClient\$1table() メソッドを呼び出すときに定義されます。 | 
| クラスメンバーをテーブル属性として指定する  |  <pre>@DynamoDBAttribute(attributeName = "customerName")</pre>  |  <pre>@DynamoDbAttribute("customerName") </pre>  | 
| クラスメンバーをハッシュ/パーティションキーとして指定する |  <pre>@DynamoDBHashKey </pre>  |  <pre>@DynamoDbPartitionKey</pre>  | 
| クラスメンバーを範囲/ソートキーとして指定する |  <pre>@DynamoDBRangeKey </pre>  |  <pre>@DynamoDbSortKey </pre>  | 
| クラスメンバーをセカンダリインデックスのハッシュ/パーティションキーとして指定する |  <pre>@DynamoDBIndexHashKey </pre>  |  <pre>@DynamoDbSecondaryPartitionKey </pre>  | 
| クラスメンバーをセカンダリインデックスの範囲/ソートキーとして指定する |  <pre>@DynamoDBIndexRangeKey </pre>  |  <pre>@DynamoDbSecondarySortKey </pre>  | 
| テーブルにマッピングするときにこのクラスメンバーを無視する |  <pre>@DynamoDBIgnore </pre>  |  <pre>@DynamoDbIgnore</pre>  | 
| クラスメンバーを自動生成された UUID キー属性として指定する |  <pre>@DynamoDBAutoGeneratedKey</pre>  |  <pre>@DynamoDbAutoGeneratedUuid </pre> これを提供する拡張機能はデフォルトではロードされません。拡張機能をクライアントビルダーに追加する必要があります。  | 
| クラスメンバーを自動生成されたタイムスタンプ属性として指定する |  <pre>@DynamoDBAutoGeneratedTimestamp</pre>  |  <pre>@DynamoDbAutoGeneratedTimestampAttribute</pre> これを提供する拡張機能はデフォルトではロードされません。拡張機能をクライアントビルダーに追加する必要があります。  | 
| クラスメンバーを自動で増分されるバージョン属性として指定する |  <pre>@DynamoDBVersionAttribute</pre>  |  <pre>@DynamoDbVersionAttribute</pre> これを提供する拡張機能は自動的にロードされます。  | 
| クラスメンバーをカスタム変換を必要とするものとして指定する |  <pre>@DynamoDBTypeConverted</pre>  |  <pre>@DynamoDbConvertedBy</pre>  | 
| クラスメンバーを別の属性タイプとして保存するように指定する |  <pre>@DynamoDBTyped(<DynamoDBAttributeType>)</pre>  |  `AttributeConverter` 実装を使用します。V2 には、一般的な Java タイプ用の多くの組み込みコンバーターが用意されています。独自のカスタム `AttributeConverter` または `AttributeConverterProvider` を実装することもできます。本ガイドの「[属性変換を制御する](ddb-en-client-adv-features-conversion.md)」を参照してください。  | 
| DynamoDB ドキュメント (JSON 形式のドキュメント) またはサブドキュメントにシリアル化できるクラスを指定する  |  <pre>@DynamoDBDocument</pre>  | 拡張ドキュメント API を使用します。以下のリソースを参照してください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) | 

### V2 の追加注釈
<a name="dynamodb-mapping-schemas-annos-v2-addnl"></a>


| ユースケース | V1 | V2 | 
| --- | --- | --- | 
| Java 値が null の場合、クラスメンバーを NULL 属性として保存しないように指定する | 該当なし |  <pre>@DynamoDbIgnoreNulls</pre>  | 
| すべての属性が null の場合、クラスメンバーを空のオブジェクトとなるように指定する | 該当なし |  <pre>@DynamoDbPreserveEmptyObject</pre>  | 
| クラスメンバーの特別な更新アクションを指定する | 該当なし |  <pre>@DynamoDbUpdateBehavior</pre>  | 
| 変更不可能なクラスを指定する | 該当なし |  <pre>@DynamoDbImmutable</pre>  | 
| クラスメンバーを自動で増分されるカウンター属性として指定する | 該当なし |  <pre>@DynamoDbAtomicCounter</pre> この機能を提供する拡張機能は自動的にロードされます。  | 

## 設定
<a name="dynamodb-mapping-configuration"></a>

V1 では、通常、`DynamoDBMapperConfig` のインスタンスを使用して特定の動作を制御します。設定オブジェクトは、マッパーの作成時またはリクエスト時に指定できます。V2 では、設定は オペレーションのリクエストオブジェクトに固有です。


| ユースケース | V1 | V1 のデフォルト | V2 | 
| --- | --- | --- | --- | 
|  |  <pre>DynamoDBMapperConfig.builder()</pre>  |  |  | 
| バッチロード/書き込みの再試行戦略 |  <pre>  .withBatchLoadRetryStrategy(loadRetryStrategy)</pre> <pre>  .withBatchWriteRetryStrategy(writeRetryStrategy)</pre>  | 失敗した項目を再試行する | 基盤となる DynamoDBClient で再試行戦略を設定します。本ガイドの「[で再試行動作を設定する AWS SDK for Java 2.x](retry-strategy.md)」を参照してください。 | 
| 整合性のある読み込み |  <pre>  .withConsistentReads(CONSISTENT)</pre>  | EVENTUAL | デフォルトでは、読み取りオペレーションの整合性のある読み取りは false です。リクエストオブジェクトで、.consistentRead(true) で上書きします。 | 
| マーシャラー/アンマーシャラーのセットによる変換スキーマ |  <pre>  .withConversionSchema(conversionSchema)</pre> 静的実装は、古いバージョンとの下位互換性を提供します。  | V2\$1COMPATIBLE | 該当なし。これは、初期の DynamoDB（V1）がデータ型を保存していた方法を指すレガシー機能であり、この動作は拡張クライアントでは保持されません。DynamoDB V1 の動作の一例は、ブール値ではなく数値としてブール値を格納することです。 | 
| テーブル名 |  <pre>  .withObjectTableNameResolver()<br />  .withTableNameOverride() <br />  .withTableNameResolver()</pre> 静的実装は、古いバージョンとの下位互換性を提供します。  | 注釈を使用する、またはクラスから推測する |  テーブル名は、`DynamoDbEnhancedClient#table()` メソッドを呼び出すときに定義されます。  | 
| ページ分割ロード戦略 |  <pre>  .withPaginationLoadingStrategy(strategy)</pre>  オプション: LAZY\$1`LOADING`、`EAGER_LOADING`、または `ITERATION_ONLY`  | LAZY\$1LOADING |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html)  | 
| リクエストメトリクスの収集 |  <pre>  .withRequestMetricCollector(collector)</pre>  | null | 標準 DynamoDB クライアントを構築するときは、metricPublisher() で ClientOverrideConfiguration を使用します。 | 
| 保存動作 |  <pre>  .withSaveBehavior(SaveBehavior.CLOBBER) </pre> オプションは `UPDATE`、`CLOBBER`、`PUT`、`APPEND_SET`、または `UPDATE_SKIP_NULL_ATTRIBUTES` です。  | UPDATE |  V2 では、`putItem()` または `updateItem()` を明示的に呼び出します。 `CLOBBER or PUT`: V2 の対応するアクションが `putItem()` を呼び出します。特定の `CLOBBER` 設定はありません。 `UPDATE`: に対応 `updateItem()` `UPDATE_SKIP_NULL_ATTRIBUTES`: に対応します`updateItem()`。リクエスト設定 `ignoreNulls` と注釈/タグ `DynamoDbUpdateBehavior` を使用して更新動作を制御します。 `APPEND_SET`: サポートされていません  | 
| 型コンバータファクトリ |  <pre>  .withTypeConverterFactory(typeConverterFactory) </pre>  | 標準型コンバータ |  次を使用して Bean に設定する <pre>@DynamoDbBean(converterProviders = {ConverterProvider.class, <br />        DefaultAttributeConverterProvider.class})</pre>  | 

### オペレーションごとの設定
<a name="dynamodb-mapping-configuration-per-op"></a>

V1 では、`query()` などの一部のオペレーションは、オペレーションに送信された「式」オブジェクトを使用して高度に設定できます。例えば、次のようになります。

```
DynamoDBQueryExpression<Customer> emailBwQueryExpr = new DynamoDBQueryExpression<Customer>()
    .withRangeKeyCondition("Email",
        new Condition()
            .withComparisonOperator(ComparisonOperator.BEGINS_WITH)
            .withAttributeValueList(
                new AttributeValue().withS("my")));

mapper.query(Customer.class, emailBwQueryExpr);
```

V2 では、設定オブジェクトを使用する代わりに、ビルダーを使用してリクエストオブジェクトにパラメータを設定します。例えば、次のようになります。

```
QueryEnhancedRequest emailBw = QueryEnhancedRequest.builder()
    .queryConditional(QueryConditional
        .sortBeginsWith(kb -> kb
            .sortValue("my"))).build();

customerTable.query(emailBw);
```

## 条件式
<a name="dynamodb-mapping-conditionals"></a>

V2 では、条件式とフィルタリング式は、条件と名前およびフィルターのマッピングをカプセル化する `Expression` オブジェクトを使用して表現されます。


| ユースケース | オペレーション | V1 | V2 | 
| --- | --- | --- | --- | 
| 予想される属性条件 | save()、delete()、Query()、Scan() |  <pre>new DynamoDBSaveExpression()<br />  .withExpected(Collections.singletonMap(<br />      "otherAttribute", new ExpectedAttributeValue(false)))<br />  .withConditionalOperator(ConditionalOperator.AND);</pre>  | 非推奨。代わりに ConditionExpression を使用してください。 | 
| 条件式 | delete() |  <pre>deleteExpression.setConditionExpression("zipcode = :zipcode")<br />deleteExpression.setExpressionAttributeValues(...)<br /></pre>  |  <pre>Expression conditionExpression =<br />    Expression.builder()<br />        .expression("#key = :value OR #key1 = :value1")<br />        .putExpressionName("#key", "attribute")<br />        .putExpressionName("#key1", "attribute3")<br />        .putExpressionValue(":value", AttributeValues.stringValue("wrong"))<br />        .putExpressionValue(":value1", AttributeValues.stringValue("three"))<br />        .build();<br /><br />DeleteItemEnhancedRequest request = DeleteItemEnhancedRequest.builder()<br />         .conditionExpression(conditionExpression).build();</pre>  | 
| フィルター式 | query()、scan() |  <pre>scanExpression<br />  .withFilterExpression("#statename = :state")<br />  .withExpressionAttributeValues(attributeValueMapBuilder.build())<br />  .withExpressionAttributeNames(attributeNameMapBuilder.build())<br /></pre>  |  <pre>Map<String, AttributeValue> values = singletonMap(":key", stringValue("value"));<br />Expression filterExpression =<br />    Expression.builder()<br />        .expression("name = :key")<br />        .expressionValues(values)<br />        .build();<br />QueryEnhancedRequest request = QueryEnhancedRequest.builder()<br />    .filterExpression(filterExpression).build();<br /></pre>  | 
| クエリの条件式 | query() |  <pre>queryExpression.withKeyConditionExpression()</pre>  |  <pre>QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b<br />                .partitionValue("movie01"));<br /><br />QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()<br />                .queryConditional(keyEqual)<br />                .build();</pre>  | 

## 型変換
<a name="dynamodb-mapping-type-conv"></a>

### デフォルトコンバータ
<a name="dynamodb-mapping-type-conv-defaults"></a>

V2 では、SDK はすべての一般的なタイプに向けてデフォルトコンバータのセットを提供します。タイプコンバータは、全体的なプロバイダーレベルと、単一の属性に対しての両方で変更できます。使用可能なコンバータのリストは、[AttributeConverter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) API リファレンスで確認できます。

### 属性のカスタムコンバータを設定する
<a name="dynamodb-mapping-type-conv-anno"></a>

V1 では、`@DynamoDBTypeConverted` を使用してゲッターメソッドに注釈を付けて、Java 属性型と DynamoDB 属性型を変換するクラスを指定できます。たとえば、Java `Currency` 型と DynamoDB 文字列を変換する `CurrencyFormatConverter` は、次のスニペットに示すように適用できます。

```
@DynamoDBTypeConverted(converter = CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

での前のスニペットに相当する V2 でのスニペットを以下に示します。

```
@DynamoDbConvertedBy(CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

**注記**  
V1 では、属性自体、タイプ、またはユーザー定義の注釈に注釈を適用できます。V2 では、ゲッターにのみ注釈を適用できます。

### タイプコンバータファクトリまたはプロバイダーを追加する
<a name="dynamodb-mapping-type-conv-factory"></a>

V1 では、独自のタイプコンバータのセットを提供するか、設定にタイプコンバータファクトリを追加することで、任意のタイプを上書きできます。タイプコンバータファクトリは `DynamoDBTypeConverterFactory` を拡張し、デフォルトセットへの参照を取得してそれを拡張することによって上書きが行われます。以下のスニペットは、その方法を示しています。

```
DynamoDBTypeConverterFactory typeConverterFactory =
    DynamoDBTypeConverterFactory.standard().override()
        .with(String.class, CustomBoolean.class, new DynamoDBTypeConverter<String, CustomBoolean>() {
            @Override
            public String convert(CustomBoolean bool) {
                return String.valueOf(bool.getValue());
            }
            @Override
            public CustomBoolean unconvert(String string) {
                return new CustomBoolean(Boolean.valueOf(string));
            }}).build();
DynamoDBMapperConfig config =
    DynamoDBMapperConfig.builder()
        .withTypeConverterFactory(typeConverterFactory)
        .build();
DynamoDBMapper mapperWithTypeConverterFactory = new DynamoDBMapper(dynamo, config);
```

V2 は、`@DynamoDbBean` 注釈を通じて同様の機能を提供します。単一の `AttributeConverterProvider` または順序付けられた `AttributeConverterProvider` のチェーンを提供することができます。独自の属性コンバータープロバイダーチェーンを指定すると、デフォルトのコンバータープロバイダーが上書きされ、その属性コンバータを使用するにはチェーンに含める必要があることに注意してください。

```
@DynamoDbBean(converterProviders = {
   ConverterProvider1.class, 
   ConverterProvider2.class,
   DefaultAttributeConverterProvider.class})
public class Customer {
  ...
}
```

本ガイドの[属性変換](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example)に関するセクションには、V2 の完全な例が含まれています。

# SDK for Java のバージョン 1 とバージョン 2 の文字列処理の違い
<a name="dynamodb-migration-string-handling"></a>

V1 と V2 では、DynamoDB にデータを送信するときの空の文字列の処理方法が異なります。
+ **V1**: DynamoDB に送信する前に空の文字列を null 値に変換します (属性なしになります)。
+ **V2**: 空の文字列を実際の空の文字列値として DynamoDB に送信します。

**重要**  
V2 に移行した後、空の文字列を DynamoDB に保存したくない場合は、カスタムコンバータを実装する必要があります。カスタムコンバータがない場合、V2 は空の文字列を実際の空の文字列属性として DynamoDB 項目に保存します。これは、これらの属性を完全に省略する V1 の動作とは異なります。

**Example 空の文字列属性を null に変換する V2 のカスタムコンバータ**  

```
/**
 * Custom converter that maintains V1 behavior by converting empty strings to null values
 * when writing to DynamoDB, ensuring compatibility with existing data. No attribute will be saved to DynamoDB.
 */
public class NullifyEmptyStringConverter implements AttributeConverter<String> {
    @Override
    public AttributeValue transformFrom(String value) {
        if (value == null || value.isEmpty()) {
            return AttributeValue.builder().nul(true).build();
        }
        return AttributeValue.builder().s(value).build();
    }

    @Override
    public String transformTo(AttributeValue attributeValue) {
        if (attributeValue.nul()) {
            return null;
        }
        return attributeValue.s();
    }

    @Override
    public EnhancedType<String> type() {
        return EnhancedType.of(String.class);
    }

    @Override
    public AttributeValueType attributeValueType() {
        return AttributeValueType.S;
    }
}

// V2 usage:
@DynamoDbBean
public class Customer {
    private String name;

    @DynamoDbConvertedBy(NullifyEmptyStringConverter.class)
    public String getName() {
        return name;
    }
}
```



# SDK for Java のバージョン 1 とバージョン 2 の楽観的ロックの違い
<a name="dynamodb-migrate-optimstic-locking"></a>

V1 と V2 の両方で、Bean クラス内の 1 つのプロパティにバージョン番号を保存するための属性アノテーションを付与することで、楽観的ロックが実装されています。


**楽観的ロック動作の違い**  

|  | V1 | V2 | 
| --- | --- | --- | 
| Bean クラスの注釈 | @DynamoDBVersionAttribute | @DynamoDbVersionAttribute (V2 は小文字の「b」を使用することに注意してください) | 
| 初期保存 | 1 に設定されたバージョン番号属性。 |  `@DynamoDbVersionAttribute(startAt = X)` で設定されたバージョン属性の開始値。デフォルト値は 0 です。  | 
| 更新 | 更新されるオブジェクトのバージョン番号がデータベース内の番号と一致することが条件チェックで検証されると、バージョン番号属性が 1 ずつ増加します。 |  更新されるオブジェクトのバージョン番号がデータベース内の番号と一致することが条件チェックで検証されると、バージョン番号属性が増加します。 `@DynamoDbVersionAttribute(incrementBy = X)` で設定された `incrementBy` オプションによって増加するバージョン番号属性。デフォルト値は 1 です。  | 
| Delete | DynamoDBMapper は、削除されるオブジェクトのバージョン番号がデータベースのバージョン番号と一致するという条件付きチェックを追加します。 |  V2 は、削除オペレーションの条件を自動的に追加しません。削除動作を制御する場合は、条件式を手動で追加する必要があります。 次の例では、`recordVersion` は Bean のバージョン属性です。 <pre>// 1. Read the item and get its current version.<br />Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build());<br />AttributeValue currentVersion = item.getRecordVersion();<br /><br />// 2. Create conditional delete with the `currentVersion` value.<br />DeleteItemEnhancedRequest deleteItemRequest =<br />    DeleteItemEnhancedRequest.builder()<br />       .key(KEY)<br />       .conditionExpression(Expression.builder()<br />           .expression("recordVersion = :current_version_value")<br />           .putExpressionValue(":current_version_value", currentVersion)<br />           .build()).build();<br /><br />customerTable.deleteItem(deleteItemRequest);</pre>  | 
| 条件チェックによるトランザクション書き込み | addConditionCheck メソッドで @DynamoDBVersionAttribute によって注釈が付けられた Bean クラスを使用することはできません。 | transactWriteItems リクエストの addConditionCheck ビルダーメソッドでは @DynamoDbVersionAttribute 注釈が付いた Bean クラスを使用できます。 | 
| 無効化 | 楽観的ロックを無効にするには、 DynamoDBMapperConfig.SaveBehavior 列挙値を UPDATE から CLOBBER に変更します。 |  `@DynamoDbVersionAttribute` 注釈を使用しないでください。  | 

# SDK for Java のバージョン 1 とバージョン 2 の Fluent セッターの違い
<a name="dynamodb-migrate-fluent-setters"></a>

V1 の DynamoDB マッピング API では Fluent セッターを持つ POJO を使用でき、V2 でもバージョン 2.30.29 以降で使用できます。

たとえば、次の POJO は `setName` メソッドから `Customer` インスタンスを返します。

```
// V1

@DynamoDBTable(tableName ="Customer")
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){
     this.name = name;
     return this;
  }
}
```

ただし、2.30.29 より前のバージョンの V2 を使用する場合、`setName` は `null` の `name` 値を持つ `Customer` インスタンスを返します。

```
// V2 prior to version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Bug: returns this instance with a `name` value of `null`.
  }
}
```

```
// Available in V2 since version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Returns this instance for method chaining with the `name` value set.
  }
}
```