メニュー
Amazon DynamoDB
開発者ガイド (API Version 2012-08-10)

項目の操作 : Java

AWS SDK for Java ドキュメント API を使用して、テーブル内の項目に対して、一般的な作成、読み込み、更新、削除(CRUD)のオペレーションを実行できます。

注記

SDK for Java には、オブジェクト永続性モデルも用意されています。このモデルにより、クライアント側のクラスを DynamoDB テーブルにマッピングすることができます。この方法により、記述する必要のあるコードの量を減らすことができます。詳細については、「Java: DynamoDBMapper」を参照してください。

以下のセクションでは、複数の Java ドキュメント API Item の操作を実行する Java スニペットについて説明します。完全な実装例を実行するには、次を参照してください。

項目の置換

putItem メソッドによって、項目をテーブルに格納します。項目が存在する場合、その項目全体が置き換えられます。項目全体を置き換える代わりに固有の属性のみを更新する場合は、updateItem メソッドを使用できます。詳細については、「項目の更新」を参照してください。

以下の手順に従ってください:

  1. DynamoDB クラスのインスタンスを作成します。

  2. 操作対象のテーブルを表すために、Table クラスのインスタンスを作成します。

  3. 新しい項目を表す Item クラスのインスタンスを作成します。新しい項目のプライマリキーと属性を指定する必要があります。

  4. 前の手順で作成した Item を使用して、Table オブジェクトの putItem メソッドを呼び出します。

次の Java コードスニペットは、前述のタスクの例です。このスニペットでは、ProductCatalog テーブルに新しい項目を書き込みます。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); // Build a list of related items List<Number> relatedItems = new ArrayList<Number>(); relatedItems.add(341); relatedItems.add(472); relatedItems.add(649); //Build a map of product pictures Map<String, String> pictures = new HashMap<String, String>(); pictures.put("FrontView", "http://example.com/products/123_front.jpg"); pictures.put("RearView", "http://example.com/products/123_rear.jpg"); pictures.put("SideView", "http://example.com/products/123_left_side.jpg"); //Build a map of product reviews Map<String, List<String>> reviews = new HashMap<String, List<String>>(); List<String> fiveStarReviews = new ArrayList<String>(); fiveStarReviews.add("Excellent! Can't recommend it highly enough! Buy it!"); fiveStarReviews.add("Do yourself a favor and buy this"); reviews.put("FiveStar", fiveStarReviews); List<String> oneStarReviews = new ArrayList<String>(); oneStarReviews.add("Terrible product! Do not buy this."); reviews.put("OneStar", oneStarReviews); // Build the item Item item = new Item() .withPrimaryKey("Id", 123) .withString("Title", "Bicycle 123") .withString("Description", "123 description") .withString("BicycleType", "Hybrid") .withString("Brand", "Brand-Company C") .withNumber("Price", 500) .withStringSet("Color", new HashSet<String>(Arrays.asList("Red", "Black"))) .withString("ProductCategory", "Bicycle") .withBoolean("InStock", true) .withNull("QuantityOnHand") .withList("RelatedItems", relatedItems) .withMap("Pictures", pictures) .withMap("Reviews", reviews); // Write the item to the table PutItemOutcome outcome = table.putItem(item);

前の例では、項目はスカラー(文字列、数値、ブール値、Null)、セット(文字列セット)、ドキュメント型(リスト、マップ)を持っています。

オプションパラメータの指定

必須のパラメータに加え、putItem メソッドにはオプションパラメータも指定できます。たとえば、以下の Java コードスニペットでは、オプションパラメータを使用して、項目のアップロード条件を指定します。指定した条件を満たさない場合は、AWS Java SDK が ConditionalCheckFailedExceptionをスローします。このコードスニペットでは、putItem メソッドに以下のオプションパラメータを指定します。

  • リクエストの条件を定義する ConditionExpression。このスニペットでは、特定の値に等しい ISBN 属性が既存の項目にある場合にのみ同じプライマリキーを持つ既存の項目を置き換えるという条件を定義します。

  • 条件で使用される ExpressionAttributeValues のマップ。この場合、必要な置き換えは 1 つだけです。条件式のプレースホルダー :val が、実行時に、チェックする実際の ISBN 値に置き換えられます。

以下の例では、これらのオプションパラメータを使用して新しい書籍項目を追加します。

