控制属性转换 - AWS SDK for Java 2.x

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

控制属性转换

默认情况下,表架构通过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; } }