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

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

控制属性转换

默认情况下,表架构通过AttributeConverterProvider接口的默认实现为许多常见的 Java 类型提供转换器。您可以使用自定义 AttributeConverterProvider 实现来更改整体默认行为。您还可以更改单个属性的转换器。

有关可用转换器的列表,请参阅AttributeConverter接口 Java 文档。

提供自定义属性转换器提供程序

您可以通过 @DynamoDbBean (converterProviders = {…}) 注释提供单个 AttributeConverterProvider 或一个有序的 AttributeConverterProvider 链。任何自定义 AttributeConverterProvider 都必须扩展 AttributeConverterProvider 接口。

请注意,如果您提供自己的属性转换器提供程序链,则将覆盖默认的转换器提供程序 DefaultAttributeConverterProvider。如果您要使用 DefaultAttributeConverterProvider 的功能,必须将其包含在链中。

也可以用空 {} 数组对 Bean 进行注释。这将禁用任何属性转换器提供程序,包括默认提供程序。在这种情况下,所有要映射的属性都必须有自己的属性转换器。

以下代码段显示了单个转换器提供程序。

@DynamoDbBean(converterProviders = ConverterProvider1.class) public class Customer { }

以下代码段显示了转换器提供程序链的用法。由于最后提供了SDK默认值,因此它的优先级最低。

@DynamoDbBean(converterProviders = { ConverterProvider1.class, ConverterProvider2.class, DefaultAttributeConverterProvider.class}) public class Customer { }

静态表架构生成器有一种工作方式与此相同的 attributeConverterProviders() 方法。如以下代码段所示。

private static final StaticTableSchema<Customer> CUSTOMER_TABLE_SCHEMA = StaticTableSchema.builder(Customer.class) .newItemSupplier(Customer::new) .addAttribute(String.class, a -> a.name("name") a.getter(Customer::getName) a.setter(Customer::setName)) .attributeConverterProviders(converterProvider1, converterProvider2) .build();

覆盖单个属性的映射

要覆盖单个属性的映射方式,请为该属性提供一个 AttributeConverter。此添加会覆盖表架构中由 AttributeConverterProviders 提供的任何转换器。这将仅为该属性添加一个自定义转换器。除非为其他属性明确指定该转换器,否则其他属性即使类型相同,也不会使用该转换器。

@DynamoDbConvertedBy 注释用于指定自定义 AttributeConverter 类,如以下代码段所示。

@DynamoDbBean public class Customer { private String name; @DynamoDbConvertedBy(CustomAttributeConverter.class) public String getName() { return this.name; } public void setName(String name) { this.name = name;} }

静态架构的生成器具有等效的属性生成器 attributeConverter() 方法。此方法采用 AttributeConverter 的实例,如下所示。

private static final StaticTableSchema<Customer> CUSTOMER_TABLE_SCHEMA = StaticTableSchema.builder(Customer.class) .newItemSupplier(Customer::new) .addAttribute(String.class, a -> a.name("name") a.getter(Customer::getName) a.setter(Customer::setName) a.attributeConverter(customAttributeConverter)) .build();

示例

此示例演示一个为 java.net.HttpCookie 对象提供属性转换器的 AttributeConverterProvider 实现。

以下 SimpleUser 类包含一个名为 lastUsedCookie 的属性,该属性是 HttpCookie 的一个实例。

@DynamoDbBean 注释的参数列出了提供转换器的两个 AttributeConverterProvider 类。

Class with annotations
@DynamoDbBean(converterProviders = {CookieConverterProvider.class, DefaultAttributeConverterProvider.class}) public static final class SimpleUser { private String name; private HttpCookie lastUsedCookie; @DynamoDbPartitionKey public String getName() { return name; } public void setName(String name) { this.name = name; } public HttpCookie getLastUsedCookie() { return lastUsedCookie; } public void setLastUsedCookie(HttpCookie lastUsedCookie) { this.lastUsedCookie = lastUsedCookie; }
Static table schema
private static final TableSchema<SimpleUser> SIMPLE_USER_TABLE_SCHEMA = TableSchema.builder(SimpleUser.class) .newItemSupplier(SimpleUser::new) .attributeConverterProviders(CookieConverterProvider.create(), AttributeConverterProvider.defaultProvider()) .addAttribute(String.class, a -> a.name("name") .setter(SimpleUser::setName) .getter(SimpleUser::getName) .tags(StaticAttributeTags.primaryPartitionKey())) .addAttribute(HttpCookie.class, a -> a.name("lastUsedCookie") .setter(SimpleUser::setLastUsedCookie) .getter(SimpleUser::getLastUsedCookie)) .build();

以下示例中的 CookieConverterProvider 提供了 HttpCookeConverter 的一个实例。

public static final class CookieConverterProvider implements AttributeConverterProvider { private final Map<EnhancedType<?>, AttributeConverter<?>> converterCache = ImmutableMap.of( // 1. Add HttpCookieConverter to the internal cache. EnhancedType.of(HttpCookie.class), new HttpCookieConverter()); public static CookieConverterProvider create() { return new CookieConverterProvider(); } // The SDK calls this method to find out if the provider contains a AttributeConverter instance // for the EnhancedType<T> argument. @SuppressWarnings("unchecked") @Override public <T> AttributeConverter<T> converterFor(EnhancedType<T> enhancedType) { return (AttributeConverter<T>) converterCache.get(enhancedType); } }

代码转换

在以下 HttpCookieConverter 类的 transformFrom() 方法中,代码接收一个 HttpCookie 实例并将其转换为 DynamoDB 映射,并将该映射作为属性存储。

transformTo() 方法接收 DynamoDB 映射参数,然后调用需要名称和值的 HttpCookie 构造函数。

public static final class HttpCookieConverter implements AttributeConverter<HttpCookie> { @Override public AttributeValue transformFrom(HttpCookie httpCookie) { return AttributeValue.fromM( Map.of ("cookieName", AttributeValue.fromS(httpCookie.getName()), "cookieValue", AttributeValue.fromS(httpCookie.getValue())) ); } @Override public HttpCookie transformTo(AttributeValue attributeValue) { Map<String, AttributeValue> map = attributeValue.m(); return new HttpCookie( map.get("cookieName").s(), map.get("cookieValue").s()); } @Override public EnhancedType<HttpCookie> type() { return EnhancedType.of(HttpCookie.class); } @Override public AttributeValueType attributeValueType() { return AttributeValueType.M; } }