

# DynamoDB の上位レベルのプログラミングインターフェイス
<a name="HigherLevelInterfaces"></a>

AWS SDK は、Amazon DynamoDB を操作するための下位レベルのインターフェイスをアプリケーションに提供します。これらのクライアント側のクラスとメソッドは、下位レベルの DynamoDB API と直接対応しています。しかし、これは多くのデベロッパーにとって、複雑なデータ型をデータベーステーブル内の項目にマップする必要がある場合の接続性の悪さ、つまり*インピーダンスの不整合*の原因となります。下位レベルのデータベースインタフェースを使用するデベロッパーは、オブジェクトデータをデータベーステーブルに対して読み書きするためのメソッドを記述する必要があります。オブジェクトタイプとデータベーステーブルの組み合わせに、個別に対応するための余分なコードが、圧倒的な量になることもあります。

AWS SDK for Java および for .NET では、開発業務を簡素化するために、高度に抽象化されたインターフェイスが用意されています。DynamoDB の上位レベルのインターフェイスを使用すると、プログラム内のオブジェクトと、それらのオブジェクトのデータを格納するためのデータベーステーブル間の関係を定義できます。このマッピングを定義した後、`save`、`load`、`delete` などの単純なオブジェクトメソッドを呼び出すと、ユーザーに代わって、基盤となる下位レベルの DynamoDB オペレーションの呼び出しが自動化されます。これにより、データベースを意識するのではなく、オブジェクトを中心にコードを作成していくことができます。

DynamoDB の上位レベルのプログラミングインターフェイスは、Java および .NET 用の AWS SDK で使用できます。

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

**注記**  
SDK for Java には、1.x と 2.x の 2 つのバージョンがあります。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 を使用することを強くお勧めします。

AWS SDK for Java には `DynamoDBMapper` クラスが用意されているため、クライアント側のクラスを Amazon DynamoDB テーブルにマッピングできます。`DynamoDBMapper` を使用するには、DynamoDB テーブル内の項目と、それが対応するコード内のオブジェクトインスタンスの間での関係性を定義します。`DynamoDBMapper` クラスを使用すると、項目に対する作成、読み込み、更新、削除 (CRUD) の各オペレーションの実行、およびテーブルに対するクエリやスキャンを行うことができます。