Copy
Item item = new Item() .withPrimaryKey("Id", 104) .withString("Title", "Book 104 Title") .withString("ISBN", "444-4444444444") .withNumber("Price", 20) .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author1", "Author2"))); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val", "444-4444444444"); PutItemOutcome outcome = table.putItem( item, "ISBN = :val", // ConditionExpression parameter null, // ExpressionAttributeNames parameter - we're not using it for this example expressionAttributeValues);

PutItem および JSON ドキュメント

JSON ドキュメントは、DynamoDB テーブルに属性として格納できます。これを行うには、項目の withJSON メソッドを使用します。このメソッドは、JSON ドキュメントを解析し、各要素を DynamoDB のネイティブデータ型にマッピングします。

特定の製品の注文を処理できるベンダーを含む、次の JSON ドキュメントを格納するとします。

Copy
{ "V01": { "Name": "Acme Books", "Offices": [ "Seattle" ] }, "V02": { "Name": "New Publishers, Inc.", "Offices": ["London", "New York" ] }, "V03": { "Name": "Better Buy Books", "Offices": [ "Tokyo", "Los Angeles", "Sydney" ] } }

withJSON メソッドを使用して、VendorInfo という名前のマップ属性でこれを ProductCatalog テーブルに格納することができます。次の Java コードスニペットはそれを行う方法を示しています。

Copy
// Convert the document into a String. Must escape all double-quotes. String vendorDocument = "{" + " \"V01\": {" + " \"Name\": \"Acme Books\"," + " \"Offices\": [ \"Seattle\" ]" + " }," + " \"V02\": {" + " \"Name\": \"New Publishers, Inc.\"," + " \"Offices\": [ \"London\", \"New York\"" + "]" + "}," + " \"V03\": {" + " \"Name\": \"Better Buy Books\"," + "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\"" + " ]" + " }" + " }"; Item item = new Item() .withPrimaryKey("Id", 210) .withString("Title", "Book 210 Title") .withString("ISBN", "210-2102102102") .withNumber("Price", 30) .withJSON("VendorInfo", vendorDocument); PutItemOutcome outcome = table.putItem(item);

項目の取得

単一の項目を取り出すには、Table オブジェクトの getItem メソッドを使用します。以下の手順に従ってください:

  1. DynamoDB クラスのインスタンスを作成します。

  2. 操作対象のテーブルを表すために、Table クラスのインスタンスを作成します。

  3. Table インスタンスの getItem メソッドを呼び出します。取り出す項目のプライマリキーを指定する必要があります。

次の Java コードスニペットは、前述のステップを示しています。このコードスニペットでは、指定したパーティションキーを持つ項目を取得します。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Item item = table.getItem("Id", 101);

オプションパラメータの指定

必須のパラメータに加え、getItem メソッドにはオプションパラメータも指定できます。たとえば、以下の Java コードスニペットでは、オプションメソッドを使用して、特定の属性リストのみを取り出します。また、強い整合性のある戻り値をリクエストします。読み込み整合性の詳細については、「読み込み整合性」を参照してください。

ProjectionExpression を使用すると、項目全体ではなく特定の属性または要素のみを取り出すことができます。ProjectionExpression は、ドキュメントのパスを使用して最上位の属性または入れ子になった属性を指定できます。詳細については、「プロジェクション式」を参照してください。

getItem メソッドのパラメーターでは、読み込み整合性を指定することはできません。ただし、すべての低レベル GetItem オペレーションの入力へのフルアクセスを提供する GetItemSpec を作成できます。 以下のコード例では、GetItemSpec を作成し、その仕様を getItem メソッドへの入力として使用します。

Copy
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 206) .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar") .withConsistentRead(true); Item item = table.getItem(spec); System.out.println(item.toJSONPretty());

Item を人間が読める形式で出力するには、toJSONPretty メソッドを使用します。上の例による出力は次のようになります。

Copy
{ "RelatedItems" : [ 341 ], "Reviews" : { "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ] }, "Id" : 123, "Title" : "20-Bicycle 123" }

GetItem および JSON ドキュメント

PutItem および JSON ドキュメント セクションでは、VendorInfo という名前のマップ属性に JSON ドキュメントを格納しました。getItem メソッドを使用して JSON 形式のドキュメント全体を取り出すか、ドキュメントパス表記を使用してドキュメント内の一部の要素のみ取り出します。次の Java コードスニペットは、この手法を示しています。

Copy
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210); System.out.println("All vendor info:"); spec.withProjectionExpression("VendorInfo"); System.out.println(table.getItem(spec).toJSON()); System.out.println("A single vendor:"); spec.withProjectionExpression("VendorInfo.V03"); System.out.println(table.getItem(spec).toJSON()); System.out.println("First office location for this vendor:"); spec.withProjectionExpression("VendorInfo.V03.Offices[0]"); System.out.println(table.getItem(spec).toJSON());

上の例による出力は次のようになります。

Copy
All vendor info: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}} A single vendor: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}} First office location for a single vendor: {"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}

注記

toJSON メソッドを使用して、任意の項目(またはその属性)を JSON 形式文字列に変換できます。次のコードスニペットは、最上位の属性と入れ子になった属性を複数取り出し、JSON として結果を出力します。

Copy
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210) .withProjectionExpression("VendorInfo.V01, Title, Price"); Item item = table.getItem(spec); System.out.println(item.toJSON());

