

# DynamoDB に対する AWS SDK サポートの概要
<a name="Programming.SDKOverview"></a>

次の図表は、AWS SDK を使用した Amazon DynamoDB アプリケーションの、プログラミングの概要を示しています。

![\[AWS SDK で DynamoDB を使用するためのプログラミングモデル。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. 自分が使用するプログラミング言語用のための AWS SDK を使用して、アプリケーションを作成します。

1. 各 AWS SDK には、DynamoDB を操作するプログラミングインターフェイスが 1 つ以上用意されています。使用できるインターフェイスは、使用するプログラミング言語と AWS SDK によって異なります。オプションには以下が含まれます。
   + [DynamoDB で動作する低レベルインターフェイス](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [DynamoDB で動作するドキュメントインターフェイス](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [DynamoDB で動作するオブジェクト永続性インターフェイス](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [高レベルのインターフェイス](HigherLevelInterfaces.md)

1. AWS SDK は、低レベル DynamoDB API で使用する HTTP (S) リクエストを作成します。

1. AWS SDK は DynamoDB エンドポイントにリクエストを送信します。

1. DynamoDB がリクエストを実行します。リクエストが成功すると、DynamoDB は HTTP 200 レスポンスコード (OK) を返します。リクエストが失敗した場合は、DynamoDB は HTTP エラーコードとエラーメッセージを返します。

1. AWS SDK はレスポンスを処理し、アプリケーションに伝達します。

各 AWS SDK は、次のような重要なサービスをアプリケーションに提供します。
+ HTTP (S) リクエストのフォーマットと、リクエストパラメータのシリアル化。
+ リクエストごとの暗号化署名の生成。
+ DynamoDB エンドポイントへのリクエストの転送と、DynamoDB からのレスポンスの受信。
+ これらの応答からの結果の抽出。
+ エラーが発生した場合の基本的な再試行ロジックの実装。

これらのタスクでは、コードを記述する必要はありません。

**注記**  
AWS SDK のインストール方法とドキュメントの詳細については、「[アマゾン ウェブ サービス用ツール](https://aws.amazon.com/tools)」を参照してください。

## AWS アカウントベースのエンドポイントの SDK サポート
<a name="Programming.SDKs.endpoints"></a>

AWS は、2024 年 9 月 4 日、SDK for Java V1 から、DynamoDB の AWS アカウントベースのエンドポイントの AWS SDK サポートをロールアウトします。これらの新しいエンドポイントは、高いパフォーマンスとスケーラビリティを AWS で確保するのに役立ちます。更新された SDK では、`https://(account-id).ddb.(region).amazonaws.com` 形式の新しいエンドポイントを自動的に使用します。

SDK クライアントの 1 つのインスタンスを使用して複数のアカウントにリクエストを行う場合、アプリケーションは接続を再利用する機会が少なくなります。AWS では、SDK クライアントインスタンスあたりの接続先のアカウント数を減らすようにアプリケーションを変更することをお勧めします。代わりに、「[AWS SDK およびツールリファレンスガイド](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html)」に記載されているように、`ACCOUNT_ID_ENDPOINT_MODE` 設定を使用してリージョンエンドポイントを引き続き使用するように SDK クライアントを設定することもできます。**

# DynamoDB で動作するプログラムインターフェイス
<a name="Programming.SDKs.Interfaces"></a>

各 [AWS SDK](https://aws.amazon.com/tools) には、Amazon DynamoDB を操作するプログラミングインターフェイスが 1 つ以上用意されています。これらのインターフェイスは、シンプルな低レベルの DynamoDB ラッパーから、オブジェクト指向の永続レイヤーまで、多岐にわたります。使用可能なインターフェイスは、AWS SDK およびプログラミング言語によって異なります。

![\[DynamoDB を使用するためのさまざまな AWS SDK で利用可能なプログラミングインターフェイス。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


次のセクションでは、AWS SDK for Java を例として使用して、使用可能なインターフェイスをいくつかハイライトします。(すべてのインターフェイスが、どの AWS SDK でも使用できるわけではありません。)

**Topics**
+ [DynamoDB で動作する低レベルインターフェイス](#Programming.SDKs.Interfaces.LowLevel)
+ [DynamoDB で動作するドキュメントインターフェイス](#Programming.SDKs.Interfaces.Document)
+ [DynamoDB で動作するオブジェクト永続性インターフェイス](#Programming.SDKs.Interfaces.Mapper)

## DynamoDB で動作する低レベルインターフェイス
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

それぞれの言語特有の AWS SDK は、低レベルの DynamoDB API リクエストによく似たメソッドを持つ、Amazon DynamoDB 用の低レベルインターフェイスを提供します。

場合によっては [データ型記述子](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors) を使用して、文字列型の `S` や、数値型の `N` など、属性のデータ型を識別する必要があります。

**注記**  
すべての言語特有の AWS SDK で、低レベルインターフェイスを使用できます。

次の Java プログラムは、AWS SDK for Java の低レベルインターフェイスを使用しています。

### 低レベルインターフェイスの例
<a name="low-level-example"></a>

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal>

                Where:
                    tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3).\s
                    key - The key used in the Amazon DynamoDB table (for example, Artist).\s
                    keyval - The key value that represents the item to get (for example, Famous Band).
                """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName);
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        getDynamoDBItem(ddb, tableName, key, keyVal);
        ddb.close();
    }

    public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) {
        HashMap<String, AttributeValue> keyToGet = new HashMap<>();
        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal)
                .build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            // If there is no matching item, GetItem does not return any data.
            Map<String, AttributeValue> returnedItem = ddb.getItem(request).item();
            if (returnedItem.isEmpty())
                System.out.format("No item found with the key %s!\n", key);
            else {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");
                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

## DynamoDB で動作するドキュメントインターフェイス
<a name="Programming.SDKs.Interfaces.Document"></a>

多くの AWS SDK はドキュメントインターフェイスを備えており、テーブルやインデックスに対してデータプレーンオペレーション (作成、読み取り、更新、削除) を実行できます。ドキュメントインターフェイスでは、[データ型記述子](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors) を指定する必要はありません。データ型は、データ自体のセマンティクスによって暗示されています。これらの AWS SDK には、JSON ドキュメントとネイティブの Amazon DynamoDB データ型とを簡単に変換するメソッドも用意されています。

**注記**  
ドキュメントインターフェイスは、AWS SDK for [Java](https://aws.amazon.com/sdk-for-java)、[.NET](https://aws.amazon.com/sdk-for-net)、[Node.js](https://aws.amazon.com/sdk-for-node-js)、および [JavaScript SDK](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/) で使用できます。

次の Java プログラムは、AWS SDK for Java のドキュメントインターフェイスを使用します。プログラムが `Music` テーブルを表す `Table` オブジェクトを作成し、そのオブジェクトに `GetItem` の使用を依頼して、曲を取得します。その後プログラムが、曲がリリースされた年を出力します。

`software.amazon.dynamodb.document.DynamoDB` クラスは DynamoDB ドキュメントインターフェイスを実装します。低レベルクライアント (`AmazonDynamoDB`) のラッパーとして、`DynamoDB` がどのような役割を果たすかに注目してください。

### ドキュメントインターフェイスの例
<a name="document-level-example"></a>

```
package com.amazonaws.codesamples.gsg;

import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.document.DynamoDB;
import software.amazon.dynamodb.document.GetItemOutcome;
import software.amazon.dynamodb.document.Table;

public class MusicDocumentDemo {

    public static void main(String[] args) {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
        DynamoDB docClient = new DynamoDB(client);

        Table table = docClient.getTable("Music");
        GetItemOutcome outcome = table.getItemOutcome(
                "Artist", "No One You Know",
                "SongTitle", "Call Me Today");

        int year = outcome.getItem().getInt("Year");
        System.out.println("The song was released in " + year);

    }
}
```

## DynamoDB で動作するオブジェクト永続性インターフェイス
<a name="Programming.SDKs.Interfaces.Mapper"></a>

一部の AWS SDK には、データプレーンオペレーションを直接実行しない、オブジェクト永続性インターフェイスが用意されています。代わりに、Amazon DynamoDB のテーブルとインデックスの項目を表すオブジェクトを作成し、それらのオブジェクトのみとやり取りを行います。これにより、データベースを意識するのではなく、オブジェクトを中心にコードを作成していくことができます。

**注記**  
オブジェクト永続性インターフェイスは、AWS SDK for Java と for .NET で利用できます。詳細については、DynamoDB の「[DynamoDB の上位レベルのプログラミングインターフェイス](HigherLevelInterfaces.md)」を参照してください。

### オブジェクト永続性インターフェイスの例
<a name="mapper-level-example"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key. Be sure one of the id values is `id101`
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table. These values
 *                        need to be in the form of `YYYY-MM-DDTHH:mm:ssZ`, such as 2022-07-11T00:00:00Z
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedGetItem {
    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        getItem(enhancedClient);
        ddb.close();
    }

    public static String getItem(DynamoDbEnhancedClient enhancedClient) {
        Customer result = null;
        try {
            DynamoDbTable<Customer> table = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key = Key.builder()
                    .partitionValue("id101").sortValue("tred@noserver.com")
                    .build();

            // Get the item by using the key.
            result = table.getItem(
                    (GetItemEnhancedRequest.Builder requestBuilder) -> requestBuilder.key(key));
            System.out.println("******* The description value is " + result.getCustName());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return result.getCustName();
    }
}
```

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

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

# このデベロッパーガイドのコード例の実行
<a name="CodeSamples"></a>

AWS SDK では、次の言語で Amazon DynamoDB を幅広くサポートしています。
+ [Java](https://aws.amazon.com/sdk-for-java): 
+ [ブラウザの JavaScript](https://aws.amazon.com/sdk-for-browser)
+ [.NET](https://aws.amazon.com/sdk-for-net)
+ [Node.js](https://aws.amazon.com/sdk-for-node-js)
+ [PHP](https://aws.amazon.com/sdk-for-php)
+ [Python](https://aws.amazon.com/sdk-for-python) \$1
+ [Ruby](https://aws.amazon.com/sdk-for-ruby)
+ [C\$1\$1](https://aws.amazon.com/sdk-for-cpp)
+ [Go](https://aws.amazon.com/sdk-for-go): 
+ [Android](https://aws.amazon.com/mobile/sdk/)
+ [iOS](https://aws.amazon.com/mobile/sdk/)

この開発者ガイドのコード例は、以下のプログラミング言語を使用して DynamoDB オペレーションの詳細を示しています。
+ [Java コードの例](CodeSamples.Java.md)
+ [.NET コード例](CodeSamples.DotNet.md)

この演習を開始する前に、AWS アカウントを作成し、アクセスキーとシークレットキーを取得して、コンピュータで AWS Command Line Interface (AWS CLI) をセットアップします。詳細については、「」を参照してください[DynamoDB (ウェブサービス) の設定](SettingUp.DynamoWebService.md)

**注記**  
DynamoDB のダウンロード可能バージョンを使用する場合は、AWS CLI を使用してテーブルとサンプルデータを作成する必要があります。また、各 `--endpoint-url` コマンドで AWS CLI パラメータも指定する必要があります。詳細については、「[ローカルエンドポイントの設定](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint)」を参照してください。

# DynamoDB でのコード例用のテーブルの作成とデータのロード
<a name="SampleData"></a>

DynamoDB でのテーブルの作成、サンプルデータセットのロード、データに対するクエリの実行、およびデータの更新に関する基本については、以下を参照してください。
+ [ステップ 1: DynamoDB にテーブルを作成する](getting-started-step-1.md)
+ [ステップ 2: DynamoDB テーブルにデータを書き込む](getting-started-step-2.md)
+ [ステップ 3: DynamoDB テーブルからデータを読み込む](getting-started-step-3.md)
+ [ステップ 4: DynamoDB テーブルのデータを更新する](getting-started-step-4.md)

# Java コードの例
<a name="CodeSamples.Java"></a>

**Topics**
+ [Java: AWS 認証情報の設定](#CodeSamples.Java.Credentials)
+ [Java: AWS リージョンとエンドポイントの設定](#CodeSamples.Java.RegionAndEndpoint)

この開発者ガイドには、Java コードスニペットとすぐに使用できるプログラムが含まれています。これらのコード例は、次のセクションで確認することができます。
+ [DynamoDB での項目と属性の操作](WorkingWithItems.md)
+ [DynamoDB でのテーブルとデータの操作](WorkingWithTables.md)
+ [DynamoDB のテーブルに対するクエリの実行](Query.md)
+ [DynamoDB でのテーブルのスキャン](Scan.md)
+ [DynamoDB でのセカンダリインデックスを使用したデータアクセス性の向上](SecondaryIndexes.md)
+ [Java 1.x: DynamoDBMapper](DynamoDBMapper.md)
+ [DynamoDB Streams の変更データキャプチャ](Streams.md)

Eclipse と [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/) を使用して、すぐに開始できます。フル機能の IDE に加えて、自動更新で AWS SDK for Java および AWS アプリケーションの構築用に事前設定されたテンプレートも取得できます。

**Java サンプルコードを実行するには (Eclipse を使用)**

1. [Eclipse](http://www.eclipse.org) IDE をダウンロードし、インストールします。

1. のダウンロードおよびインストール。[AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/)。

1. Eclipse を起動し、**Eclipse** メニューから、**[File]** (ファイル)、**[New]** (新規)、**[Other]** (その他) の順に選択します。

1. **[Select a wizard]** (ウィザードの選択) で、**AWS**、**[AWS Java Project]** ( Java プロジェクト) の順に選択してから、**[Next]** (次へ) をクリックします。

1. **[AWS Java の作成]** で、次の操作を行います。

   1. **[Project name]** (プロジェクト名) にプロジェクトの名前を入力します。

   1. **[Select Account]** (アカウントの選択) リストから認証情報プロファイルを選択します。

      [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/) を初めて使用する場合、**[AWS アカウントの設定]** を選択して、AWS 認証情報を設定します。

1. **[Finish]** (完了) を選択してプロジェクトを作成します。

1. **Eclipse** メニューから **[File]** (ファイル)、**[New]** (新規)、**[Class]** (クラス) の順に選択します。

1. **[Java Class]** (Java クラス) の **[Name]** (名前) にクラスの名前を入力し (実行するコード例と同じ名前を使用)、**[Finish]** (完了) を選択してクラスを作成します。

1. ドキュメントページから Eclipse エディタにサンプルコードをコピーします。

1. コードを実行するには、Eclipse メニューの **[Run]** (実行) を選択します。

SDK for Java には、DynamoDB を操作するためにスレッドセーフなクライアントが用意されています。ベストプラクティスとして、ご利用のアプリケーションでクライアントを 1 つ作成し、そのクライアントをスレッド間で再利用します。

詳細については、[AWS SDK for Java](https://aws.amazon.com/sdk-for-java) を参照してください。

**注記**  
このガイドのサンプルコードは、最新バージョンの AWS SDK for Java で使用するためのものです。  
AWS Toolkit for Eclipse を使用している場合、SDK for Java の自動更新を設定することができます。これを Eclipse で行うには、**[Preferences]** (基本設定) に移動し、**AWS Toolkit**、**AWS SDK for Java**、**[Download new SDKs automatically]** (新しい SDK を自動的にダウンロード) の順に選択します。

## Java: AWS 認証情報の設定
<a name="CodeSamples.Java.Credentials"></a>

SDK for Java では、ランタイムにアプリケーションに AWS 認証情報を指定する必要があります。このガイドのコード例では、AWS 認証情報ファイルを使用していることを前提としています。詳細については、「AWS SDK for Java デベロッパーガイド」の「[開発用の AWS 認証情報のセットアップ](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html)」を参照してください。

`~/.aws/credentials` という名前の AWS 認証情報ファイルの例を次に示します。ここで、チルダ文字 (`~`) はホームディレクトリを表します。

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

## Java: AWS リージョンとエンドポイントの設定
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

デフォルトでは、コード例は、米国西部 (オレゴン) リージョンの DynamoDB にアクセスします。このリージョンを変更するには、`AmazonDynamoDB` プロパティを変更します。

次のサンプルコードは、新しい `AmazonDynamoDB` をインスタンス化します。

```
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import com.amazonaws.regions.Regions;
...
// This client will default to US West (Oregon)
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.build();
```

`withRegion` メソッドを使用して、利用可能な任意のリージョンで、DynamoDB を対象としてコードを実行できます。リージョンのリストについては、「*Amazon Web Services 全般のリファレンス*」の「[AWS リージョンとエンドポイント](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)」を参照してください。

ローカルコンピュータで DynamoDB を使用してサンプルコードを実行する場合は、エンドポイントを設定する必要があります。

### AWS SDKV1
<a name="CodeSamples.Java.RegionAndEndpoint.V1"></a>

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
```

### AWS SDK V2
<a name="CodeSamples.Java.RegionAndEndpoint.V2"></a>

```
DynamoDbClient client = DynamoDbClient.builder()
    .endpointOverride(URI.create("http://localhost:8000"))
    // The region is meaningless for local DynamoDb but required for client builder validation
    .region(Region.US_EAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(
    AwsBasicCredentials.create("dummy-key", "dummy-secret")))
    .build();
```

# .NET コード例
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [.NET: AWS 認証情報の設定](#CodeSamples.DotNet.Credentials)
+ [.NET: AWS リージョンとエンドポイントの設定](#CodeSamples.DotNet.RegionAndEndpoint)

このガイドには、.NET コードスニペットとすぐに使用できるプログラムが含まれています。これらのコード例は、次のセクションで確認することができます。
+ [DynamoDB での項目と属性の操作](WorkingWithItems.md)
+ [DynamoDB でのテーブルとデータの操作](WorkingWithTables.md)
+ [DynamoDB のテーブルに対するクエリの実行](Query.md)
+ [DynamoDB でのテーブルのスキャン](Scan.md)
+ [DynamoDB でのセカンダリインデックスを使用したデータアクセス性の向上](SecondaryIndexes.md)
+ [DynamoDB での .NET ドキュメントの操作](DotNetSDKMidLevel.md)
+ [.NET オブジェクト永続性モデルと DynamoDB の使用](DotNetSDKHighLevel.md)
+ [DynamoDB Streams の変更データキャプチャ](Streams.md)

AWS SDK for .NET と Toolkit for Visual Studio を使用すると、すぐに始めることができます。

**.NET サンプルコードを実行するには (Visual Studio を使用)**

1. [Microsoft Visual Studio](https://www.visualstudio.com) をダウンロードし、インストールします。

1. (オプション) [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/) をダウンロードしてインストールします。

1. AWS 認証情報をセットアップします。共有 AWS 認証情報ファイル (`~/.aws/credentials`) で認証情報プロファイルを設定します。詳細については、「*AWS SDK for .NET デベロッパーガイド*」の「[AWS 認証情報の設定](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html)」を参照してください。

1. Visual Studio を起動します。**[File]** (ファイル)、**[New]** (新規)、**[Project]** (プロジェクト) の順に選択します。

1. **[コンソールアプリ]** を検索し、.NET をターゲットとする C\$1 テンプレートを選択し、**[次へ]** を選択します。プロジェクト名と場所を設定し、**[作成]** を選択します。

1. プロジェクトに DynamoDB NuGet パッケージ用 AWS SDK を追加します。

   1. ソリューションエクスプローラーで、プロジェクトのコンテキスト (右クリック) メニューを開いて、**[Manage NuGet Packages]** (NuGet パッケージの管理) を選択します。

   1. NuGet パッケージマネージャーで、**[Browse]** (参照) を選択します。

   1. 検索ボックスに「**AWSSDK.DynamoDBv2**」と入力し、完了するまで待ちます。

   1. **AWSSDK.DynamoDBv2**、**[Install]** (インストール) の順に選択します。

1. Visual Studio プロジェクトで、`Program.cs` を開きます。内容を、実行するドキュメントページのコード例に置き換えます。

1. コードを実行するには、Visual Studio ツールバーの **[Start]** (開始) を選択します。

SDK for .NET には、DynamoDB を操作するためにスレッドセーフなクライアントが用意されています。ベストプラクティスとして、ご利用のアプリケーションでクライアントを 1 つ作成し、そのクライアントをスレッド間で再利用します。

詳細については、「[AWS SDK for .NET](https://aws.amazon.com/sdk-for-net)」を参照してください。

**注記**  
このガイドのサンプルコードは、最新バージョンの AWS SDK for .NET で使用するためのものです。

## .NET: AWS 認証情報の設定
<a name="CodeSamples.DotNet.Credentials"></a>

SDK for .NET では、ランタイムにアプリケーションに AWS 認証情報を指定する必要があります。このガイドのコード例は、SDK ストアを使用して AWS 認証情報ファイルを管理することを前提としています。詳細については、「*AWS SDK for .NET デベロッパーガイド*」の「[SDK ストアの使用](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store)」を参照してください。

Toolkit for Visual Studio では、任意の数のアカウントの複数セットの認証情報がサポートされています。各セットは*プロファイル*と呼ばれています。Visual Studio では、プロジェクトの `App.config` ファイルにエントリを追加するため、アプリケーションはランタイム時に AWS 認証情報を見つけることができます。

次の例は、Toolkit for Visual Studio を使用した新しいプロジェクトの作成時に生成されたデフォルトの `App.config` ファイルを示しています。

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

ランタイム時に、このプログラムは `AWSProfileName` エントリで指定されているように、AWS 認証情報の `default` セットを使用します。AWS 認証情報自体は、暗号化されたフォームで SDK ストアに保持されます。Toolkit for Visual Studio は、すべて Visual Studio 内からの認証情報を管理するためのグラフィカルユーザーインターフェイスを使用します。詳細については、「*AWS Toolkit for Visual Studio ユーザーガイド*」の「[認証情報の指定](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds)」を参照してください。

**注記**  
デフォルトでは、コード例は、米国西部 (オレゴン) リージョンの DynamoDB にアクセスします。リージョンを変更するには、App.config ファイルで `AWSRegion` エントリを変更します。`AWSRegion` を DynamoDB が利用可能なすべてのリージョンに設定します。リージョンのリストについては、「*Amazon Web Services 全般のリファレンス*」の「[AWS リージョンとエンドポイント](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)」を参照してください。

## .NET: AWS リージョンとエンドポイントの設定
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

デフォルトでは、コード例は、米国西部 (オレゴン) リージョンの DynamoDB にアクセスします。リージョンを変更するには、`AWSRegion` ファイルで `App.config` エントリを変更します。または、`AmazonDynamoDBClient` プロパティを変更してリージョンを変更することもできます。

次のサンプルコードは、新しい `AmazonDynamoDBClient` をインスタンス化します。クライアントは、別のリージョンでコードが DynamoDB に対して実行するように変更されます。

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

リージョンのリストについては、「*Amazon Web Services 全般のリファレンス*」の「[AWS リージョンとエンドポイント](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region)」を参照してください。

ローカルコンピュータで DynamoDB を使用してサンプルコードを実行する場合は、エンドポイントを設定する必要があります。

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

# DynamoDB 低レベル API
<a name="Programming.LowLevelAPI"></a>

Amazon DynamoDB の*低レベル API* は、DynamoDB 用のプロトコルレベルのインターフェイスです。このレベルでは、すべての HTTP リクエストは、適切な形式で有効なデジタル署名がある必要があります。

AWS SDK は、低レベル DynamoDB API リクエストをユーザーに代わって作成し、DynamoDB からのレスポンスを処理します。これにより、低レベルの詳細ではなく、アプリケーションロジックに専念することができます。ただし、低レベル DynamoDB API の動作方法についての基本的な知識も役立ちます。

低レベル DynamoDB API の詳細については、[Amazon DynamoDB API リファレンス](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)を参照してください。

**注記**  
DynamoDB Streams には、DynamoDB とは別に独自の低レベル API があり、AWS SDK で完全にサポートされています。  
詳細については、「[DynamoDB Streams の変更データキャプチャ](Streams.md)」を参照してください。低レベル DynamoDB Streams API については、[Amazon DynamoDB Streams API リファレンス](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html)を参照してください。

低レベル DynamoDB API は、ワイヤプロトコル形式として、JavaScript Object Notation (JSON) を使用しています。JSON では、データ値とデータ構造が両方同時にわかるように、データが階層で示されます。名前と値のペアは、`name:value` の形式で定義されます。データ階層は、名前と値のペアをブラケットで囲み、ネストする形で定義します。

DynamoDB は、ストレージ形式としてではなく、トランスポートプロトコルとしてのみ、JSON を使用しています。JSON を使用して AWS SDK が DynamoDB にデータを送信し、DynamoDB が JSON で応答します。DynamoDB は、JSON 形式でデータを永続的に保存しません。

**注記**  
JSON の詳細については、`JSON.org` ウェブサイトで「[JSON の入門](http://json.org)」を参照してください。

**Topics**
+ [リクエストの形式](#Programming.LowLevelAPI.RequestFormat)
+ [レスポンスの形式](#Programming.LowLevelAPI.ResponseFormat)
+ [データ型記述子](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [数値データ](#Programming.LowLevelAPI.Numbers)
+ [バイナリデータ](#Programming.LowLevelAPI.Binary)

![\[DynamoDB の低レベル API、および AWS SDK によるプロトコルレベルのリクエストとレスポンスの処理方法。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## リクエストの形式
<a name="Programming.LowLevelAPI.RequestFormat"></a>

DynamoDB 低レベル API は、HTTP(S) `POST` リクエストを入力として受け付けます。AWS SDK はこれらのリクエストを作成します。

`Pets` という名のテーブルに、`AnimalType` (パーティションキー)、`Name` (ソートキー) によって構成されるキースキーマがあるとします。これらの属性はいずれも、`string` 型になります。`Pets` から項目を取得するために、AWS SDK は次のリクエストを作成します。

```
POST / HTTP/1.1
Host: dynamodb.<region>.<domain>;
Accept-Encoding: identity
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.0
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature>
X-Amz-Date: <Date> 
X-Amz-Target: DynamoDB_20120810.GetItem

{
    "TableName": "Pets",
    "Key": {
        "AnimalType": {"S": "Dog"},
        "Name": {"S": "Fido"}
    }
}
```

このリクエストに関して以下の点に注意してください。
+ `Authorization` ヘッダーには、DynamoDB がリクエストを認証するのに必要な情報が含まれています。詳細は、「*Amazon Web Services 全般のリファレンス*」の「[AWS API リクエストへの署名](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)」と「[署名バージョン 4 の署名プロセス](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)」を参照してください。
+ `X-Amz-Target` ヘッダーには、DynamoDB オペレーションの名前である `GetItem` が含まれます 。(これは、低レベル API バージョンと共に示されます。この場合は `20120810` となります。)
+ リクエストのペイロード (本文) には、JSON 形式で、オペレーションのパラメーターが含まれます。`GetItem` オペレーションでは、パラメーターは `TableName` と `Key` です。

## レスポンスの形式
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

リクエストを受け取ったら、DynamoDB が処理しレスポンスを返します。前の例に示したように、HTTP レスポンスペイロードには、オペレーションからの結果が含まれます。

```
HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{
    "Item": {
        "Age": {"N": "8"},
        "Colors": {
            "L": [
                {"S": "White"},
                {"S": "Brown"},
                {"S": "Black"}
            ]
        },
        "Name": {"S": "Fido"},
        "Vaccinations": {
            "M": {
                "Rabies": {
                    "L": [
                        {"S": "2009-03-17"},
                        {"S": "2011-09-21"},
                        {"S": "2014-07-08"}
                    ]
                },
                "Distemper": {"S": "2015-10-13"}
            }
        },
        "Breed": {"S": "Beagle"},
        "AnimalType": {"S": "Dog"}
    }
}
```

この時点で、AWS SDK は、さらに処理するためにアプリケーションに応答データを返します。

**注記**  
リクエストを処理できない場合は、DynamoDB より HTTP エラーコードとメッセージが返ります。AWS SDK は、これらを例外形式でアプリケーションに伝達します。詳細については、「[DynamoDB でのエラー処理](Programming.Errors.md)」を参照してください。

## データ型記述子
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

低レベル DynamoDB API のプロトコルは、各属性がデータ型記述子に伴われる必要があります。*データ型記述子*は、各属性を解釈する方法を DynamoDB に伝えるトークンです。

[リクエストの形式](#Programming.LowLevelAPI.RequestFormat)と[レスポンスの形式](#Programming.LowLevelAPI.ResponseFormat)には、データ型記述子が使用されている例が示されています。`GetItem` リクエストでは、`S` キースキーマ属性 (`Pets` と `AnimalType`) に `Name` を `string` 型で指定します。`GetItem` レスポンスには、`string` (`S`)、`number` (`N`)、`map` (`M`)、`list` (`L`) 型の属性を持つ、*Pets* 項目が含まれます。

DynamoDB データ型記述子の一覧を次に示します。
+ **`S`** — 文字列
+ **`N`** — 数値
+ **`B`** — バイナリ
+ **`BOOL`** — ブール
+ **`NULL`** — Null
+ **`M`** — マップ
+ **`L`** — リスト
+ **`SS`** — 文字列セット
+ **`NS`** — 数値セット
+ **`BS`** — バイナリセット

次の表は、各データ型記述子の正しい JSON 形式を示しています。数値は精度を維持するために文字列として表されますが、ブール値と null はネイティブの JSON 型を使用することに注意してください。


| ディスクリプタ | JSON 形式 | 注意事項 | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | 値は JSON 文字列です。 | 
| N | \$1"N": "123.45"\$1 | 値は文字列であり、JSON 数値ではありません。これにより、言語間で精度が維持されます。 | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | 値は base64 でエンコードされた文字列です。 | 
| BOOL | \$1"BOOL": true\$1 | 値は JSON ブール値 (true または false) で、文字列ではありません。 | 
| NULL | \$1"NULL": true\$1 | 値は null を示す JSON ブール値 true です。 | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | 値は、属性名と値のペアの JSON オブジェクトです。 | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | 値は属性値の JSON 配列です。 | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | 値は文字列の JSON 配列です。 | 
| NS | \$1"NS": ["1", "2.5"]\$1 | 値は数値文字列の JSON 配列です。 | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | 値は base64 でエンコードされた文字列の JSON 配列です。 | 

**注記**  
 DynamoDB データ型の詳細な説明については、「[データ型](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)」を参照してください。

## 数値データ
<a name="Programming.LowLevelAPI.Numbers"></a>

プログラミング言語により、提供される JSON のサポートのレベルが異なります。場合によっては、JSONドキュメントを検証し解析するにあたり、サードパーティーのライブラリを使用することもできます。

JSON Number 型に基づいて構築されたサードパーティーライブラリもあり、`int` や `long`、`double` など独自の型を提供しています。ただし、他のデータ型に正確にマッピングされない DynamoDB のネイティブ数値データ型が使用されるため、このようなデータ型の区別が競合の原因になる可能性があります。加えて、多くの JSON ライブラリでは固定精度の数値は処理されず、小数点を含む数字列は自動的に倍精度浮動小数点データ型であると推定されます。

これらの問題を解決するために、DynamoDB ではデータ損失のない単一の数値型が用意されています。誤って倍精度の値に暗黙的変換が行われないように、DynamoDB では数値のデータ転送には文字列が使用されます。この方法によって、01、2、03 などの値を適切な順序で配置するなど、適切な並べ替えセマンティクスを維持しながら、柔軟に属性値を更新することが可能になります。

数値の精度がアプリケーションにとって重要な場合は、数値を文字列に変換してから、DynamoDB に渡します。

## バイナリデータ
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB ではバイナリ属性がサポートされています。ただし JSON では、ネイティブではバイナリデータのエンコードがサポートされていません。リクエストでバイナリデータを送信するには、base64 形式でエンコードする必要があります。DynamoDB はリクエストを受け取ると、base64 データをバイナリに復号します。

DynamoDB で使用される base64 エンコーディングスキームは、Internet Engineering Task Force (IETF) ウェブサイトの「[RFC 4648](http://tools.ietf.org/html/rfc4648)」に記載されています。