Usar extensiones - 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.

Usar extensiones

El API cliente mejorado de DynamoDB admite extensiones de complementos que proporcionan funciones que van más allá de las operaciones de mapeo. Las extensiones tienen dos métodos de enlace, beforeWrite() y afterRead(). beforeWrite() modifica una operación de escritura antes de que se produzca y el método afterRead() modifica los resultados de una operación de lectura después de que se produzca. Como algunas operaciones (como las actualizaciones de elementos) hacen una escritura y una lectura, se recurre a ambos métodos de enlace.

Las extensiones se cargan en el orden en que se especificaron en el generador de clientes mejorado. El orden de carga puede ser importante porque una extensión puede actuar sobre valores que han sido transformados por una extensión anterior.

El cliente mejorado API incluye un conjunto de extensiones de complementos que se encuentran en el extensions paquete. De forma predeterminada, el cliente mejorado carga VersionedRecordExtension y AtomicCounterExtension. Puede anular el comportamiento predeterminado con el generador de clientes mejorado y cargar cualquier extensión. También puede no especificar ninguna si no desea utilizar las extensiones predeterminadas.

Si carga sus propias extensiones, el cliente mejorado no carga ninguna extensión predeterminada. Si desea el comportamiento proporcionado por alguna de las extensiones predeterminadas, deberá añadirla explícitamente a la lista de extensiones.

En el siguiente ejemplo, una extensión personalizada denominada verifyChecksumExtension se carga después de la VersionedRecordExtension, que normalmente se carga de forma predeterminada por sí misma. La AtomicCounterExtension no se carga en este ejemplo.

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

VersionedRecordExtension

La VersionedRecordExtension se carga de forma predeterminada e incrementará y rastreará el número de versión de un elemento a medida que los elementos se escriban en la base de datos. Se añadirá una condición a cada escritura que hará que esta falle si el número de versión del elemento persistido real no coincide con el valor que la aplicación leyó por última vez. Este comportamiento proporciona efectivamente un bloqueo positivo para las actualizaciones de elementos. Si otro proceso actualiza un elemento entre el momento en que el primer proceso ha leído el elemento y está escribiendo una actualización en él, la escritura fallará.

Para especificar qué atributo usar para rastrear el número de versión del elemento, etiquete un atributo numérico en el esquema de la tabla.

El siguiente fragmento especifica que el atributo version debe contener el número de versión del artículo.

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

AtomicCounterExtension

La AtomicCounterExtension se carga de forma predeterminada e incrementa un atributo numérico etiquetado cada vez que se escribe un registro en la base de datos. Se pueden especificar los valores de inicio y de incremento. Si no se especifica ningún valor, el valor inicial se establece en 0 y el valor del atributo se incrementa en 1.

Para especificar qué atributo es un contador, etiquete un atributo de tipo Long en el esquema de la tabla.

En el siguiente fragmento se muestra el uso de los valores de inicio e incremento predeterminados para el atributo counter.

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

El enfoque del esquema de tabla estático se muestra en el siguiente fragmento. La extensión del contador atómico utiliza un valor inicial de 10 e incrementa el valor en 5 cada vez que se escribe el registro.

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

AutoGeneratedTimestampRecordExtension

La AutoGeneratedTimestampRecordExtension actualiza automáticamente los atributos de tipo Instant con una marca de tiempo actual cada vez que el elemento se escribe correctamente en la base de datos.

Esta extensión no se carga de forma predeterminada. Por lo tanto, debe especificarla como una extensión personalizada al crear el cliente mejorado, como se muestra en el primer ejemplo de este tema.

Para especificar qué atributo actualizar con la marca de tiempo actual, etiquete el atributo Instant en el esquema de la tabla.

El atributo lastUpdate es el objetivo del comportamiento de las extensiones en el siguiente fragmento. Tenga en cuenta el requisito de que el atributo debe ser de tipo Instant.

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

AutoGeneratedUuidExtension

Puede generar un identificador único UUID (identificador único universal) para un atributo cuando se escribe un registro nuevo en la base de datos mediante el AutoGeneratedUuidExtension. El método JDK UUID.random UUID () de Java genera el valor y usted aplica la extensión a un atributo de tipojava.lang.String.

Como Java SDK no carga esta extensión de forma predeterminada, es necesario especificarla como extensión personalizada al crear el cliente mejorado, como se muestra en el primer ejemplo de este tema.

El uniqueId atributo es el objetivo del comportamiento de la extensión en el siguiente fragmento.

@AutoGeneratedUuidExtension public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())

Si quieres que la extensión rellene el campo UUID únicamente para los putItem métodos y no para los updateItem métodos, añade la anotación de actualización del comportamiento, tal y como se muestra en el siguiente fragmento.

@AutoGeneratedUuidExtension @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS) public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

Si utiliza el enfoque de esquema de tabla estática, utilice el siguiente código equivalente.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(), StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))

Extensiones personalizadas

La siguiente clase de extensión personalizada muestra un método beforeWrite() que usa una expresión de actualización. Después de la línea de comentarios 2, creamos un SetAction para establecer el atributo registrationDate si el elemento de la base de datos aún no tiene un atributo registrationDate. Siempre que se actualiza un objeto Customer, la extensión se asegura de que se establece una registrationDate.

public final class CustomExtension implements DynamoDbEnhancedClientExtension { // 1. In a custom extension, use an UpdateExpression to define what action to take before // an item is updated. @Override public WriteModification beforeWrite(DynamoDbExtensionContext.BeforeWrite context) { if ( context.operationContext().tableName().equals("Customer") && context.operationName().equals(OperationName.UPDATE_ITEM)) { return WriteModification.builder() .updateExpression(createUpdateExpression()) .build(); } return WriteModification.builder().build(); // Return an "empty" WriteModification instance if the extension should not be applied. // In this case, if the code is not updating an item on the Customer table. } private static UpdateExpression createUpdateExpression() { // 2. Use a SetAction, a subclass of UpdateAction, to provide the values in the update. SetAction setAction = SetAction.builder() .path("registrationDate") .value("if_not_exists(registrationDate, :regValue)") .putExpressionValue(":regValue", AttributeValue.fromS(Instant.now().toString())) .build(); // 3. Build the UpdateExpression with one or more UpdateAction. return UpdateExpression.builder() .addAction(setAction) .build(); } }