扁平化其他类的属性 - AWS SDK for Java 2.x

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

扁平化其他类的属性

如果表的属性通过继承或组合分布在多个不同的 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 表并希望找到某些属性,则此区别就变得很重要。