使用 UpdateItemEnhancedRequest DynamoDb java sdk2 更新特定属性
Update specific attribute using UpdateItemEnhancedRequest DynamoDb java sdk2
我们有一个 DynamoDB table,它有一个属性计数器,多个 lambda 将基于一个事件异步递减。我正在尝试使用 UpdateItemEnhancedRequest 更新计数器(使用 Dynamodb 增强客户端。- JAVA SDK 2)。我能够建立更新计数器的条件,但它会更新整个项目,而不仅仅是计数器。有人可以指导如何使用 DynamoDb 增强客户端更新单个属性吗?
代码示例
public void update(String counter, T item) {
AttributeValue value = AttributeValue.builder().n(counter).build();
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":value", value);
Expression myExpression = Expression.builder()
.expression("nqctr = :value")
.expressionValues(expressionValues)
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(myExpression)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}
更新特定列时,您需要指定要更新的列。假设我们有这个 table:
现在假设我们要更新 archive 列。您需要在代码中指定列。这里我们把key对应的item的archive列改为Closed(单列更新)。请注意,我们使用名为 updatedValues.
的 HashMap 对象指定列名
// Archives an item based on the key
public String archiveItem(String id){
DynamoDbClient ddb = getClient();
HashMap<String,AttributeValue> itemKey = new HashMap<String,AttributeValue>();
itemKey.put("id", AttributeValue.builder()
.s(id)
.build());
HashMap<String, AttributeValueUpdate> updatedValues =
new HashMap<String,AttributeValueUpdate>();
// Update the column specified by name with updatedVal
updatedValues.put("archive", AttributeValueUpdate.builder()
.value(AttributeValue.builder()
.s("Closed").build())
.action(AttributeAction.PUT)
.build());
UpdateItemRequest request = UpdateItemRequest.builder()
.tableName("Work")
.key(itemKey)
.attributeUpdates(updatedValues)
.build();
try {
ddb.updateItem(request);
return"The item was successfully archived";
注意:这不是增强客户端。
此代码来自 AWS 教程,展示了如何使用 Spring Boot 构建 Java Web 应用程序。完整教程在这里:
Creating the DynamoDB web application item tracker
要使用增强型客户端更新单个列,请调用 Table method. This returns a DynamoDbTable instance。现在您可以调用 updateItem 方法。
这是使用增强型客户端更新 archive 列的逻辑。注意你得到一个 Work 对象,调用它的 setArchive 然后传递 Work 对象。 workTable.updateItem(r->r.item(工作));
Java代码:
// Update the archive column by using the Enhanced Client.
public String archiveItemEC(String id) {
DynamoDbClient ddb = getClient();
try {
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
//Get the Key object.
Key key = Key.builder()
.partitionValue(id)
.build();
// Get the item by using the key.
Work work = workTable.getItem(r->r.key(key));
work.setArchive("Closed");
workTable.updateItem(r->r.item(work));
return"The item was successfully archived";
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
此答案显示了更新 DynamoDB 中单个列的两种方法 table。上面的教程现在是这样显示的。
在您原来的解决方案中,您误解了 conditionExpression
属性的含义。这用于验证与键匹配的项目必须为真才能执行更新的条件,而不是执行更新本身的表达式。
有一种方法可以使用增强型客户端执行此操作,而无需在进行更新之前获取对象。 UpdateItemEnhancedRequest
class 有一个 ignoreNulls
attribute 将从更新中排除所有空属性。默认情况下是 false
,这就是导致对象完全覆盖的原因。
我们假设这是您的项目的结构(没有所有增强的客户端注释和样板,您可以添加它们):
class T {
public String partitionKey;
public Int counter;
public String someOtherAttribute
public T(String partitionKey) {
this.partitionKey = partitionKey;
this.counter = null;
this.someOtherAttribute = null
}
}
您可以仅在项目存在时发布计数器更新,如下所示:
public void update(Int counter, String partitionKey) {
T updateItem = new T(partitionKey)
updateItem.counter = counter
Expression itemExistsExpression = Expression.builder()
.expression("attribute_exists(partitionKey)")
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(itemExistsExpression)
.ignoreNulls(true)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}
我们有一个 DynamoDB table,它有一个属性计数器,多个 lambda 将基于一个事件异步递减。我正在尝试使用 UpdateItemEnhancedRequest 更新计数器(使用 Dynamodb 增强客户端。- JAVA SDK 2)。我能够建立更新计数器的条件,但它会更新整个项目,而不仅仅是计数器。有人可以指导如何使用 DynamoDb 增强客户端更新单个属性吗?
代码示例
public void update(String counter, T item) {
AttributeValue value = AttributeValue.builder().n(counter).build();
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":value", value);
Expression myExpression = Expression.builder()
.expression("nqctr = :value")
.expressionValues(expressionValues)
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(myExpression)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}
更新特定列时,您需要指定要更新的列。假设我们有这个 table:
现在假设我们要更新 archive 列。您需要在代码中指定列。这里我们把key对应的item的archive列改为Closed(单列更新)。请注意,我们使用名为 updatedValues.
的 HashMap 对象指定列名// Archives an item based on the key
public String archiveItem(String id){
DynamoDbClient ddb = getClient();
HashMap<String,AttributeValue> itemKey = new HashMap<String,AttributeValue>();
itemKey.put("id", AttributeValue.builder()
.s(id)
.build());
HashMap<String, AttributeValueUpdate> updatedValues =
new HashMap<String,AttributeValueUpdate>();
// Update the column specified by name with updatedVal
updatedValues.put("archive", AttributeValueUpdate.builder()
.value(AttributeValue.builder()
.s("Closed").build())
.action(AttributeAction.PUT)
.build());
UpdateItemRequest request = UpdateItemRequest.builder()
.tableName("Work")
.key(itemKey)
.attributeUpdates(updatedValues)
.build();
try {
ddb.updateItem(request);
return"The item was successfully archived";
注意:这不是增强客户端。
此代码来自 AWS 教程,展示了如何使用 Spring Boot 构建 Java Web 应用程序。完整教程在这里:
Creating the DynamoDB web application item tracker
要使用增强型客户端更新单个列,请调用 Table method. This returns a DynamoDbTable instance。现在您可以调用 updateItem 方法。
这是使用增强型客户端更新 archive 列的逻辑。注意你得到一个 Work 对象,调用它的 setArchive 然后传递 Work 对象。 workTable.updateItem(r->r.item(工作));
Java代码:
// Update the archive column by using the Enhanced Client.
public String archiveItemEC(String id) {
DynamoDbClient ddb = getClient();
try {
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
//Get the Key object.
Key key = Key.builder()
.partitionValue(id)
.build();
// Get the item by using the key.
Work work = workTable.getItem(r->r.key(key));
work.setArchive("Closed");
workTable.updateItem(r->r.item(work));
return"The item was successfully archived";
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
此答案显示了更新 DynamoDB 中单个列的两种方法 table。上面的教程现在是这样显示的。
在您原来的解决方案中,您误解了 conditionExpression
属性的含义。这用于验证与键匹配的项目必须为真才能执行更新的条件,而不是执行更新本身的表达式。
有一种方法可以使用增强型客户端执行此操作,而无需在进行更新之前获取对象。 UpdateItemEnhancedRequest
class 有一个 ignoreNulls
attribute 将从更新中排除所有空属性。默认情况下是 false
,这就是导致对象完全覆盖的原因。
我们假设这是您的项目的结构(没有所有增强的客户端注释和样板,您可以添加它们):
class T {
public String partitionKey;
public Int counter;
public String someOtherAttribute
public T(String partitionKey) {
this.partitionKey = partitionKey;
this.counter = null;
this.someOtherAttribute = null
}
}
您可以仅在项目存在时发布计数器更新,如下所示:
public void update(Int counter, String partitionKey) {
T updateItem = new T(partitionKey)
updateItem.counter = counter
Expression itemExistsExpression = Expression.builder()
.expression("attribute_exists(partitionKey)")
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(itemExistsExpression)
.ignoreNulls(true)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}