我正在使用来自AWS Java SDK的DynamoDBMapper,并使用一个相当简单的项目:它有一个字符串属性(用作哈希键)和一个map属性。
@DynamoDBTable(tableName = "MyTable")
public class MyItem {
private String myStringAttr;
private Map<String, String> myMapAttr;
@DynamoDBHashKey(attributeName = "MyStringAttribute")
public String getMyKeyAttr() { return myKeyAttr; }
public void setMyKeyAttr(String myKeyAttr) { this.myKeyAttr = myKeyAttr; }
@DynamoDBAttribute(attributeName = "MyMapAttribute")
public Map<String, String> getMyMapAttr() { return myMapAttr; }
public void setMyMapAttr(Map<string, string> myMapAttr) { this.myMapAttr = myMapAttr; }
}
我可以使用load()
和save()
方法读取和写入我的对象。我遇到的问题是当我需要在地图中为表中的现有项目更新或添加单个条目时。在不知道所述项目的地图现有条目的情况下(我不想每次在尝试更新或添加之前都执行load()
),我似乎能做的最好的事情就是清除整个地图并将其替换为我尝试更新或添加的单个条目。 是否可以使用 DynamoDBMapper 向现有项目的映射属性添加/更新单个条目?
我查看了DynamoDBSaveExpression
和DynamoDBMapperConfig
提供的各种选项。我能找到的最接近的选项是 DynamoDBMapperConfig.SaveBehavior.APPEND_SET
,但这适用于设置类型属性,而不是我正在使用的地图类型。
我能够使用文档 API 的 updateItem()
方法以及包含 UpdateExpression 的UpdateItemSpec
来实现这个确切的用例,如下所示。如果给定的键尚不存在,这将向映射添加一个新条目,或者如果现有条目确实存在,则将值更新为特定条目,所有这些都不会触及映射中的其他条目。但是,我发现文档 API 使用起来相当麻烦,如果可能的话,我更愿意坚持使用DynamoDBMapper
。
Table table = dynamoDB.getTable("MyTable");
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey("MyStringAttribute", 1)
.withUpdateExpression("set #mma.#mek = :mev")
.withNameMap(new NameMap()
.with("#mma", "MyMapAttribute")
.with("#mek", "SomeMapEntryKey")
.withValueMap(new ValueMap()
.withString(":mev", "Some map entry value"));
UpdateItemOutcome outcome = table.updateItem(updateItemSpec);
一种可能的解决方案是:-
1) 使用 DynamoDBMapper 加载从表"MyTable"中获取数据
2) 在步骤 1 中检索到的对象中向映射添加新条目,并使用带有配置的 DynamoDBMapper 保存该对象,如下所述
DynamoDBMapperConfig dynamoDBMapperConfig = new DynamoDBMapperConfig(SaveBehavior.UPDATE);
我知道这是一个两步过程。但是,当我遇到同样的情况时,我尝试了很多,但找不到任何使用 DynamoDBMapper 直接更新"地图"数据类型的解决方案。
希望这有帮助!