使用不可變的資料類別 - AWS SDK for Java 2.x

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

使用不可變的資料類別

DynamoDB 增強型用戶端的映射功能API適用於不可變的資料類別。不可變類別只有 getter,且需要 SDK用來建立類別執行個體的建置器類別。不如客戶類別 所示使用@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 資料表屬性的取得器。

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

  3. 僅必須符合下列其中一項建構條件。

    • 建置器類別必須具有公有預設建構器。

    • 資料類別必須具有名為 的公有靜態方法builder(),該方法不會使用參數,並傳回建置器類別的執行個體。此選項以不可變類別顯示Customer

  4. 建置器類別必須具有名稱為 的公有方法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

第三方程式庫,例如 Project Lombok ,可協助產生與不可變物件相關聯的樣板程式碼。只要資料類別遵循本節中詳述的慣例,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; }