出力は次のようになります。

Copy
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}

バッチ書き込み: 複数の項目の書き込みおよび削除

バッチ書き込みは、複数の項目の書き込みと削除をバッチで行うことを意味します。batchWriteItem メソッドによって、単一の コール内にある 1 つまたは複数のテーブルから複数の項目を置換および削除できます。以下に、AWS SDK for Java ドキュメント API を使用して複数の項目を入力および削除する手順を示します。

  1. DynamoDB クラスのインスタンスを作成します。

  2. テーブルのすべての入力および削除オペレーションを記述する TableWriteItems クラスのインスタンスを作成します。1 つのバッチ書き込みオペレーションで複数のテーブルに書き込む場合、テーブルごとに TableWriteItems インスタンスを 1 つずつ作成する必要があります。

  3. 前の手順で作成した TableWriteItems オブジェクトを指定して、batchWriteItem メソッドを呼び出します。

  4. 応答を処理します。返された未処理のリクエスト項目が応答内に存在していたかどうかをチェックする必要があります。これは、プロビジョニングされたスループットの制限または他の何らかの一時的エラーに達する場合に、発生する可能性があります。また、DynamoDB によって、リクエストのサイズ、およびリクエスト内で指定できるオペレーションの数が制限されます。これらの制限を超えると、DynamoDB によってリクエストが却下されます。詳細については、「DynamoDB での制限」を参照してください。

次の Java コードスニペットは、前述のステップを示しています。この例では、2 つのテーブル(ForumThread)で batchWriteItem オペレーションを実行します。対応する TableWriteItems オブジェクトは、次のアクションを定義します。

  • Forum テーブル内で項目を入力

  • Thread テーブル内で項目を入力および削除

その後、コードは batchWriteItem を呼び出してオペレーションを実行します。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableWriteItems forumTableWriteItems = new TableWriteItems("Forum") .withItemsToPut( new Item() .withPrimaryKey("Name", "Amazon RDS") .withNumber("Threads", 0)); TableWriteItems threadTableWriteItems = new TableWriteItems(Thread) .withItemsToPut( new Item() .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1") .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value"); BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems); // Code for checking unprocessed items is omitted in this example

実例については、「例: AWS SDK for Java ドキュメント API を使用したバッチ書き込みオペレーション」を参照してください。

バッチ取得: 複数の項目の取得

batchGetItem メソッドによって、1 つまたは複数のテーブルから複数の項目を取得できます。単一の項目を取り出すために、getItem メソッドを使用できます。

以下の手順に従ってください:

  1. DynamoDB クラスのインスタンスを作成します。

  2. テーブルから取り出すプライマリキーのリストを記述する TableKeysAndAttributes クラスのインスタンスを作成します。1 つのバッチ取得オペレーションで複数のテーブルから読み込む場合、テーブルごとに TableKeysAndAttributes インスタンスを 1 つずつ作成する必要があります。

  3. 前の手順で作成した TableKeysAndAttributes オブジェクトを指定して、batchGetItem メソッドを呼び出します。

次の Java コードスニペットは、前述のステップを示しています。この例では、Forum テーブル内の 2 つの項目、および Thread テーブル内の 3 つの項目を取り出します。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName); threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB","DynamoDB Thread 1", "Amazon DynamoDB","DynamoDB Thread 2", "Amazon S3","S3 Thread 1"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem( forumTableKeysAndAttributes, threadTableKeysAndAttributes); for (String tableName : outcome.getTableItems().keySet()) { System.out.println("Items in table " + tableName); List<Item> items = outcome.getTableItems().get(tableName); for (Item item : items) { System.out.println(item); } }

オプションパラメータの指定

必須のパラメータに加え、batchGetItem を使用する場合はオプションパラメータも指定できます。たとえば、定義した TableKeysAndAttributes ごとに ProjectionExpression を指定できます。これにより、テーブルから取り出す属性を指定することができます。

次のコードスニペットでは、Forum テーブルの 2 つの項目を取り出します。withProjectionExpression パラメータは、Threads 属性のみを取得することを指定します。

Copy
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum") .withProjectionExpression("Threads"); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);

項目の更新

Table オブジェクトの updateItem メソッドは、既存の属性値の更新、新しい属性の追加、または既存の項目からの属性の削除を実行できます。

