

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

# 使用不可變的資料類別
<a name="ddb-en-client-use-immut"></a>

DynamoDB 增強型用戶端 API 的映射功能適用於不可變的資料類別。不可變類別只有取得器，且需要 SDK 用來建立類別執行個體的建置器類別。不像[客戶類別](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust)中所示使用`@DynamoDbBean`註釋，不可變類別會使用`@DynamoDbImmutable`註釋，這會採用參數來指示要使用的建置器類別。

下列類別是 的不可變版本`Customer`。

```
package org.example.tests.model.immutable;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbImmutable(builder = CustomerImmutable.Builder.class)
public class CustomerImmutable {
    private final String id;
    private final String name;
    private final String email;
    private final Instant regDate;

    private CustomerImmutable(Builder b) {
        this.id = b.id;
        this.email = b.email;
        this.name = b.name;
        this.regDate = b.regDate;
    }

    // This method will be automatically discovered and used by the TableSchema.
    public static Builder builder() { return new Builder(); }

    @DynamoDbPartitionKey
    public String id() { return this.id; }

    @DynamoDbSortKey
    public String email() { return this.email; }

    @DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name")
    public String name() { return this.name; }

    @DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"})
    public Instant regDate() { return this.regDate; }

    public static final class Builder {
        private String id;
        private String email;
        private String name;
        private Instant regDate;

        // The private Builder constructor is visible to the enclosing CustomerImmutable class.
        private Builder() {}

        public Builder id(String id) { this.id = id; return this; }
        public Builder email(String email) { this.email = email; return this; }
        public Builder name(String name) { this.name = name; return this; }
        public Builder regDate(Instant regDate) { this.regDate = regDate; return this; }

        // This method will be automatically discovered and used by the TableSchema.
        public CustomerImmutable build() { return new CustomerImmutable(this); }
    }
}
```

當您使用 註釋資料類別時，必須符合下列要求`@DynamoDbImmutable`。

1. 不是 覆寫`Object.class`且尚未加上註釋的每個方法，`@DynamoDbIgnore`都必須是 DynamoDB 資料表屬性的 getter。

1. 每個 getter 在建置器類別上都必須有對應的區分大小寫設定器。

1. 僅必須符合下列其中一項建構條件。
   + 建置器類別必須具有公有預設建構函數。
   + 資料類別必須具有名為 的公有靜態方法`builder()`，不採用任何參數，並傳回建置器類別的執行個體。此選項會顯示在不可變類別中`Customer`。

1.  建置器類別必須具有名為 的公有方法`build()`，不採用任何參數，並傳回不可變類別的執行個體。

若要`TableSchema`為您的不可變類別建立 ，請使用 上的 `fromImmutableClass()`方法`TableSchema`，如下列程式碼片段所示。

```
static final TableSchema<CustomerImmutable> customerImmutableTableSchema = 
                         TableSchema.fromImmutableClass(CustomerImmutable.class);
```

就像您可以從可變類別建立 DynamoDB 資料表一樣，您可以從不可變類別建立一個資料表，並對 `createTable()` 進行*一次性*呼叫`DynamoDbTable`，如下列程式碼片段範例所示。

```
static void createTableFromImmutable(DynamoDbEnhancedClient enhancedClient, String tableName, DynamoDbWaiter waiter){
    // First, create an in-memory representation of the table using the 'table()' method of the DynamoDb Enhanced Client.
    // 'table()' accepts a name for the table and a TableSchema instance that you created previously.
    DynamoDbTable<CustomerImmutable> customerDynamoDbTable = enhancedClient
            .table(tableName, TableSchema.fromImmutableClass(CustomerImmutable.class));
        
    // Second, call the 'createTable()' method on the DynamoDbTable instance.
    customerDynamoDbTable.createTable();
    waiter.waitUntilTableExists(b -> b.tableName(tableName));
}
```

## 使用第三方程式庫，例如 Lombok
<a name="ddb-en-client-use-immut-lombok"></a>

第三方程式庫，例如 [Project Lombok](https://projectlombok.org/)，可協助產生與不可變物件相關聯的樣板程式碼。只要資料類別遵循本節中詳述的慣例，DynamoDB 增強型用戶端 API 就會使用這些程式庫。

下列範例顯示具有 Lombok 註釋的不可變`CustomerImmutable`類別。請注意，Lombok `onMethod`的功能如何將屬性型 DynamoDB 註釋，例如 `@DynamoDbPartitionKey`，複製到產生的程式碼。

```
@Value
@Builder
@DynamoDbImmutable(builder = Customer.CustomerBuilder.class)
public class Customer {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;

    @Getter(onMethod_=@DynamoDbSortKey)
    private String email;

    @Getter(onMethod_=@DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name"))
    private String name;

    @Getter(onMethod_=@DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"}))
    private Instant createdDate;
}
```