扁平化其他类的属性 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

扁平化其他类的属性

如果表的属性通过继承或组合分布在多个不同的 Java 类中,则 DynamoDB 增强版API客户端支持将这些属性扁平化为一个类。

使用继承

如果您的类使用继承,请使用以下方法来扁平化层次结构。

使用带注释的 Bean

对于注释方法,两个类都必须带有 @DynamoDbBean 注释,并且一个类必须带有一个或多个主键注释。

以下是具有继承关系的数据类的示例。

Standard data class
@DynamoDbBean public class Customer extends GenericRecord { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @DynamoDbBean public abstract class GenericRecord { private String id; private String createdDate; @DynamoDbPartitionKey public String getId() { return id; } public void setId(String id) { this.id = id; } public String getCreatedDate() { return createdDate; } public void setCreatedDate(String createdDate) { this.createdDate = createdDate; } }
Lombok

Lombok 的 onMethod 选项将基于属性的 DynamoDB 注释(例如 @DynamoDbPartitionKey)复制到生成的代码中。

@DynamoDbBean @Data @ToString(callSuper = true) public class Customer extends GenericRecord { private String name; } @Data @DynamoDbBean public abstract class GenericRecord { @Getter(onMethod_=@DynamoDbPartitionKey) private String id; private String createdDate; }

使用静态架构

对于静态架构方法,使用生成器的 extend() 方法将父类的属性折叠到子类上。如以下示例的注释行 1 之后所示。

StaticTableSchema<org.example.tests.model.inheritance.stat.GenericRecord> GENERIC_RECORD_SCHEMA = StaticTableSchema.builder(org.example.tests.model.inheritance.stat.GenericRecord.class) // The partition key will be inherited by the top level mapper. .addAttribute(String.class, a -> a.name("id") .getter(org.example.tests.model.inheritance.stat.GenericRecord::getId) .setter(org.example.tests.model.inheritance.stat.GenericRecord::setId) .tags(primaryPartitionKey())) .addAttribute(String.class, a -> a.name("created_date") .getter(org.example.tests.model.inheritance.stat.GenericRecord::getCreatedDate) .setter(org.example.tests.model.inheritance.stat.GenericRecord::setCreatedDate)) .build(); StaticTableSchema<org.example.tests.model.inheritance.stat.Customer> CUSTOMER_SCHEMA = StaticTableSchema.builder(org.example.tests.model.inheritance.stat.Customer.class) .newItemSupplier(org.example.tests.model.inheritance.stat.Customer::new) .addAttribute(String.class, a -> a.name("name") .getter(org.example.tests.model.inheritance.stat.Customer::getName) .setter(org.example.tests.model.inheritance.stat.Customer::setName)) // 1. Use the extend() method to collapse the parent attributes onto the child class. .extend(GENERIC_RECORD_SCHEMA) // All the attributes of the GenericRecord schema are added to Customer. .build();

前面的静态架构示例使用以下数据类。由于映射是在构建静态表架构时定义的,因此数据类不需要注释。

Standard data class
public class Customer extends GenericRecord { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public abstract class GenericRecord { private String id; private String createdDate; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getCreatedDate() { return createdDate; } public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
Lombok
@Data @ToString(callSuper = true) public class Customer extends GenericRecord{ private String name; } @Data public abstract class GenericRecord { private String id; private String createdDate; }

使用组合

如果您的类使用组合,请使用以下方法来扁平化层次结构。

使用带注释的 Bean

使用 @DynamoDbFlatten 注释将所含的类扁平化。

以下数据类示例使用 @DynamoDbFlatten 注释将所含的 GenericRecord 类的所有属性有效添加到 Customer 类中。

Standard data class
@DynamoDbBean public class Customer { private String name; private GenericRecord record; public String getName() { return this.name; } public void setName(String name) { this.name = name; } @DynamoDbFlatten public GenericRecord getRecord() { return this.record; } public void setRecord(GenericRecord record) { this.record = record; } @DynamoDbBean public class GenericRecord { private String id; private String createdDate; @DynamoDbPartitionKey public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getCreatedDate() { return this.createdDate; } public void setCreatedDate(String createdDate) { this.createdDate = createdDate; } }
Lombok
@Data @DynamoDbBean public class Customer { private String name; @Getter(onMethod_=@DynamoDbFlatten) private GenericRecord record; } @Data @DynamoDbBean public class GenericRecord { @Getter(onMethod_=@DynamoDbPartitionKey) private String id; private String createdDate; }

您可以根据需要,使用扁平化注释对任意数量的符合条件的不同类进行扁平化。以下限制适用:

  • 所有属性名称在扁平化后必须是唯一的。

  • 分区键、排序键或表名称不得超过一个。

使用静态架构

构建静态表架构时,请使用生成器的 flatten() 方法。您还可以提供用于识别所含类的 getter 和 setter 方法。

StaticTableSchema<GenericRecord> GENERIC_RECORD_SCHEMA = StaticTableSchema.builder(GenericRecord.class) .newItemSupplier(GenericRecord::new) .addAttribute(String.class, a -> a.name("id") .getter(GenericRecord::getId) .setter(GenericRecord::setId) .tags(primaryPartitionKey())) .addAttribute(String.class, a -> a.name("created_date") .getter(GenericRecord::getCreatedDate) .setter(GenericRecord::setCreatedDate)) .build(); StaticTableSchema<Customer> CUSTOMER_SCHEMA = StaticTableSchema.builder(Customer.class) .newItemSupplier(Customer::new) .addAttribute(String.class, a -> a.name("name") .getter(Customer::getName) .setter(Customer::setName)) // Because we are flattening a component object, we supply a getter and setter so the // mapper knows how to access it. .flatten(GENERIC_RECORD_SCHEMA, Customer::getRecord, Customer::setRecord) .build();

前面的静态架构示例使用以下数据类。

Standard data class
public class Customer { private String name; private GenericRecord record; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public GenericRecord getRecord() { return this.record; } public void setRecord(GenericRecord record) { this.record = record; } public class GenericRecord { private String id; private String createdDate; public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getCreatedDate() { return this.createdDate; } public void setCreatedDate(String createdDate) { this.createdDate = createdDate; } }
Lombok
@Data public class Customer { private String name; private GenericRecord record; } @Data public class GenericRecord { private String id; private String createdDate; }

您可以根据需要,使用生成器模式对任意数量的符合条件的不同类进行扁平化。

对其他代码的影响

当您使用 @DynamoDbFlatten 属性(或 flatten() 生成器方法)时,DynamoDB 中的项目将针对组合成的对象的每个属性包含一个属性。它还包括进行组合的对象的属性。

相反,如果您使用组合成的类对数据类进行注释但不使用 @DynamoDbFlatten,则该项目将与组合成的对象一起保存为单个属性。

例如,我们可以比较使用组合的扁平化示例中显示的 Customer 类在对 record 属性进行扁平化和不进行扁平化时的区别。您可以使用可视化差异JSON,如下表所示。

进行扁平化 不进行扁平化
3 个属性 2 个属性
{ "id": "1", "createdDate": "today", "name": "my name" }
{ "id": "1", "record": { "createdDate": "today", "name": "my name" } }

如果您有其他代码访问 DynamoDB 表并希望找到某些属性,则此区别就变得很重要。