Trabajar con clases de datos inmutables - AWS SDK for Java 2.x

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Trabajar con clases de datos inmutables

La función de mapeo del API cliente mejorado de DynamoDB funciona con clases de datos inmutables. Una clase inmutable solo tiene captadores y requiere una clase de creación que se SDK utilice para crear instancias de la clase. En lugar de usar la anotación @DynamoDbBean como se muestra en la clase Customer, las clases inmutables usan la anotación @DynamoDbImmutable, que toma un parámetro que indica la clase de generador que se va a usar.

La siguiente clase es una versión inmutable 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); } } }

Debe cumplir los siguientes requisitos al anotar una clase de datos con @DynamoDbImmutable.

  1. Todo método que no sea una sustitución de Object.class y que no haya sido anotado con @DynamoDbIgnore debe ser un método de obtención de un atributo de la tabla de DynamoDB.

  2. Cada getter debe tener un setter correspondiente que distinga entre mayúsculas y minúsculas en la clase de constructor.

  3. Solo debe cumplirse una de las siguientes condiciones de construcción.

    • La clase de constructor debe tener un constructor público predeterminado.

    • La clase de datos debe tener un nombre de método estático público builder() que no tome parámetros y devuelva una instancia de clase constructor. Esta opción se muestra en la clase Customer inmutable.

  4. La clase del constructor debe tener un método público llamado build() que no acepte parámetros y devuelva una instancia de la clase inmutable.

Para crear un TableSchema para su clase inmutable, utilice el método fromImmutableClass() en TableSchema como se muestra en el siguiente fragmento.

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

Del mismo modo que puede crear una tabla de DynamoDB a partir de una clase mutable, también puede crear una a partir de una clase inmutable con una llamada única a createTable() de DynamoDbTable como se muestra en el siguiente ejemplo de fragmento.

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

Utilizar bibliotecas de terceros, como Lombok

Las bibliotecas de terceros, como Project Lombok, ayudan a generar código reutilizable asociado a objetos inmutables. El API cliente mejorado de DynamoDB funciona con estas bibliotecas siempre que las clases de datos sigan las convenciones que se detallan en esta sección.

En el siguiente ejemplo, se muestra la clase CustomerImmutable inmutable con anotaciones de Lombok. Observe cómo la característica onMethod de Lombok copia las anotaciones de DynamoDB basadas en atributos, como @DynamoDbPartitionKey, en el código generado.

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