updateItem メソッドは、以下のように動作します。

  • 項目が存在しない(指定されたプライマリキーを持つ項目がテーブル内にない)場合、updateItem はテーブルに新しい項目を追加します

  • 項目が存在する場合、updateItemUpdateExpression パラメータで指定されたとおりに更新を実行します。

注記

putItem を使用して項目を「更新」することもできます。たとえば、putItem を呼び出して項目をテーブルに追加したが、指定されたプライマリーキーを持つ項目がすでに存在する場合、putItem は項目全体を置き換えます。入力で指定されていない属性が既存の項目内にある場合、putItem は項目からそれらの属性を削除します。

一般に、項目属性を変更するときは必ず updateItem を使用することをお勧めします。updateItem メソッドは、入力で指定した項目属性のみを変更し、項目内の他の属性は変更されません。

以下の手順に従ってください:

  1. 操作対象のテーブルを表すために、Table クラスのインスタンスを作成します。

  2. Table インスタンスの updateTable メソッドを呼び出します。変更する属性とその変更方法を記述する UpdateExpression と同時に、取り出す項目のプライマリーキーを指定する必要があります。

次の Java コードスニペットは、前述のタスクの例です。このスニペットでは、ProductCatalog テーブルで書籍項目を更新します。この例では、Authors のセットに著者を追加し、既存の ISBN 属性を削除します。また、価格を 1 引き下げます。

ExpressionAttributeValues マップは UpdateExpression で使用されます。プレースホルダー :val1 および :val2 は、実行時に、Authors と Price の実際の値に置き換えられます。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#A", "Authors"); expressionAttributeNames.put("#P", "Price"); expressionAttributeNames.put("#I", "ISBN"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", new HashSet<String>(Arrays.asList("Author YY","Author ZZ"))); expressionAttributeValues.put(":val2", 1); //Price UpdateItemOutcome outcome = table.updateItem( "Id", // key attribute name 101, // key attribute value "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression expressionAttributeNames, expressionAttributeValues);

オプションパラメータの指定

必須のパラメータに加えて、更新を実行するために満たす必要がある条件も含めて、updateItem メソッドのオプションパラメータを指定することもできます。指定した条件を満たさない場合は、AWS Java SDK が ConditionalCheckFailedExceptionをスローします。たとえば、以下の Java コードスニペットでは、書籍項目の価格を条件付きで 25 に更新します。現在の価格が 20 である場合にのみ価格を更新する必要があることを示す ConditionExpression を指定します。

Copy
Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#P", "Price"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", 25); // update Price to 25... expressionAttributeValues.put(":val2", 20); //...but only if existing Price is 20 UpdateItemOutcome outcome = table.updateItem( new PrimaryKey("Id",101), "set #P = :val1", // UpdateExpression "#P = :val2", // ConditionExpression expressionAttributeNames, expressionAttributeValues);

アトミックカウンター

updateItem を使用してアトミックカウンターを実装できます。アトミックカウンターでは、他の書き込みリクエストを妨げることなく、既存の属性の値をインクリメントまたはデクリメントします。アトミックカウンターをインクリメントするには、UpdateExpression を使用して、set アクションで既存の数値型の属性に数値を加算します。

次のコード例はアトミックカウンターを示しており、Quantity 属性を 1 ずつインクリメントさせています。さらに、UpdateExpression での ExpressionAttributeNames パラメータの使用方法も示します。

Copy
Table table = dynamoDB.getTable("ProductCatalog"); Map<String,String> expressionAttributeNames = new HashMap<String,String>(); expressionAttributeNames.put("#p", "PageCount"); Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", 1); UpdateItemOutcome outcome = table.updateItem( "Id", 121, "set #p = #p + :val", expressionAttributeNames, expressionAttributeValues);

項目の削除

deleteItem メソッドによって、テーブルから項目を削除します。削除する項目のプライマリキーを指定する必要があります。

以下の手順に従ってください:

  1. DynamoDB クライアントのインスタンスを作成します。

  2. 削除する項目のキーを指定して、deleteItem メソッドを呼び出します。

次の Java コードスニペットは、このタスクを示しています。

Copy
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); DeleteItemOutcome outcome = table.deleteItem("Id", 101);

オプションパラメータの指定

deleteItem のオプションパラメータを指定できます。たとえば、次の Java コードスニペットは、ProductCatalog 内の書籍項目は書籍が絶版になった(InPublication 属性が false)場合のみ削除可能であることを示す ConditionExpression を指定します。

Copy
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", false); DeleteItemOutcome outcome = table.deleteItem("Id",103, "InPublication = :val", null, // ExpressionAttributeNames - not used in this example expressionAttributeValues);