

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 控制屬性轉換
<a name="ddb-en-client-adv-features-conversion"></a>

根據預設，資料表結構描述會透過 `[AttributeConverterProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverterProvider.html)` 介面的預設實作，為許多常見的 Java 類型提供轉換器。您可以使用自訂 `AttributeConverterProvider` 實作變更整體預設行為。您也可以變更單一屬性的轉換器。

如需可用轉換器的清單，請參閱 [AttributeConverter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) 介面 Java 文件。

## 提供自訂屬性轉換器提供者
<a name="ddb-en-client-adv-features-conversion-prov"></a>

您可以透過 `AttributeConverterProvider``@DynamoDbBean``(converterProviders = {…})`註釋提供單一`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();
```

## 覆寫單一屬性的映射
<a name="ddb-en-client-adv-features-conversion-single"></a>

若要覆寫單一屬性的映射方式，請提供 屬性`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();
```

## 範例
<a name="ddb-en-client-adv-features-conversion-example"></a>

此範例顯示為[https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpCookie.html](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpCookie.html)物件提供屬性轉換器的`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);
        }
    }
```

### 轉換程式碼
<a name="ddb-en-client-adv-features-conversion-example-code"></a>

在下列`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;
        }
    }
```