Java(AWS SDK v2)中的 DynamoDB DeleteItem
在 AWS SDK for Java 2.x 里,一次删除就是一个携带完整主键的 DeleteItemRequest,而 ReturnValue.ALL_OLD 会告诉你那里到底有没有东西。
给下面的代码加一个 conditionExpression,它就会长出一个照样能编译的 bug。代码块下面的第一条要点讲的就是这个 bug。
代码
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.DeleteItemRequest;
import software.amazon.awssdk.services.dynamodb.model.DeleteItemResponse;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ReturnValue;
public class DeleteItemExample {
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());
DeleteItemRequest request = DeleteItemRequest.builder()
.tableName("Music")
.key(key)
.returnValues(ReturnValue.ALL_OLD)
.build();
DeleteItemResponse response = ddb.deleteItem(request);
if (response.attributes().isEmpty()) {
System.out.println("No item with that key existed");
} else {
System.out.println("Deleted: " + response.attributes());
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}说明
ConditionalCheckFailedException继承自DynamoDbException——所以上面那个catch块会吞掉一次失败的守卫条件,还把它当成服务出故障打印出来。一旦请求带上了conditionExpression,就要先捕获更窄的那个类型。一个起了作用的条件是一种结果,不是错误。- 异常里带着落败的那个项目——在请求上加
returnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD),e.item()就会把 DynamoDB 眼中的那一行交还给你。AWS 明说了价格:"No read capacity units are consumed." attributes()永远不会返回null——什么都没匹配到的删除会给出一个空映射,所以用isEmpty()来判断。hasAttributes()区分的是「服务什么都没返回」和「服务返回了一个空映射」。ReturnValue枚举是和UpdateItem共用的——returnValues(ReturnValue.ALL_NEW)在这里能编译通过,然后以ValidationException的形式回来,因为 "DeleteItemdoes not recognize any values other thanNONEorALL_OLD"。builder 的String重载会把同样的错误藏起来(完整取值)。- 清空一张表不是一次 API 调用——
DeleteItem只删一个键,而 SDK 里没有任何东西能删多个。清空表是先Scan取键、再批量写入,而且通常不如DeleteTable加CreateTable划算。
用可视化的方式来做
如果你用来做守卫的属性是保留字,条件就需要一个 # 别名。保留字检查器会告诉你哪些属性名落在 AWS 那份 573 词的清单上,并为命中的那些生成 expressionAttributeNames 映射。
DynoTable 会先把删除暂存到「待提交更改」面板里,然后才让它抵达表。Cmd+Backspace 暂存选中的行,Cmd+Shift+Backspace 一步删除并提交,任何暂存的内容都可以丢弃。下载 DynoTable。
相关示例
- Go 中的 DynamoDB DeleteItem——用 AWS SDK for Go v2 做同样的删除。
- Java 中的 DynamoDB PutItem——同一个键的写入侧。
- DynamoDB 条件表达式——用
attribute_exists和值检查为删除加上守卫。 - DynamoDB ConditionalCheckFailedException——一次失败的条件删除会抛出什么,以及什么时候这是预期之中的。
参考资料
- DeleteItem — Amazon DynamoDB API Reference
- Use DeleteItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- DynamoDbClient — AWS SDK for Java 2.x API Reference
- DeleteItemRequest — AWS SDK for Java 2.x API Reference
- ConditionalCheckFailedException — AWS SDK for Java 2.x API Reference
- Condition expressions — Amazon DynamoDB Developer Guide
最后核实于 2026-07-28,依据上方链接的 AWS 官方文档。