使用 @DynamoDbPreserveEmptyObject 保留空对象 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 @DynamoDbPreserveEmptyObject 保留空对象

如果您将包含空对象的 Bean 保存到 Amazon DynamoDB 中,并且希望 SDK 在检索时重新创建空对象,请使用 @DynamoDbPreserveEmptyObject 注释内部 Bean 的 getter。

为了说明该注释的工作原理,代码示例使用了以下两个 Bean。

以下数据类包含两个 InnerBean 字段。getter 方法 getInnerBeanWithoutAnno() 不使用 @DynamoDbPreserveEmptyObject 注释。getInnerBeanWithAnno() 方法使用注释。

@DynamoDbBean public class MyBean { private String id; private String name; private InnerBean innerBeanWithoutAnno; private InnerBean innerBeanWithAnno; @DynamoDbPartitionKey public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public InnerBean getInnerBeanWithoutAnno() { return innerBeanWithoutAnno; } public void setInnerBeanWithoutAnno(InnerBean innerBeanWithoutAnno) { this.innerBeanWithoutAnno = innerBeanWithoutAnno; } @DynamoDbPreserveEmptyObject public InnerBean getInnerBeanWithAnno() { return innerBeanWithAnno; } public void setInnerBeanWithAnno(InnerBean innerBeanWithAnno) { this.innerBeanWithAnno = innerBeanWithAnno; } @Override public String toString() { return new StringJoiner(", ", MyBean.class.getSimpleName() + "[", "]") .add("innerBeanWithoutAnno=" + innerBeanWithoutAnno) .add("innerBeanWithAnno=" + innerBeanWithAnno) .add("id='" + id + "'") .add("name='" + name + "'") .toString(); } }

以下 InnerBean 类的实例是 MyBean 的字段,并且在示例代码中被初始化为空对象。

@DynamoDbBean public class InnerBean { private String innerBeanField; public String getInnerBeanField() { return innerBeanField; } public void setInnerBeanField(String innerBeanField) { this.innerBeanField = innerBeanField; } @Override public String toString() { return "InnerBean{" + "innerBeanField='" + innerBeanField + '\'' + '}'; } }

以下代码示例将带有初始化内部 Bean 的 MyBean 对象保存到 DynamoDB,然后检索该项目。记录的输出显示 innerBeanWithoutAnno 未初始化,但已创建 innerBeanWithAnno

public MyBean preserveEmptyObjectAnnoUsingGetItemExample(DynamoDbTable<MyBean> myBeanTable) { // Save an item to DynamoDB. MyBean bean = new MyBean(); bean.setId("1"); bean.setInnerBeanWithoutAnno(new InnerBean()); // Instantiate the inner bean. bean.setInnerBeanWithAnno(new InnerBean()); // Instantiate the inner bean. myBeanTable.putItem(bean); GetItemEnhancedRequest request = GetItemEnhancedRequest.builder() .key(Key.builder().partitionValue("1").build()) .build(); MyBean myBean = myBeanTable.getItem(request); logger.info(myBean.toString()); // Output 'MyBean[innerBeanWithoutAnno=null, innerBeanWithAnno=InnerBean{innerBeanField='null'}, id='1', name='null']'. return myBean; }

您可以使用以下 StaticTableSchema 版本的表架构来代替 Bean 上的注释。

public static TableSchema<MyBean> buildStaticSchemas() { StaticTableSchema<InnerBean> innerBeanStaticTableSchema = StaticTableSchema.builder(InnerBean.class) .newItemSupplier(InnerBean::new) .addAttribute(String.class, a -> a.name("innerBeanField") .getter(InnerBean::getInnerBeanField) .setter(InnerBean::setInnerBeanField)) .build(); return StaticTableSchema.builder(MyBean.class) .newItemSupplier(MyBean::new) .addAttribute(String.class, a -> a.name("id") .getter(MyBean::getId) .setter(MyBean::setId) .addTag(primaryPartitionKey())) .addAttribute(String.class, a -> a.name("name") .getter(MyBean::getName) .setter(MyBean::setName)) .addAttribute(EnhancedType.documentOf(InnerBean.class, innerBeanStaticTableSchema), a -> a.name("innerBean1") .getter(MyBean::getInnerBeanWithoutAnno) .setter(MyBean::setInnerBeanWithoutAnno)) .addAttribute(EnhancedType.documentOf(InnerBean.class, innerBeanStaticTableSchema, b -> b.preserveEmptyObject(true)), a -> a.name("innerBean2") .getter(MyBean::getInnerBeanWithAnno) .setter(MyBean::setInnerBeanWithAnno)) .build(); }