Java (AWS SDK v2) での DynamoDB GetItem
AWS SDK for Java 2.x はアイテムを、イミュータブルなビルダーで組み立てる Map<String, AttributeValue> としてモデル化します。その慣習のうち 2 つが他の多くの SDK と異なります。数値が文字列として型付けされることと、レスポンスのコレクションが決して null にならないことです。
リクエスト自体には、他と同じく完全なプライマリキーが必要です。
コード
import java.util.HashMap;
import java.util.Map;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
public class GetItemExample {
public static void main(String[] args) {
try (DynamoDbClient ddb = DynamoDbClient.builder()
.region(Region.US_EAST_1)
.build()) {
Map<String, AttributeValue> key = new HashMap<>();
key.put("Artist", AttributeValue.builder().s("Arturo Sandoval").build());
key.put("SongTitle", AttributeValue.builder().s("Cubano Chant").build());
Map<String, String> names = new HashMap<>();
names.put("#proj0", "Artist");
names.put("#proj1", "SongTitle");
names.put("#proj2", "AlbumTitle");
names.put("#proj3", "Year");
GetItemRequest request = GetItemRequest.builder()
.tableName("Music")
.key(key)
.projectionExpression("#proj0, #proj1, #proj2, #proj3")
.expressionAttributeNames(names)
.build();
Map<String, AttributeValue> item = ddb.getItem(request).item();
if (item.isEmpty()) {
System.out.println("Item not found");
} else {
System.out.println(item);
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}解説
n()はStringを取ります。AttributeValue.builder().n(1994)はコンパイルできません。Javadoc が理由を述べています: "Numbers are sent across the network to DynamoDB as strings, to maximize compatibility across languages and libraries." つまりn("1994")であり、戻ってきたときのパースは自分の仕事です。item()は決してnullを返しません。見つからない場合は空のマップになるので、判定はisEmpty()です。「サービスが何も返さなかった」と「サービスが空のマップを返した」を区別したいならhasItem()を呼びます。SDK は空のコレクションを自動生成するので、それを見通せるのはhasItem()だけです。- 返ってくるマップはイミュータブルです。Javadoc は、これを変更すると
UnsupportedOperationExceptionが投げられると明記しています。編集する予定があるなら、まずHashMapにコピーしましょう。 - エイリアスのマップをローカルで検証するものは何もありません。
expressionAttributeNamesはただのMap<String, String>です。ここで#proj3が必要なのはYearが予約語だからで、宣言したのに一度も参照しないエイリアスはそれ自体がサービス側のエラーになります: 「Value provided in ExpressionAttributeNames unused in expressions」。 - アプリケーション全体でクライアントは 1 つ。AWS は端的にこう述べています: "Service clients in the AWS SDK for Java 2.x are thread-safe." try-with-resources のブロックは一発きりの
mainには合いますが、長時間動くサービスでは起動時にクライアントを作り、リクエストごとに閉じないでください。 .consistentRead(true)は読み取りコストを 2 倍にし、GSI では拒否されます。AttributeValueのマップが煩わしくなってきたときは DynamoDB Enhanced Client(software.amazon.awssdk.enhanced.dynamodb)の出番で、これと同じ低レベル呼び出しの上でアイテムをアノテーション付きの Bean にマッピングします。
ビジュアルに行う
この読み取りが 0.5 キャパシティユニットで済むか 1 になるかは、アイテムが 4 KB に収まるかどうか次第です。アイテムサイズ計算ツールは、貼り付けたアイテムをその境界に照らして測ります。
DynoTable は同じアイテムを普通の行として表示し、グリッドの裏にあるクエリを、これらのビルダーで組み立てた Java プログラムとしてエクスポートします。DynoTable をダウンロード。
関連する例
- Go での DynamoDB GetItem — AWS SDK for Go v2 での同じ読み取り。
- Java での DynamoDB Query — 1 アイテムではなくパーティション全体を読む。
- DynamoDB のパーティションキーの仕組み —
GetItemに完全なキーが必要な理由。 - DynamoDB ResourceNotFoundException — ここで最初に出る定番のエラー: テーブル名かリージョンの間違い。
- 「The provided key element does not match the schema」 — 渡したキーがテーブルのキースキーマと一致していない。
参考資料
- GetItem — Amazon DynamoDB API Reference
- Use GetItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- DynamoDbClient — AWS SDK for Java 2.x API Reference
- GetItemRequest — AWS SDK for Java 2.x API Reference
- Read consistency — Amazon DynamoDB Developer Guide
- Use singleton service client instances with the AWS SDK for Java 2.x
最終検証日 2026-07-28、上記にリンクした公式 AWS ドキュメントに照らして確認しました。