使用擴充功能 - AWS SDK for Java 2.x

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

使用擴充功能

DynamoDB 增強型用戶端API支援外掛程式擴充功能,可提供映射操作以外的功能。延伸模組有兩種勾點方法,beforeWrite()以及 afterRead()。 會在寫入操作發生前beforeWrite()修改寫入操作,而該afterRead()方法會在讀取操作發生後修改讀取操作的結果。由於某些操作 (例如項目更新) 同時執行寫入和讀取,因此會呼叫這兩種掛鉤方法。

擴充功能會以增強型用戶端建置器中指定的順序載入。負載順序可能很重要,因為一個延伸模組可以對先前延伸模組轉換的值採取行動。

增強型用戶端API隨附一組位於 extensions 套件中的外掛程式延伸模組。根據預設,增強型用戶端會載入 VersionedRecordExtensionAtomicCounterExtension。您可以使用增強型用戶端建置器覆寫預設行為,並載入任何延伸。如果您不想要預設延伸模組,也可以不指定任何 。

如果您載入自己的擴充功能,增強型用戶端不會載入任何預設擴充功能。如果您想要任一預設延伸模組提供的行為,您需要明確地將其新增至延伸模組清單。

在下列範例中,名為 的自訂延伸verifyChecksumExtension模組會在 之後載入VersionedRecordExtension,通常依預設會自行載入。在此範例中AtomicCounterExtension不會載入 。

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

VersionedRecordExtension

依預設VersionedRecordExtension會載入 ,並在項目寫入資料庫時增加和追蹤項目版本號碼。如果實際持久性項目的版本編號與應用程式上次讀取的值不相符,則每次寫入都會新增一個條件,導致寫入失敗。此行為有效地為項目更新提供樂觀鎖定。如果另一個程序在第一個程序讀取項目並寫入更新之間的時間更新項目,寫入將會失敗。

若要指定要用來追蹤項目版本編號的屬性,請在資料表結構描述中標記數值屬性。

下列程式碼片段指定 version 屬性應保留項目版本號碼。

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

等效的靜態資料表結構描述方法會顯示在下列程式碼片段中。

.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

依預設AtomicCounterExtension會載入 ,並在每次記錄寫入資料庫時增加標記的數值屬性。可以指定開始值和增量值。如果未指定任何值,則開始值會設為 0,屬性的值增量為 1。

若要指定哪個屬性是計數器,請在資料表結構描述Long中標記 類型的屬性。

下列程式碼片段顯示 counter 屬性的預設開始值和增量值的使用。

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

靜態資料表結構描述方法會顯示在下列程式碼片段中。原子計數器延伸使用 10 的開始值,每次寫入記錄時,該值會增加 5。

.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

每次項目成功寫入資料庫時, AutoGeneratedTimestampRecordExtension會自動Instant使用目前時間戳記更新類型的已標記屬性。

預設不會載入此延伸模組。因此,當您建置增強型用戶端時,您需要將其指定為自訂延伸模組,如本主題的第一個範例所示。

若要指定要使用目前時間戳記更新的屬性,請在資料表結構描述中標記 Instant 屬性。

lastUpdate 屬性是下列程式碼片段中延伸行為的目標。請注意 屬性必須是 Instant類型的要求。

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

等效的靜態資料表結構描述方法會顯示在下列程式碼片段中。

.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

使用 將新記錄寫入資料庫時,您可以為屬性產生唯一 UUID(通用唯一識別碼)AutoGeneratedUuidExtension。Java JDK UUID.random UUID() 方法會產生 值,並將延伸模組套用至類型 的屬性java.lang.String

由於 Java 預設SDK不會載入此延伸模組,因此您需要在建置增強型用戶端時將其指定為自訂延伸模組,如本主題的第一個範例所示。

uniqueId 屬性是下列程式碼片段中延伸模組行為的目標。

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

等效的靜態資料表結構描述方法會顯示在下列程式碼片段中。

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

如果您想要延伸UUID模組僅針對putItem方法填入 ,而不是針對updateItem方法填入 ,請新增更新行為註釋,如下列程式碼片段所示。

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

如果您使用靜態資料表結構描述方法,請使用下列等效程式碼。

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

自訂擴充功能

下列自訂延伸類別顯示使用更新表達式beforeWrite()的方法。評論第 2 行之後,如果資料庫中的項目尚未具有registrationDate屬性,我們會建立 SetAction來設定 registrationDate 屬性。每當Customer更新物件時,延伸模組都會確保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(); } }