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 的形式回来,因为 "DeleteItem does not recognize any values other than NONE or ALL_OLD"。builder 的 String 重载会把同样的错误藏起来(完整取值)。
  • 清空一张表不是一次 API 调用——DeleteItem 只删一个键,而 SDK 里没有任何东西能删多个。清空表是先 Scan 取键、再批量写入,而且通常不如 DeleteTableCreateTable 划算。

用可视化的方式来做

如果你用来做守卫的属性是保留字,条件就需要一个 # 别名。保留字检查器会告诉你哪些属性名落在 AWS 那份 573 词的清单上,并为命中的那些生成 expressionAttributeNames 映射。

DynoTable 会先把删除暂存到「待提交更改」面板里,然后才让它抵达表。Cmd+Backspace 暂存选中的行,Cmd+Shift+Backspace 一步删除并提交,任何暂存的内容都可以丢弃。下载 DynoTable

相关示例

参考资料

最后核实于 2026-07-28,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。