Trabalhar com classes de dados imutáveis - AWS SDK for Java 2.x

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Trabalhar com classes de dados imutáveis

O atributo de mapeamento da API do Cliente Aprimorado do DynamoDB funciona com classes de dados imutáveis. Uma classe imutável tem apenas getters e requer uma classe construtora que o SDK usa para criar instâncias da classe. Em vez de usar a anotação @DynamoDbBean conforme mostrado na classe Customer, as classes imutáveis usam a anotação @DynamoDbImmutable, a qual usa um parâmetro que indica a classe do construtor a ser usada.

A classe a seguir é uma versão imutável de 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); } } }

Você deve atender aos seguintes requisitos ao anotar uma classe de dados com @DynamoDbImmutable.

  1. Todo método que não é uma substituição de Object.class e não foi anotado com @DynamoDbIgnore deve ser um getter de um atributo da tabela do DynamoDB.

  2. Cada getter deve ter um setter correspondente com distinção entre maiúsculas e minúsculas na classe builder.

  3. Somente uma das seguintes condições de estrutura precisa ser atendida:

    • A classe builder deve ter um construtor padrão público.

    • A classe de dados deve ter um método estático público chamado builder() que não usa parâmetros e que retorna uma instância da classe builder. Essa opção é mostrada na classe imutável Customer.

  4. A classe builder deve ter um método público chamado build() que não use parâmetros e retorne uma instância da classe imutável.

Para criar um TableSchema para sua classe imutável, use o método fromImmutableClass() no TableSchema conforme mostrado no trecho a seguir.

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

Assim como você pode criar uma tabela do DynamoDB a partir de uma classe mutável, você pode criar uma a partir de uma classe imutável com uma chamada única para createTable() do DynamoDbTable conforme mostrado no exemplo de trecho a seguir.

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)); }

Usar bibliotecas de terceiros, como Lombok

Bibliotecas de terceiros, como Project Lombok, ajudam a gerar código clichê associado a objetos imutáveis. A API do Cliente Aprimorado do DynamoDB funciona com essas bibliotecas, desde que as classes de dados sigam as convenções detalhadas nesta seção.

O exemplo a seguir mostra a classe CustomerImmutable imutável com anotações do Lombok. Observe como o atributo onMethod do Lombok copia anotações do DynamoDB baseadas em atributos, como @DynamoDbPartitionKey, no código gerado.

@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; }