Utiliser des extensions - AWS SDK for Java 2.x

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utiliser des extensions

Le API client DynamoDB Enhanced prend en charge les extensions de plug-in qui fournissent des fonctionnalités allant au-delà des opérations de mappage. Les extensions ont deux méthodes de crochet, beforeWrite() etafterRead(). beforeWrite()modifie une opération d'écriture avant qu'elle ne se produise, et la afterRead() méthode modifie les résultats d'une opération de lecture après qu'elle se produise. Étant donné que certaines opérations (telles que les mises à jour d'éléments) effectuent à la fois une écriture puis une lecture, les deux méthodes hook sont appelées.

Les extensions sont chargées dans l'ordre dans lequel elles sont spécifiées dans le générateur de clients amélioré. L'ordre de chargement peut être important car une extension peut agir sur des valeurs transformées par une extension précédente.

Le client amélioré API est fourni avec un ensemble d'extensions de plugins qui se trouvent dans le extensions package. Par défaut, le client amélioré charge le VersionedRecordExtension et leAtomicCounterExtension. Vous pouvez modifier le comportement par défaut à l'aide du générateur de clients Enhance et charger n'importe quelle extension. Vous pouvez également n'en spécifier aucune si vous ne souhaitez pas utiliser les extensions par défaut.

Si vous chargez vos propres extensions, le client amélioré ne charge aucune extension par défaut. Si vous souhaitez obtenir le comportement fourni par l'une ou l'autre des extensions par défaut, vous devez l'ajouter explicitement à la liste des extensions.

Dans l'exemple suivant, une extension personnalisée nommée verifyChecksumExtension est chargée d'après leVersionedRecordExtension, qui est généralement chargée par défaut elle-même. Le n'AtomicCounterExtensionest pas chargé dans cet exemple.

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

VersionedRecordExtension

Le VersionedRecordExtension est chargé par défaut et incrémente et suit le numéro de version d'un élément au fur et à mesure que les éléments sont écrits dans la base de données. Une condition sera ajoutée à chaque écriture qui entraîne l'échec de l'écriture si le numéro de version de l'élément persistant réel ne correspond pas à la valeur lue pour la dernière fois par l'application. Ce comportement assure efficacement un verrouillage optimiste pour les mises à jour des articles. Si un autre processus met à jour un élément entre le moment où le premier processus l'a lu et celui où il écrit une mise à jour, l'écriture échouera.

Pour spécifier l'attribut à utiliser pour suivre le numéro de version de l'article, balisez un attribut numérique dans le schéma du tableau.

L'extrait suivant indique que l'versionattribut doit contenir le numéro de version de l'article.

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

L'approche équivalente du schéma de table statique est illustrée dans l'extrait suivant.

.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

Le AtomicCounterExtension est chargé par défaut et incrémente un attribut numérique balisé chaque fois qu'un enregistrement est écrit dans la base de données. Les valeurs de début et d'incrément peuvent être spécifiées. Si aucune valeur n'est spécifiée, la valeur de départ est définie sur 0 et la valeur de l'attribut augmente de 1.

Pour spécifier quel attribut est un compteur, balisez un attribut de type Long dans le schéma du tableau.

L'extrait suivant montre l'utilisation des valeurs de début et d'incrément par défaut pour l'attribut. counter

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

L'approche du schéma de table statique est illustrée dans l'extrait suivant. L'extension du compteur atomique utilise une valeur de départ de 10 et augmente la valeur de 5 à chaque fois que l'enregistrement est écrit.

.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

Le met AutoGeneratedTimestampRecordExtension automatiquement à jour les attributs balisés de type Instant avec un horodatage actuel chaque fois que l'élément est écrit avec succès dans la base de données.

Cette extension n'est pas chargée par défaut. Par conséquent, vous devez le spécifier en tant qu'extension personnalisée lorsque vous créez le client amélioré, comme indiqué dans le premier exemple de cette rubrique.

Pour spécifier l'attribut à mettre à jour avec l'horodatage actuel, balisez-le dans le Instant schéma de la table.

L'lastUpdateattribut est la cible du comportement de l'extension dans l'extrait suivant. Notez l'exigence selon laquelle l'attribut doit être un Instant type.

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

L'approche équivalente du schéma de table statique est illustrée dans l'extrait suivant.

.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

Vous pouvez générer un identifiant unique UUID (identifiant unique universel) pour un attribut lorsqu'un nouvel enregistrement est écrit dans la base de données à l'aide du AutoGeneratedUuidExtension. La méthode Java JDK UUID.random UUID () génère la valeur et vous appliquez l'extension à un attribut de typejava.lang.String.

Étant donné SDK que Java ne charge pas cette extension par défaut, vous devez la spécifier en tant qu'extension personnalisée lorsque vous créez le client amélioré, comme indiqué dans le premier exemple de cette rubrique.

L'uniqueIdattribut est la cible du comportement de l'extension dans l'extrait suivant.

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

L'approche équivalente du schéma de table statique est illustrée dans l'extrait suivant.

.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 vous souhaitez que l'extension soit renseignée UUID uniquement pour les putItem méthodes et non pour les updateItem méthodes, ajoutez l'annotation du comportement de mise à jour, comme indiqué dans l'extrait suivant.

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

Si vous utilisez l'approche du schéma de table statique, utilisez le code équivalent suivant.

.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))

Extensions personnalisées

La classe d'extension personnalisée suivante montre une beforeWrite() méthode qui utilise une expression de mise à jour. Après la ligne de commentaire 2, nous créons un SetAction pour définir l'registrationDateattribut si l'élément de la base de données n'en possède pas déjà unregistrationDate. Chaque fois qu'un Customer objet est mis à jour, l'extension s'assure que a registrationDate est défini.

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