Java(AWS SDK v2)中的 DynamoDB GetItem
AWS SDK for Java 2.x 把一个项建模成通过不可变构建器组装出来的 Map<String, AttributeValue>。它有两个约定和大多数 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——没命中时返回的是一个空 map,所以判断方式是isEmpty()。要把"服务什么都没返回"和"服务返回了一个空 map"区分开,就调用hasItem();SDK 会自动构造空集合,而hasItem()是唯一能看穿这一点的东西。- 它交给你的那个 map 是不可变的——Javadoc 明确说修改它会抛
UnsupportedOperationException。打算改的话,先拷进一个HashMap。 - 本地没有任何东西会校验别名映射——
expressionAttributeNames就是一个普通的Map<String, String>。这里#proj3是必需的,因为Year是保留字;而声明了却从不引用的别名,是另一种服务端错误:"Value provided in ExpressionAttributeNames unused in expressions"。 - 整个应用共用一个客户端——AWS 说得很直白:"Service clients in the AWS SDK for Java 2.x are thread-safe." try-with-resources 这种写法适合一次性的
main;在长期运行的服务里,请在启动时构建客户端,并且不要每个请求都关一次。 .consistentRead(true)会让读取成本翻倍,而且在 GSI 上会被拒绝。如果你写腻了AttributeValue映射,那就用 DynamoDB 增强客户端(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——读整个分区,而不是单个项。
- 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 官方文档。