**Topics**
+ [DynamoDBMapper クラス](DynamoDBMapper.Methods.md)
+ [DynamoDBMapper for Java でサポートされるデータ型](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`クラスでは、テーブルを作成、更新、または削除することはできません。これらのタスクを実行するには、代わりに SDK for Java の下位レベルインターフェイスを使用します。

SDK for Java には、クラスをテーブルにマッピングするための、一連のアノテーションタイプが用意されています。たとえば、パーティションキーとして `ProductCatalog` を含む `Id` テーブルがあるとします。

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

次の Java コードに示すように、クライアントアプリケーション内のクラスを `ProductCatalog` テーブルにマッピングすることができます。このコードでは、`CatalogItem` という名前の Plain Old Java Object (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 クラス
<a name="DynamoDBMapper.Methods"></a>



`DynamoDBMapper` クラスは、Amazon DynamoDB のエントリポイントとなります。このクラスは、DynamoDB エンドポイントへのアクセスを提供し、さまざまなテーブルのデータを使用できるようにします。また、アイテムに対する作成、読み込み、更新、削除 (CRUD) の各オペレーションの実行、およびテーブルに対するクエリやスキャンを行うことができます。このクラスでは、DynamoDB を操作するために以下のメソッドが提供されます。

対応する Javadoc ドキュメントについては、*AWS SDK for Java 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)
+ [削除](#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)
+ [バッチ書き込み](#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` オブジェクトを使用して、オプションの設定パラメータを入力できます。

同じプライマリキーを持つ項目が存在しない場合は、このメソッドによってテーブル内に新しい項目が作成されます。同じプライマリキーを持つ項目が存在する場合は、その既存の項目が更新されます。パーティションキーとソートキーが String 型で、`@DynamoDBAutoGeneratedKey` によって注釈が付けられている場合、初期化しなければ、ランダムな UUID (Universally Unique Identifier) が与えられます。`@DynamoDBVersionAttribute` で注釈が付けられたバージョンフィールドは、バージョンが 1 ずつ増えていきます。さらに、バージョンフィールドが更新されるかキーが生成されると、オペレーションの結果として、渡されたオブジェクトが更新されます。

デフォルトでは、マップされたクラスプロパティに対応する属性のみが更新されます。アイテムのその他の既存の属性には影響はありません。ただし、`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)」を参照してください。

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

テーブルから項目を削除します。マッピングされたクラスのオブジェクトインスタンスを渡す必要があります。

バージョニングを有効にした場合は、クライアント側とサーバー側で項目のバージョンが一致する必要があります。ただし、`SaveBehavior.CLOBBER` オプションを使用する場合は、バージョンを一致させる必要はありません。バージョニングの詳細については、「[DynamoDB およびバージョン番号を使用した楽観的ロック](DynamoDBMapper.OptimisticLocking.md)」を参照してください。

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

テーブルまたはセカンダリインデックスをクエリする

フォーラムスレッドの返信を格納する `Reply` というテーブルがあるとします。各スレッドの件名については、0 以上の返信を受け取ることができます。`Reply` テーブルのプライマリキーは、`Id` および `ReplyDateTime` フィールドで構成されます。ここで、`Id` はプライマリキーのパーティションキー、`ReplyDateTime` はソートキーを表します。

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

`Reply` クラスと、それに対応する DynamoDB 内の `Reply` テーブルの間で、マッピングを作成したとします。次の Java コードでは、`DynamoDBMapper` を使用して特定のスレッド件名に対する過去 2 週間のすべての返信を検索しています。

**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` メソッドによって、「遅延ロード」されたコレクションが返されます。最初に結果が 1 ページのみ返され、必要に応じて、さらに次ページを要求するサービス呼び出しが行われます。一致するすべての項目を取得するには、`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>

テーブルまたはセカンダリインデックスのクエリを実行し、一致した結果を 1 ページ返します。`query` メソッドと同様、パーティションキー値とソートキー属性に適用されるクエリフィルタを指定する必要があります。ただし `queryPage` では、データの最初の "ページ"、つまり 1 MB 以内に収まるデータ量のみが返されます。

## スキャン
<a name="DynamoDBMapper.Methods.scan"></a>

テーブル全体またはセカンダリインデックスをスキャンします。オプションで `FilterExpression` を指定して結果セットをフィルタリングできます。

フォーラムスレッドの返信を格納する `Reply` というテーブルがあるとします。各スレッドの件名については、0 以上の返信を受け取ることができます。`Reply` テーブルのプライマリキーは、`Id` および `ReplyDateTime` フィールドで構成されます。ここで、`Id` はプライマリキーのパーティションキー、`ReplyDateTime` はソートキーを表します。

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

`Reply` テーブルに Java クラスをマッピングした場合は、`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` メソッドによって、「遅延ロード」されたコレクションが返されます。最初に結果が 1 ページのみ返され、必要に応じて、さらに次ページを要求するサービス呼び出しが行われます。一致するすべての項目を取得するには、`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>

テーブルまたはセカンダリインデックスがスキャンされ、一致する結果が 1 ページ返されます。`scan` メソッドと同様に、オプションで `FilterExpression` を指定して結果セットをフィルタリングできます。ただし、`scanPage` では、データの最初の "ページ"、つまり、1 MB 以内に収まるデータ量のみが返されます。

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

テーブル全体、またはセカンダリインデックスの並列スキャンが実行されます。テーブルの論理セグメントの数と、結果をフィルタするスキャン式を指定します。`parallelScan` では、スキャンタスクが複数のワーカーに分割され、論理セグメントごとに 1 つのワーカーが割り当てられます。ワーカーは、データを並列に処理し、結果を返します。

次の 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` メソッドに対する 1 つ以上の呼び出しを使用して、1 つ以上のテーブルにオブジェクトを保存します。このメソッドでは、トランザクション保証はなされません。

次の Java コードでは、2 つの項目 (書籍) を `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>

テーブルのプライマリキーを使用して、1 つ以上のテーブルから複数の項目を取り出します。

次の Java コードでは、2 つの異なるテーブルから 2 つの項目を取得します。

```
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` メソッドに対する 1 つ以上の呼び出しを使用して、1 つ以上のテーブルからオブジェクトを削除します。このメソッドでは、トランザクション保証はなされません。

次の Java コードでは、2 つの項目 (書籍) を `ProductCatalog` テーブルから削除します。

```
Book book1 = mapper.load(Book.class, 901);
Book book2 = mapper.load(Book.class, 902);
mapper.batchDelete(Arrays.asList(book1, book2));
```

## バッチ書き込み
<a name="DynamoDBMapper.Methods.batchWrite"></a>

`AmazonDynamoDB.batchWriteItem` メソッドに対する 1 つ以上の呼び出しを使用して、1 つ以上のテーブルに対してオブジェクトの保存および削除を行います。このメソッドではトランザクション保証はなされず、バージョニング（条件付き入力または削除）もサポートされません。

次の 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` メソッドに対する 1 回の呼び出しを使用して、1 つまたは複数のテーブルに対してオブジェクトの保存および削除を行います。

トランザクション固有の例外のリストについては、「[TransactWriteItems エラー](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors)」を参照してください。

DynamoDB トランザクション、および提供されるアトミック性、整合性、分離、耐久性 (ACID) の保証の詳細については、「[DynamoDB トランザクションで複雑なワークフローを管理する](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` メソッドへの 1 回の呼び出しを使用して、1 つまたは複数のテーブルからオブジェクトをロードします。

トランザクション固有の例外のリストについては、「[TransactGetItems エラー](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors)」を参照してください。

DynamoDB トランザクション、および提供されるアトミック性、整合性、分離、耐久性 (ACID) の保証の詳細については、「[DynamoDB トランザクションで複雑なワークフローを管理する](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 メソッドを `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>

Amazon S3 にアクセスする際の基盤となる `S3ClientCache` を返します。`S3ClientCache` は、`AmazonS3Client` オブジェクトのスマートマップです。複数のクライアントがある場合、`S3ClientCache` によって、AWS リージョン別にクライアントを整理しやすくなり、新しい Amazon S3 クライアントをオンデマンドで作成できるようになります。

# DynamoDBMapper for Java でサポートされるデータ型
<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 でサポートされます。  
AWS SDK for Java 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`（数値型）  | 
|  文字列  |  `S` (文字列型)   | 
|  Boolean  |  `BOOL` (ブール型)、0 または 1。  | 
|  ByteBuffer  |  `B`（バイナリ型）  | 
|  日付  |  `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 ドキュメントについては、[AWS SDK for Java 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>

テーブルの属性にプロパティをマッピングします。デフォルトでは、各クラスのプロパティが、同じ名前の項目属性にマッピングされます。ただし名前が同じでない場合は、この注釈を使用して属性にプロパティをマッピングすることができます。次の 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) が生成されます。String プロパティには、自動生成済みのキーとしてマーキングできます。

次の例は、自動生成されたパラメータを使用する方法を示しています。

```
@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 属性にマッピングしたい場合を考えます。次のサンプルコードでは、マップ型の入れ子の属性 (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` クラスを定義し、その `Id` プロパティを `ProductCatalog` タグを使用して `@DynamoDBHashKey` テーブルのプライマリキーにマッピングしています。

```
@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` クラスから継承したクラスを作成した場合には、次の Java サンプルコードに示すように、`@DynamoDBTable` 注釈を追加することで、別のテーブルに明示的にマッピングできます。

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

詳細については、[AWS SDK for Java 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` – リストからの読み込みに Iterator のみを使用することができます。反復中、リストは、前のすべての結果をクリアしてから、次のページをロードすることで、最大 1 ページのロードされた結果をメモリに維持するようにします。つまり、リストを反復できるのは 1 回だけです。メモリのオーバーヘッドを低減するために、大きい項目を処理するときにこの方法を使用することをお勧めします。

  マッパーインスタンスにページ分割ロードの方法を指定しない場合、デフォルトは `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 の項目を確実に同じになるようにするための手段です。この方法を使用すると、データベースの書き込みは、他のユーザーの書き込みによって上書きされないように保護されます。逆の場合も同様に保護されます。

オプティミスティックロックを使用する場合、各項目には、バージョン番号として機能する属性があります。項目をテーブルから取り出すと、アプリケーションは、その項目のバージョン番号を記録します。サーバー側のバージョン番号が変更されていない場合のみ、項目を更新できます。バージョンの不一致がある場合は、前に他のユーザーによってそのアイテムが変更されたことを意味します。アイテムの古いバージョンがあるため、更新の試行は失敗します。その場合は更新をやり直します。もう一度項目を取得して、更新してください。オプティミスティックロックでは、他のユーザーが行った変更を誤って上書きできないようにします。また、お客様が行った変更を他のユーザーが誤って変更することを防ぐこともできます。

独自の楽観的ロック戦略を実装することもできますが、AWS SDK for Java には `@DynamoDBVersionAttribute` アノテーションが用意されています。テーブルのマッピングクラスで、バージョン番号を保存する 1 つのプロパティを指定し、この注釈を使用してそのプロパティをマーキングします。オブジェクトを保存すると、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` 注釈は、`Long` や `Integer` などの、null が許容された型を提供するプリミティブラッパークラスによって得られた、null が許容された型に適用できます。

オプティミスティックロックは、次の `DynamoDBMapper` メソッドに対して次のような影響があります。
+ `save` – `DynamoDBMapper` は、新しい項目に対して初期バージョン番号 1 を割り当てます。項目を取得し、その項目の 1 つ以上のプロパティを更新して変更を保存する場合には、クライアント側とサーバー側のバージョン番号が一致する場合のみ、保存が成功します。`DynamoDBMapper` によってバージョン番号が自動的にインクリメントされます。
+ `delete` – `delete` メソッドは 1 つのオブジェクトをパラメータとして指定し、項目を削除する前に `DynamoDBMapper` によるバージョンチェックが実行されます。バージョンチェックは、リクエスト内で `DynamoDBMapperConfig.SaveBehavior.CLOBBER` を指定して無効にすることができます。

  `DynamoDBMapper` 内のオプティミスティックロックの内部実装では、DynamoDB の条件付き更新と条件付き削除機能が使用されます。
+ `transactionWrite` —
  + `Put` – `DynamoDBMapper` は、新しい項目に対して初期バージョン番号 1 を割り当てます。項目を取得し、その項目の 1 つ以上のプロパティを更新して変更を保存する場合には、クライアント側とサーバー側のバージョン番号が一致する場合のみ、put オペレーションが成功します。`DynamoDBMapper` によってバージョン番号が自動的にインクリメントされます。
  + `Update` – `DynamoDBMapper` は、新しい項目に対して初期バージョン番号 1 を割り当てます。項目を取得し、その項目の 1 つ以上のプロパティを更新して変更を保存する場合には、クライアント側とサーバー側のバージョン番号が一致する場合のみ、更新オペレーションが成功します。`DynamoDBMapper` によってバージョン番号が自動的にインクリメントされます。
  + `Delete` – `DynamoDBMapper` は、項目を削除する前にバージョンチェックを実行します。削除オペレーションは、クライアント側とサーバー側のバージョン番号が一致する場合にのみ成功します。
  + `ConditionCheck` – `@DynamoDBVersionAttribute` アノテーションは、`ConditionCheck` オペレーションではサポートされていません。`ConditionCheck` 項目に `@DynamoDBVersionAttribute` の注釈が付いている場合、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 型 (「[DynamoDBMapper for Java でサポートされるデータ型](DynamoDBMapper.DataTypes.md)」を参照) に加えて、Amazon DynamoDB 型に直接マッピングされない、アプリケーション内の型を使用できます。これらの型をマッピングするには、複合型を DynamoDB 対応の型に (またその反対に) 変換する処理を実装し、`@DynamoDBTypeConverted` アノテーションを使用して複合型のアクセサーメソッドに注釈付けを行う必要があります。コンバーターコードは、オブジェクトが保存またはロードされるときにデータを変換します。これは、複合型を消費するすべてのオペレーションでも使用されます。クエリおよびスキャンオペレーションの中でデータを比較する場合、その比較は DynamoDB に格納されているデータに対して行われることにご注意ください。

たとえば、プロパティ `CatalogItem`（`Dimension` 型）を定義する、次の `DimensionType` クラスがあるとします。このプロパティには、項目の寸法として高さ、幅、厚さが格納されています。これらの項目のディメンションを DynamoDB の中に文字列 (8.5x11x.05 など) として格納しようとしている場合を考えます。次の例は、`DimensionType` オブジェクトを文字列に変換し、文字列を `DimensionType` に変換するコンバーターコードを示しています。



**注記**  
このコード例では、アカウントの DynamoDB に対し、[DynamoDB でのコード例用のテーブルの作成とデータのロード](SampleData.md) セクションの手順に従ってデータが既にロードされていることを前提としています。  
以下の例を実行するための詳しい手順については、「[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>

AWS SDK for Java には `DynamoDBMapper` クラスが用意されているため、クライアント側のクラスを DynamoDB テーブルにマッピングできます。`DynamoDBMapper` を使用するには、DynamoDB テーブル内の項目と、それが対応するコード内のオブジェクトインスタンスの間での関係性を定義します。`DynamoDBMapper` クラスを使用すると、項目に対する作成、読み込み、更新、削除 (CRUD) の各オペレーションの実行、およびテーブルに対するクエリやスキャンを行うことができます。

`DynamoDBMapper` の使用方法の詳細については、「AWS SDK for Java 1.x デベロッパーガイド」の「[AWS SDK for Java を使用する DynamoDB の例](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html)」を参照してください。**

# Java 2.x: DynamoDB 拡張クライアント
<a name="DynamoDBEnhanced"></a>

DynamoDB 拡張クライアントは、AWS SDK for Java バージョン 2 (v2) の一部である高レベルのライブラリです。クライアント側のクラスを DynamoDB テーブルにマッピングする簡単な方法を提供します。テーブルおよび対応するモデルクラスの間の関係をコードで定義します。関係を定義したら、DynamoDB のテーブルまたは項目に対して、さまざまな作成、読み取り、更新、または削除 (CRUD) オペレーションを直感的に実行できます。

DynamoDB で拡張クライアントを使用する方法の詳細については、「[AWS SDK for Java 2.x での DynamoDB 拡張クライアントの使用](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)」を参照してください。

# DynamoDB での .NET ドキュメントの操作
<a name="DotNetSDKMidLevel"></a>

AWS SDK for .NET では、低レベル 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`（バイナリ型）   | 
| ブール | N (数値型)。0 は false、1 は true を表します。 | 
| DateTime | S (文字列型)。DateTime の値は、ISO-8601 形式の文字列として格納されます。 | 
| Guid | S (文字列型)。 | 
| コレクション型 (リスト、ハッシュセット、配列) | BS（バイナリセット）型、SS（文字列セット）型、NS（数値セット）型 | 

AWS SDK for .NET は、DynamoDB のブール型、null 型、リスト型、およびマップ型を .NET ドキュメントモデル API にマッピングするための型を定義します。
+ ブール型には `DynamoDBBool` 使用します。
+ null 型には `DynamoDBNull` を使用します。
+ リスト型には `DynamoDBList` を使用します。
+ マップ型には `Document` を使用します。

**注記**  
空のバイナリ値がサポートされています。
空の文字列値の読み取りがサポートされています。空の文字列属性値は、DynamoDB への書き込み中に、文字列セット型の属性値内でサポートされます。文字列型の空の文字列属性値と、リスト型またはマップ型に含まれる空の文字列値が書き込みリクエストから削除されます。

# .NET オブジェクト永続性モデルと DynamoDB の使用
<a name="DotNetSDKHighLevel"></a>

AWS SDK for .NET には、クライアント側クラスを Amazon DynamoDB テーブルにマッピングできるオブジェクト永続性モデルを有効にしています。各オブジェクトインスタンスが、対応するテーブルの項目にマッピングされます。クライアント側オブジェクトをテーブルに保存するために、オブジェクト永続性モデルでは、DynamoDB のエントリポイントとして `DynamoDBContext` クラスを使用できます。このクラスでは、DynamoDB に接続してテーブルにアクセスし、各種の CRUD オペレーションやクエリを実行することができます。

オブジェクト永続性モデルには、クライアント側クラスをテーブルにマッピングし、プロパティ/フィールドを属性にマッピングする、属性のセットが用意されています。

**注記**  
オブジェクト永続性モデルには、テーブルを作成、更新、または削除するための API はありません。データオペレーションだけが可能になっています。テーブルの作成、更新、削除が可能なのは AWS SDK for .NET の低レベル API だけです。

次の例は、オブジェクト永続性モデルの動作を示しています。`ProductCatalog` テーブルから開始します。ここでは `Id` がプライマリキーになっています。

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

`Book`、`Title`、`ISBN` プロパティを持つ `Authors` クラスがあるとします。次の C\$1 サンプルコードに示すように、オブジェクト永続性モデルで定義された属性を追加することで、`Book` クラスを `ProductCatalog` テーブルにマッピングできます。

**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` プロパティが `Authors` テーブル内の `ProductCatalog` 属性にマッピングされています。
+ **デフォルトのマッピング** – デフォルトでは、オブジェクト永続性モデルによって、クラスプロパティがテーブル内の同じ名前の属性にマッピングされます。

  前述の例では、`Title` および `ISBN` プロパティが、`ProductCatalog` テーブル内の同じ名前の属性にマッピングされています。

すべてのクラスプロパティをマッピングする必要はありません。これらのプロパティを特定するには、`DynamoDBIgnore` 属性を追加します。`Book` インスタンスをテーブルに保存する場合、`DynamoDBContext` には `CoverPage` プロパティは含まれません。このプロパティは、書籍インスタンスを取り出す場合にも返されません。

int や string など、.NET プリミティブ型のプロパティをマッピングできます。また、任意データをいずれかの DynamoDB 型にマッピングする適切なコンバーターがある限り、任意のデータ型をマッピングすることもできます。任意の型のマッピングについては、「[AWS SDK for .NET のオブジェクト永続性モデルを使用した、DynamoDB での任意データのマッピング](DynamoDBContext.ArbitraryDataMapping.md)」を参照してください。

オブジェクト永続性モデルでは、オプティミスティックロックがサポートされています。それによって、更新オペレーションで、更新する項目の最新のコピーを確実に使用することができます。詳細については、「[DynamoDB と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック](DynamoDBContext.VersionSupport.md)」を参照してください。

詳細については、以下のトピックを参照してください。

**Topics**
+ [サポートされているデータ型](#DotNetDynamoDBContext.SupportedTypes)
+ [.NET オブジェクト永続性モデルからの DynamoDB 属性](DeclarativeTagsList.md)
+ [.NET オブジェクト永続性モデルからの DynamoDBContext クラス](DotNetDynamoDBContext.md)
+ [DynamoDB と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック](DynamoDBContext.VersionSupport.md)
+ [AWS SDK for .NET のオブジェクト永続性モデルを使用した、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` は具体的なコレクション型、およびシンプルな Plain Old CLR Objects (POCOs) を変換できます。

次の表に、前述の .NET 型が DynamoDB の型にどのようにマッピングされるかを示します。


****  

| .NET プリミティブ型 | DynamoDB 型 | 
| --- | --- | 
|  すべての数値型  |  `N`（数値型）  | 
|  すべての文字列型  |  `S` (文字列型)   | 
|  MemoryStream、byte[]  |  `B`（バイナリ型）   | 
| ブール | N (数値型)。0 は false、1 は true を表します。 | 
| コレクション型 | BS（バイナリセット）型、SS（文字列セット）型、NS（数値セット）型 | 
| DateTime | S (文字列型)。DateTime の値は、ISO-8601 形式の文字列として格納されます。 | 

オブジェクト永続性モデルでは、任意のデータ型もサポートされています。ただし、複合型を DynamoDB 型にマッピングする場合には、変換用のコードを用意する必要があります。

**注記**  
空のバイナリ値がサポートされています。
空の文字列値の読み取りがサポートされています。空の文字列属性値は、DynamoDB への書き込み中に、文字列セット型の属性値内でサポートされます。文字列型の空の文字列属性値と、リスト型またはマップ型に含まれる空の文字列値が書き込みリクエストから削除されます。

# .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` テーブルにマッピングします。クラス定義では、プロパティのうち 2 つがプライマリキーにマッピングされることも示しています。

```
[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` 属性は継承できます。前述の例では、`Lead` クラスから継承された新しいクラス `Developer` を追加すると、`People` テーブルにもマッピングされます。`Developer` テーブルに `Lead` と `People` の両方のオブジェクトが格納されます。
+ `DynamoDBTable` 属性もオーバーライドできます。次の C\$1 サンプルコードでは、`Manager` クラスは、`Developer` クラスから継承されます。ただし、`DynamoDBTable` 属性を明示的に追加すると、クラスは別のテーブル (`Managers`) にマップされます。

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

 次の C\$1 の例に示すように、オプションのパラメータ `LowerCamelCaseProperties` を追加すると、オブジェクトをテーブルに格納する際にプロパティ名の先頭文字を小文字にするよう、DynamoDB にリクエストを送ることができます。

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

`Developer` クラスのインスタンスを保存する場合、`DynamoDBContext` では `DeveloperName` プロパティが `developerName` として保存されます。

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

項目のバージョン番号を格納するクラスプロパティを識別します。バージョニングの詳細については、「[DynamoDB と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック](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)
+ [Delete](#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)
+ [保存](#w2aac17b9c21c23c39c35)
+ [Scan](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [DynamoDBContext でのオプションパラメータの指定](#OptionalConfigParams)

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

複数の個々の `MultiTableBatchGet` オブジェクトで構成される `BatchGet` オブジェクトを作成します。これらの各 `BatchGet` オブジェクトは、単一の DynamoDB テーブルから項目を取り出す場合に使用します。

1 つ以上のテーブルから項目を取得するには、`ExecuteBatchGet` メソッドを使用し、`MultiTableBatchGet` オブジェクトをパラメータとして渡します。

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

複数の個々の `MultiTableBatchWrite` オブジェクトで構成される `BatchWrite` オブジェクトを作成します。これらの各 `BatchWrite` オブジェクトは、単一の DynamoDB テーブルに項目を書き込んだり、それを削除したりするために使用します。

テーブルに書き込むには、`ExecuteBatchWrite` メソッドを使用し、`MultiTableBatchWrite` オブジェクトをパラメータとして渡します。

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

テーブルから複数の項目を取り出すために使用できる `BatchGet` オブジェクトを作成します。

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

テーブルに複数の項目を入力する、またはテーブルから複数の項目を削除するために使用できる `BatchWrite` オブジェクトを作成します。

## Delete
<a name="w2aac17b9c21c23c39c15"></a>

テーブルから項目を削除します。このメソッドでは、削除する項目のプライマリキーが必要になります。プライマリキーの値、またはこのメソッドのパラメータとしてプライマリキーの値を使用するクライアント側オブジェクトを入力できます。
+ クライアント側オブジェクトをパラメータとして指定し、オプティミスティックロックを有効にすると、クライアント側とサーバー側のオブジェクトのバージョンが一致する場合のみ、削除が成功します。
+ プライマリキーの値だけをパラメータとして指定すると、オプティミスティックロックを有効にしているかどうかにかかわらず、削除が成功します。

**注記**  
このオペレーションをバックグラウンドで実行するには、`DeleteAsync` メソッドを使用します。

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

すべてのマネージドリソースとアンマネージドリソースを破棄します。

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

1 つ以上のテーブルからデータを読み込みます。`BatchGet` 内のすべての `MultiTableBatchGet` オブジェクトを処理します。

**注記**  
このオペレーションをバックグラウンドで実行するには、`ExecuteBatchGetAsync` メソッドを使用します。

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

1 つ以上のテーブルにデータを書き込むまたは削除します。`BatchWrite` 内のすべての `MultiTableBatchWrite` オブジェクトを処理します。

**注記**  
このオペレーションをバックグラウンドで実行するには、`ExecuteBatchWriteAsync` メソッドを使用します。

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

`Document` のインスタンスと仮定すると、`FromDocument` メソッドは、クライアント側のクラスのインスタンスを返します。

これは、オブジェクト永続性モデルと合わせてドキュメントモデルクラスを使用してデータオペレーションを行う場合に役立ちます。AWS SDK for .NET で使用されるドキュメントモデルクラスの詳細については、「[DynamoDB での .NET ドキュメントの操作](DotNetSDKMidLevel.md)」を参照してください。

`Document` という名前の `doc` オブジェクトがあり、`Forum` 項目の表現を含んでいるとします。(このオブジェクトの構成方法については、下の `ToDocument` メソッドの説明を参照してください)。次の C\$1 サンプルコードに示すように、`FromDocument` を使用して `Forum` から `Document` 項目を取得することができます。

**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` コレクションが返ります。最初に結果が 1 ページのみ返され、必要に応じて、さらに次ページを要求するサービス呼び出しが行われます。一致する項目をすべて取得するには、`IEnumerable` を反復的に処理します。

テーブルにシンプルなプライマリキー (パーティションキー) がある場合は、`Query` メソッドを使用できません。代わりに `Load` メソッドを使用して、パーティションキーを入力して項目を取り出すことができます。

**注記**  
このオペレーションをバックグラウンドで実行するには、`QueryAsync` メソッドを使用します。

## 保存
<a name="w2aac17b9c21c23c39c35"></a>

指定したオブジェクトがテーブルに保存されます。入力オブジェクトで指定されたプライマリキーがテーブル内に存在しない場合は、このメソッドによって新しい項目がテーブルに追加されます。プライマリキーが存在する場合は、このメソッドによって既存の項目が更新されます。

オプティミスティックロックを設定している場合には、クライアント側とサーバー側で項目のバージョンが一致する場合のみ、更新が正常に実行されます。詳細については、「[DynamoDB と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック](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` コレクションが返ります。最初に結果が 1 ページのみ返され、必要に応じて、さらに次ページを要求するサービス呼び出しが行われます。一致するすべての項目は、`IEnumerable` を反復的に処理するだけで取得できます。

パフォーマンス上の理由から、テーブルについてはスキャンを避け、クエリを行うようにしてください。

**注記**  
このオペレーションをバックグラウンドで実行するには、`ScanAsync` メソッドを使用します。

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

クラスインスタンスから、`Document` ドキュメントモデルクラスのインスタンスが返されます。

これは、オブジェクト永続性モデルと合わせてドキュメントモデルクラスを使用してデータオペレーションを行う場合に役立ちます。AWS SDK for .NET で使用されるドキュメントモデルクラスの詳細については、「[DynamoDB での .NET ドキュメントの操作](DotNetSDKMidLevel.md)」を参照してください。

クライアント側のクラスが `Forum` サンプルテーブルにマッピングされているとします。その場合は次の C\$1 サンプルコードに示すように、`DynamoDBContext` を使用して、`Document` テーブルから項目を `Forum` オブジェクトとして取得することができます。

**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`-**このパラメータにより、`Save` オペレーション時に属性の null 値を無視するように `DynamoDBContext` に指示できます。このパラメータが false の場合 (または設定されていない場合)、null 値は、特定の属性を削除するディレクティブと見なされます。
+ **`SkipVersionCheck`–**このパラメータは、項目の保存または削除を実行する際、バージョンの比較を行わないように `DynamoDBContext` に指示します。バージョニングの詳細については、「[DynamoDB と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック](DynamoDBContext.VersionSupport.md)」を参照してください。
+ **`TableNamePrefix`-**すべてのテーブル名に特定の文字列をプレフィックスします。このパラメータが null の場合（または設定されていない場合）、プレフィックスは使用されません。
+ `DynamoDBEntryConversion` – クライアントで使用する変換スキーマを指定します。このパラメータはバージョン V1 または V2 に設定できます。デフォルトのバージョンは V1 です。

  設定したバージョンに応じて、このパラメータの動作が変わります。例えば、次のようになります。
  + V1 では、`bool` データ型が `N` 数値型に変換されます。0 は false、1 は true を表します。V2 では、`bool` が `BOOL` に変換されます。
  + V2 の場合、リストと配列は HashSets と一緒にグループ化されません。数値、文字列ベースの型、バイナリベースの型のリストと配列は `L` (List) 型に変換され、リストを更新するために空で送信できます。この動作は、空のリストがワイヤ経由で送信されない V1 とは異なります。

    V1 の場合、List、HashSet、配列などのコレクションタイプは同じように扱われます。List、HashSet、数値の配列は `NS` (数値セット) 型に変換されます。

  次の例では、変換スキーマのバージョンを V2 に設定し、.NET 型と DynamoDB データ型間の変換動作を変更します。

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

次の C\$1 サンプルコードでは、前述のオプションパラメータのうち 2 つ (`ConsistentRead` と `SkipVersionCheck`) を指定して、新しい `DynamoDBContext` を作成します。

**Example**  

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

`DynamoDBContext` では、このコンテキストを使用して送信した各リクエストに、これらのオプションパラメータが含められます。

次の C\$1 サンプルコードに示すように、これらのパラメータを `DynamoDBContext` レベルで設定する代わりに、`DynamoDBContext` を使用して実行するオペレーションに対して個別に指定することもできます。この例では特定の書籍項目がロードされています。`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 と AWS SDK for .NET のオブジェクト永続性モデルを使用した楽観的ロック
<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 を割り当てます。既存の項目を取得し、1 つ以上のプロパティを更新して変更を保存しようとすると、保存オペレーションは、クライアント側とサーバー側のバージョン番号が一致する場合にのみ成功します。`DynamoDBContext` によってバージョン番号が増加します。バージョン番号を設定する必要はありません。
+ 次の C\$1 サンプルコードに示すように、`Delete` メソッドでは、プライマリキーの値またはオブジェクトのいずれかをパラメータとして指定できるオーバーロードを使用できます。  
**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 });
```

# AWS SDK for .NET のオブジェクト永続性モデルを使用した、DynamoDB での任意データのマッピング
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

サポート済みの .NET 型 (「[サポートされているデータ型](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)」を参照) に加えて、アプリケーション内にあり Amazon DynamoDB 型に直接マッピングされていない型を使用できます。オブジェクト永続性モデルでは、任意型から DynamoDB 型に (またはその反対に) データを変換できるコンバーターを用意することで、任意型のデータを格納できます。コンバーターコードによって、オブジェクトの保存およびロード中にデータが変換されます。

クライアント側で任意の型を作成できます。ただし、テーブルには、いずれかの DynamoDB 型を使用してデータが格納されます。また、クエリおよびスキャンの際のデータ比較は、DynamoDB に格納されているデータに対して行われます。

次の C\$1 コード例では、`Book`、`Id`、`Title`、および `ISBN` プロパティを使用して `Dimension` クラスを定義しています。`Dimension` プロパティは、`DimensionType`、`Height`、および `Width` プロパティを記述する `Thickness` に含まれています。このコード例では、コンバーターメソッド `ToEntry` および `FromEntry` によって、`DimensionType` と DynamoDB の文字列型との間でデータが変換されます。たとえば、`Book` インスタンスを保存すると、コンバータによって、「8.5 x 11 x 05」などの書籍 `Dimension` 文字列が作成されます。書籍を取得すると、その文字列は `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;
        }
    }
}
```