選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

使用 程式設計 DynamoDB AWS SDK for Java 2.x

焦點模式
使用 程式設計 DynamoDB AWS SDK for Java 2.x - Amazon DynamoDB

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

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

此程式設計指南為想要搭配 Java 使用 Amazon DynamoDB 的程式設計人員提供 方向。本指南涵蓋不同的概念,包括抽象層、組態管理、錯誤處理、控制重試政策和管理保持連線。

關於 AWS SDK for Java 2.x

您可以使用 官方從 Java 存取 DynamoDB AWS SDK for Java。SDK 適用於 Java 的 有兩種版本:1.x 和 2.x。適用於 1.x 的 end-of-support已於 2024 年 1 月 12 日發佈。其將於 2024 年 7 月 31 日進入維護模式,並於 2025 年 12 月 31 日 end-of-support到期。對於新開發,強烈建議您使用 2.x,該版本於 2018 年首次發行。本指南專門針對 2.x,僅專注於與 DynamoDB SDK相關的 部分。

如需 維護和支援的相關資訊 AWS SDKs,請參閱《 AWS SDK 和 工具參考指南》中的 和工具維護政策和 AWS SDKs 和工具AWS SDKs版本支援矩陣

AWS SDK for Java 2.x 是 1.x 程式碼基礎的主要重寫。SDK 適用於 Java 的 2.x 支援現代 Java 功能,例如 Java 8 中引入的非封鎖 I/O。SDK 適用於 Java 的 2.x 也新增了對可插入HTTP用戶端實作的支援,以提供更多的網路連線彈性和組態選項。

SDK 適用於 Java 1.x 的 和SDK適用於 Java 2.x 的 之間的明顯變更是使用新的套件名稱。Java 1.x SDK使用com.amazonaws套件名稱,而 Java 2software.amazon.awssdk.x SDK使用 。同樣地,Java 1.x 的 Maven 成品SDK使用 com.amazonaws groupId,而 Java 2groupId.x SDK成品使用 software.amazon.awssdk

重要

The AWS SDK for Java 1.x 有一個名為 的 DynamoDB 套件com.amazonaws.dynamodbv2。套件名稱中的 "v2" 不表示其適用於 Java 2 (J2SE)。相反地,「v2」表示套件支援 DynamoDB 低階的第二個版本,API而不是低階 的原始版本API。

支援 Java 版本

AWS SDK for Java 2.x 提供長期支援 (LTS) Java 版本的完整支援。

AWS SDK for Java 2.x入門

下列教學課程說明如何使用 Apache Maven 來定義SDK適用於 Java 2.x 的 相依性。本教學課程也說明如何撰寫連線至 DynamoDB 的程式碼,以列出可用的 DynamoDB 資料表。本指南中的教學課程是以 AWS SDK for Java 2.x 開發人員指南中的 入門 AWS SDK for Java 2.x教學課程為基礎。我們已編輯本教學課程,以呼叫 DynamoDB 而非 Amazon S3。

步驟 1:設定本教學課程

開始本教學課程之前,您需要下列項目:

  • 存取 DynamoDB 的許可。

  • 使用 設定單一登入存取的 Java AWS 服務 開發環境 AWS 存取入口網站。

若要設定本教學課程,請遵循 AWS SDK for Java 2.x 開發人員指南中的設定概觀中的指示。使用 Java 的單一登入存取設定開發環境,SDK並且您擁有作用中的 AWS 存取入口網站工作階段後,請繼續本教學課程的步驟 2

步驟 2:建立專案

若要建立本教學課程的專案,請執行 Maven 命令,提示您輸入如何設定專案。輸入並確認所有輸入後,Maven 會透過建立pom.xml檔案和建立 stub Java 檔案來完成建置專案。

  1. 開啟終端機或命令提示視窗,並導覽至您選擇的目錄,例如您的 DesktopHome 資料夾。

  2. 在終端機輸入下列命令,然後按 Enter

    mvn archetype:generate \ -DarchetypeGroupId=software.amazon.awssdk \ -DarchetypeArtifactId=archetype-app-quickstart \ -DarchetypeVersion=2.22.0
  3. 針對每個提示,輸入列於第二欄的值。

    提示 要輸入的值
    Define value for property 'service': dynamodb
    Define value for property 'httpClient': apache-client
    Define value for property 'nativeImage': false
    Define value for property 'credentialProvider' identity-center
    Define value for property 'groupId': org.example
    Define value for property 'artifactId': getstarted
    Define value for property 'version' 1.0-SNAPSHOT: <Enter>
    Define value for property 'package' org.example: <Enter>
  4. 在您輸入最後一個值後,Maven 會列出您所做的選擇。若要確認,請輸入 Y。 或者,輸入 N,然後重新輸入您的選擇。

Maven getstarted會根據您輸入的artifactId值建立名為 的專案資料夾。在 getstarted 資料夾中,尋找名為 README.md 的檔案,供您檢閱、pom.xml檔案和src目錄。

Maven 會建置下列目錄樹狀目錄。

getstarted ├── README.md ├── pom.xml └── src ├── main │ ├── java │ │ └── org │ │ └── example │ │ ├── App.java │ │ ├── DependencyFactory.java │ │ └── Handler.java │ └── resources │ └── simplelogger.properties └── test └── java └── org └── example └── HandlerTest.java 10 directories, 7 files

以下顯示pom.xml專案檔案的內容。

dependencyManagement 區段包含對 的相依性 AWS SDK for Java 2.x,且dependencies區段具有對 DynamoDB 的相依性。指定這些相依性會強制 Maven 在 Java 類別路徑中包含相關.jar檔案。根據預設, AWS SDK 不會包含所有 類別 AWS 服務。對於 DynamoDB,如果您使用低階界面,則應該依賴dynamodb成品。或者,如果您使用高階界面,則在dynamodb-enhanced成品上。如果您未包含相關的相依性,則程式碼無法編譯。由於 maven.compiler.sourcemaven.compiler.target 屬性中的 1.8值,專案使用 Java 1.8。

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>getstarted</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version> <aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version. <slf4j.version>1.7.28</slf4j.version> <junit5.version>5.8.1</junit5.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.java.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>dynamodb</artifactId> <-------- DynamoDB dependency <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>sso</artifactId> <-------- Required for identity center authentication. </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication. </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> <-------- HTTP client specified. <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>${slf4j.version}</version> </dependency> <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <!-- Test Dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit5.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> </plugins> </build> </project>

dependencyManagement 區段包含對 的相依性 AWS SDK for Java 2.x,且dependencies區段具有對 DynamoDB 的相依性。指定這些相依性會強制 Maven 在 Java 類別路徑中包含相關.jar檔案。根據預設, AWS SDK 不會包含所有 類別 AWS 服務。對於 DynamoDB,如果您使用低階界面,則應該依賴dynamodb成品。或者,如果您使用高階界面,則在dynamodb-enhanced成品上。如果您未包含相關的相依性,則程式碼無法編譯。由於 maven.compiler.sourcemaven.compiler.target 屬性中的 1.8值,專案使用 Java 1.8。

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>getstarted</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version> <aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version. <slf4j.version>1.7.28</slf4j.version> <junit5.version>5.8.1</junit5.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.java.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>dynamodb</artifactId> <-------- DynamoDB dependency <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>sso</artifactId> <-------- Required for identity center authentication. </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication. </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> <-------- HTTP client specified. <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>${slf4j.version}</version> </dependency> <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <!-- Test Dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit5.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> </plugins> </build> </project>

步驟 3:撰寫程式碼

下列程式碼顯示 Maven 建立的App類別。main 方法是應用程式的進入點,它會建立 Handler類別的執行個體,然後呼叫其sendRequest方法。

package org.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static final Logger logger = LoggerFactory.getLogger(App.class); public static void main(String... args) { logger.info("Application starts"); Handler handler = new Handler(); handler.sendRequest(); logger.info("Application ends"); } }

package org.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static final Logger logger = LoggerFactory.getLogger(App.class); public static void main(String... args) { logger.info("Application starts"); Handler handler = new Handler(); handler.sendRequest(); logger.info("Application ends"); } }

Maven 建立的 DependencyFactory類別包含建置和傳回DynamoDbClient執行個體的dynamoDbClient原廠方法。DynamoDbClient 執行個體使用 Apache 型HTTP用戶端的執行個體。這是因為您在 Maven 提示您使用哪個HTTP用戶端apache-client時指定。

下列程式碼顯示 DependencyFactory 類別。

package org.example; import software.amazon.awssdk.http.apache.ApacheHttpClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; /** * The module containing all dependencies required by the {@link Handler}. */ public class DependencyFactory { private DependencyFactory() {} /** * @return an instance of DynamoDbClient */ public static DynamoDbClient dynamoDbClient() { return DynamoDbClient.builder() .httpClientBuilder(ApacheHttpClient.builder()) .build(); } }

package org.example; import software.amazon.awssdk.http.apache.ApacheHttpClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; /** * The module containing all dependencies required by the {@link Handler}. */ public class DependencyFactory { private DependencyFactory() {} /** * @return an instance of DynamoDbClient */ public static DynamoDbClient dynamoDbClient() { return DynamoDbClient.builder() .httpClientBuilder(ApacheHttpClient.builder()) .build(); } }

Handler 類別包含您程式的主要邏輯。在 App類別中建立 Handler 執行個體時, DependencyFactory 會提供 DynamoDbClient服務用戶端。您的程式碼使用DynamoDbClient執行個體呼叫 DynamoDB。

Maven 會產生具有TODO註解的下列Handler類別。教學課程的下一個步驟會以程式碼取代TODO註解。

package org.example; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; public class Handler { private final DynamoDbClient dynamoDbClient; public Handler() { dynamoDbClient = DependencyFactory.dynamoDbClient(); } public void sendRequest() { // TODO: invoking the API calls using dynamoDbClient. } }

package org.example; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; public class Handler { private final DynamoDbClient dynamoDbClient; public Handler() { dynamoDbClient = DependencyFactory.dynamoDbClient(); } public void sendRequest() { // TODO: invoking the API calls using dynamoDbClient. } }

若要填入邏輯,請使用下列程式碼取代Handler類別的完整內容。sendRequest 方法已填入,並新增必要的匯入。

下列程式碼使用DynamoDbClient執行個體來擷取現有資料表的清單。如果指定帳戶和 有資料表 AWS 區域,則程式碼會使用Logger執行個體來記錄這些資料表的名稱。

package org.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; public class Handler { private final DynamoDbClient dynamoDbClient; public Handler() { dynamoDbClient = DependencyFactory.dynamoDbClient(); } public void sendRequest() { Logger logger = LoggerFactory.getLogger(Handler.class); logger.info("calling the DynamoDB API to get a list of existing tables"); ListTablesResponse response = dynamoDbClient.listTables(); if (!response.hasTableNames()) { logger.info("No existing tables found for the configured account & region"); } else { response.tableNames().forEach(tableName -> logger.info("Table: " + tableName)); } } }

下列程式碼使用DynamoDbClient執行個體來擷取現有資料表的清單。如果指定帳戶和 有資料表 AWS 區域,則程式碼會使用Logger執行個體來記錄這些資料表的名稱。

package org.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; public class Handler { private final DynamoDbClient dynamoDbClient; public Handler() { dynamoDbClient = DependencyFactory.dynamoDbClient(); } public void sendRequest() { Logger logger = LoggerFactory.getLogger(Handler.class); logger.info("calling the DynamoDB API to get a list of existing tables"); ListTablesResponse response = dynamoDbClient.listTables(); if (!response.hasTableNames()) { logger.info("No existing tables found for the configured account & region"); } else { response.tableNames().forEach(tableName -> logger.info("Table: " + tableName)); } } }

步驟 4:建置和執行應用程式

在您建立專案並包含完整的Handler類別之後,請建置並執行應用程式。

  1. 請確定您有一個作用中的 AWS IAM Identity Center 工作階段。若要確認,請執行 AWS Command Line Interface (AWS CLI) 命令aws sts get-caller-identity並檢查回應。如果您沒有作用中的工作階段,請參閱使用 登入 AWS CLI以取得指示。

  2. 開啟終端機或命令提示視窗,然後導覽至您的專案目錄 getstarted

  3. 若要建置專案,請執行下列命令:

    mvn clean package
  4. 若要執行應用程式,請執行下列命令:

    mvn exec:java -Dexec.mainClass="org.example.App"

檢視檔案後,請刪除物件,然後刪除儲存貯體。

成功

如果您的 Maven 專案建置並執行時沒有錯誤,恭喜您!您已成功使用適用於 Java 2.x SDK的 建置第一個 Java 應用程式。

清除

若要清除您在本教學課程中建立的資源,請刪除專案資料夾 getstarted

檢閱 AWS SDK for Java 2.x 文件

AWS SDK for Java 2.x 開發人員指南涵蓋 SDK 所有層面 AWS 服務。我們建議您檢閱下列主題:

提示

檢閱這些主題之後,請將AWS SDK for Java 2.x API參考加入書籤。它涵蓋所有項目 AWS 服務,我們建議您使用它做為主要API參考。

支援的介面

AWS SDK for Java 2.x 支援下列界面,取決於您想要的抽象程度。

低階界面

低階界面提供 one-to-one基礎服務的映射API。每個 DynamoDB API 都可透過此界面使用。這表示低階界面可以提供完整的功能,但通常更詳細且複雜。例如,您必須使用 .s()函數來保留字串,並使用 .n()函數來保留數字。下列範例使用低階界面PutItem插入項目。

import org.slf4j.*; import software.amazon.awssdk.http.crt.AwsCrtHttpClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.*; import java.util.Map; public class PutItem { // Create a DynamoDB client with the default settings connected to the DynamoDB // endpoint in the default region based on the default credentials provider chain. private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.create(); private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class); private void putItem() { PutItemResponse response = DYNAMODB_CLIENT.putItem(PutItemRequest.builder() .item(Map.of( "pk", AttributeValue.builder().s("123").build(), "sk", AttributeValue.builder().s("cart#123").build(), "item_data", AttributeValue.builder().s("YourItemData").build(), "inventory", AttributeValue.builder().n("500").build() // ... more attributes ... )) .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .tableName("YourTableName") .build()); LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)"); } }

高階界面

中的高階界面 AWS SDK for Java 2.x 稱為 DynamoDB 增強型用戶端。此界面提供更栩栩如生的程式碼撰寫體驗。

增強型用戶端提供在用戶端資料類別與 DynamoDB 資料表之間映射的方法,這些資料表旨在存放該資料。您要在自己的程式碼中定義資料表及其對應模型類別之間的關係。然後,您可以依賴 SDK 來管理資料類型操作。如需增強型用戶端的詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的 DynamoDB 增強型用戶端API

下列範例PutItem使用高階介面。在此範例中,DynamoDbBean名為 的 YourItem會建立 TableSchema,使其能夠直接使用 做為putItem()呼叫的輸入。

import org.slf4j.*; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*; import software.amazon.awssdk.enhanced.dynamodb.model.*; import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity; public class DynamoDbEnhancedClientPutItem { private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(YourItem.class)); private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class); private void putItem() { PutItemEnhancedResponse<YourItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourItem.class) .item(new YourItem("123", "cart#123", "YourItemData", 500)) .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .build()); LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)"); } @DynamoDbBean public static class YourItem { public YourItem() {} public YourItem(String pk, String sk, String itemData, int inventory) { this.pk = pk; this.sk = sk; this.itemData = itemData; this.inventory = inventory; } private String pk; private String sk; private String itemData; private int inventory; @DynamoDbPartitionKey public void setPk(String pk) { this.pk = pk; } public String getPk() { return pk; } @DynamoDbSortKey public void setSk(String sk) { this.sk = sk; } public String getSk() { return sk; } public void setItemData(String itemData) { this.itemData = itemData; } public String getItemData() { return itemData; } public void setInventory(int inventory) { this.inventory = inventory; } public int getInventory() { return inventory; } } }

AWS SDK for Java 1.x 有自己的高階界面,通常由其主要類別 所指DynamoDBMapper。 AWS SDK for Java 2.x 會以名為 的個別套件 (和 Maven 成品) 發佈software.amazon.awssdk.enhanced.dynamodb。Java 2.x SDK通常由其主類別 參考。 DynamoDbEnhancedClient

使用不可變資料類別的高階界面

DynamoDB 增強型用戶端的映射功能API也適用於不可變的資料類別。不可變的類別只有 getter,且需要建置器類別, SDK會用來建立類別的執行個體。Java 中的抗擾性是一種常用的樣式,開發人員可用來建立沒有副作用的類別。這些類別在複雜多執行緒應用程式中的行為更可預測。不如 所示使用@DynamoDbBean註釋High-level interface example,不可變類別會使用@DynamoDbImmutable註釋,這會將建置器類別做為其輸入。

下列範例採用建置器類別DynamoDbEnhancedClientImmutablePutItem做為輸入來建立資料表結構描述。然後,範例會提供結構描述做為PutItemAPI呼叫的輸入。

import org.slf4j.*; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.model.*; import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity; public class DynamoDbEnhancedClientImmutablePutItem { private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<YourImmutableItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableItem.class)); private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutablePutItem.class); private void putItem() { PutItemEnhancedResponse<YourImmutableItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableItem.class) .item(YourImmutableItem.builder() .pk("123") .sk("cart#123") .itemData("YourItemData") .inventory(500) .build()) .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .build()); LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)"); } }

下列範例顯示不可變的資料類別。

@DynamoDbImmutable(builder = YourImmutableItem.YourImmutableItemBuilder.class) class YourImmutableItem { private final String pk; private final String sk; private final String itemData; private final int inventory; public YourImmutableItem(YourImmutableItemBuilder builder) { this.pk = builder.pk; this.sk = builder.sk; this.itemData = builder.itemData; this.inventory = builder.inventory; } public static YourImmutableItemBuilder builder() { return new YourImmutableItemBuilder(); } @DynamoDbPartitionKey public String getPk() { return pk; } @DynamoDbSortKey public String getSk() { return sk; } public String getItemData() { return itemData; } public int getInventory() { return inventory; } static final class YourImmutableItemBuilder { private String pk; private String sk; private String itemData; private int inventory; private YourImmutableItemBuilder() {} public YourImmutableItemBuilder pk(String pk) { this.pk = pk; return this; } public YourImmutableItemBuilder sk(String sk) { this.sk = sk; return this; } public YourImmutableItemBuilder itemData(String itemData) { this.itemData = itemData; return this; } public YourImmutableItemBuilder inventory(int inventory) { this.inventory = inventory; return this; } public YourImmutableItem build() { return new YourImmutableItem(this); } } }

使用不可變資料類別和第三方樣板產生程式庫的高階界面

不可避免的資料類別 (如上例所示) 需要一些樣板程式碼。例如,除了 類別之外,資料類別上的 getter 和 setter 邏輯Builder。第三方程式庫,例如 Project Lombok,可協助您產生該類型的樣板程式碼。減少大部分樣板程式碼可協助您限制使用不可變資料類別和 所需的程式碼數量 AWS SDK。這進一步改善了程式碼的生產力和可讀性。如需詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的使用第三方程式庫,例如 Lombok

下列範例示範 Project Lombok 如何簡化使用 DynamoDB 增強型用戶端 所需的程式碼API。

import org.slf4j.*; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.model.*; import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity; public class DynamoDbEnhancedClientImmutableLombokPutItem { private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<YourImmutableLombokItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableLombokItem.class)); private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutableLombokPutItem.class); private void putItem() { PutItemEnhancedResponse<YourImmutableLombokItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableLombokItem.class) .item(YourImmutableLombokItem.builder() .pk("123") .sk("cart#123") .itemData("YourItemData") .inventory(500) .build()) .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .build()); LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)"); } }

下列範例顯示不可變資料類別的不可變資料物件。

import lombok.*; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*; @Builder @DynamoDbImmutable(builder = YourImmutableLombokItem.YourImmutableLombokItemBuilder.class) @Value public class YourImmutableLombokItem { @Getter(onMethod_=@DynamoDbPartitionKey) String pk; @Getter(onMethod_=@DynamoDbSortKey) String sk; String itemData; int inventory; }

YourImmutableLombokItem 類別使用 Project Lombok 和 AWS SDK提供的下列註釋:

  • @Builder – APIs為 Project Lombok 提供的資料類別產生複雜的建置器。

  • @DynamoDbImmutable – 將DynamoDbImmutable類別識別為 AWS SDK提供的 DynamoDB 可映射實體註釋。

  • @Value – 的不可變變體@Data。根據預設,所有欄位都會設為私有和最終,不會產生設定程式。Project Lombok 提供此註釋。

文件界面

AWS SDK for Java 2.x 文件界面可避免需要指定資料類型描述項。資料類型是由資料本身的語義隱含的。此文件界面類似於 文件界面 AWS SDK for Java 1.x,但具有重新設計的界面。

以下Document interface example顯示使用文件界面表示的PutItem呼叫。此範例也會使用 EnhancedDocument。若要使用增強型文件 對 DynamoDB 資料表執行命令API,您必須先將資料表與文件資料表結構描述建立關聯,才能建立DynamoDBTable資源物件。文件資料表結構描述建置器需要主要索引鍵和屬性轉換器提供者。

您可以使用 AttributeConverterProvider.defaultProvider() 來轉換預設類型的文件屬性。您可以使用自訂AttributeConverterProvider實作變更整體預設行為。您也可以變更單一屬性的轉換器。AWS SDKs 和 工具參考指南提供有關如何使用自訂轉換器的更多詳細資訊和範例。其主要用途是用於沒有預設轉換器的網域類別屬性。使用自訂轉換器,您可以SDK為 提供寫入或讀取至 DynamoDB 所需的資訊。

import org.slf4j.*; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument; import software.amazon.awssdk.enhanced.dynamodb.model.*; import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity; public class DynamoDbEnhancedDocumentClientPutItem { private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder() .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S) .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S) .attributeConverterProviders(AttributeConverterProvider.defaultProvider()) .build()); private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientPutItem.class); private void putItem() { PutItemEnhancedResponse<EnhancedDocument> response = DYNAMODB_TABLE.putItemWithResponse( PutItemEnhancedRequest.builder(EnhancedDocument.class) .item( EnhancedDocument.builder() .attributeConverterProviders(AttributeConverterProvider.defaultProvider()) .putString("pk", "123") .putString("sk", "cart#123") .putString("item_data", "YourItemData") .putNumber("inventory", 500) .build()) .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .build()); LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)"); } }

若要在原生 Amazon DynamoDB 資料類型之間轉換JSON文件,您可以使用下列公用程式方法:

比較介面與Query範例

本節顯示使用各種介面所表達的相同Query呼叫。若要微調這些查詢的結果,請注意下列事項:

  • DynamoDB 以一個特定的分割區索引鍵值為目標,因此您必須完全指定分割區索引鍵。

  • 若要讓查詢目標只有購物車項目,排序索引鍵具有使用 的索引鍵條件表達式begins_with

  • 我們使用 limit()將查詢限制為最多 100 個傳回的項目。

  • 我們將 scanIndexForward 設定為 false。結果會依 UTF-8 位元組的順序傳回,這通常表示會先傳回數字最低的購物車項目。透過將 scanIndexForward 設定為 false,我們會反轉順序,並先傳回具有最高號碼的購物車項目。

  • 我們會套用篩選條件來移除不符合條件的任何結果。篩選的資料會耗用讀取容量,無論項目是否符合篩選條件。

範例 Query 使用低階界面

下列範例YourTableName會使用 查詢名為 的資料表keyConditionExpression。這會將查詢限制為特定的分割區索引鍵值,並排序以特定字首值開頭的索引鍵值。這些金鑰條件會限制從 DynamoDB 讀取的資料量。最後,查詢會在使用 從 DynamoDB 擷取的資料上套用篩選條件filterExpression

import org.slf4j.*; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.*; import java.util.Map; public class Query { // Create a DynamoDB client with the default settings connected to the DynamoDB // endpoint in the default region based on the default credentials provider chain. private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.builder().build(); private static final Logger LOGGER = LoggerFactory.getLogger(Query.class); private static void query() { QueryResponse response = DYNAMODB_CLIENT.query(QueryRequest.builder() .expressionAttributeNames(Map.of("#name", "name")) .expressionAttributeValues(Map.of( ":pk_val", AttributeValue.fromS("id#1"), ":sk_val", AttributeValue.fromS("cart#"), ":name_val", AttributeValue.fromS("SomeName"))) .filterExpression("#name = :name_val") .keyConditionExpression("pk = :pk_val AND begins_with(sk, :sk_val)") .limit(100) .scanIndexForward(false) .tableName("YourTableName") .build()); LOGGER.info("nr of items: " + response.count()); LOGGER.info("First item pk: " + response.items().get(0).get("pk")); LOGGER.info("First item sk: " + response.items().get(0).get("sk")); } }
範例 Query 使用文件界面

下列範例YourTableName會使用文件界面查詢名為 的資料表。

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument; import software.amazon.awssdk.enhanced.dynamodb.model.*; import java.util.Map; public class DynamoDbEnhancedDocumentClientQuery { // Create a DynamoDB client with the default settings connected to the DynamoDB // endpoint in the default region based on the default credentials provider chain. private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder() .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S) .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S) .attributeConverterProviders(AttributeConverterProvider.defaultProvider()) .build()); private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientQuery.class); private void query() { PageIterable<EnhancedDocument> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder() .filterExpression(Expression.builder() .expression("#name = :name_val") .expressionNames(Map.of("#name", "name")) .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName"))) .build()) .limit(100) .queryConditional(QueryConditional.sortBeginsWith(Key.builder() .partitionValue("id#1") .sortValue("cart#") .build())) .scanIndexForward(false) .build()); LOGGER.info("nr of items: " + response.items().stream().count()); LOGGER.info("First item pk: " + response.items().iterator().next().getString("pk")); LOGGER.info("First item sk: " + response.items().iterator().next().getString("sk")); } }
範例 Query 使用高階界面

下列範例YourTableName會使用 DynamoDB 增強型用戶端 查詢名為 的資料表API。

import org.slf4j.*; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*; import software.amazon.awssdk.enhanced.dynamodb.model.*; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import java.util.Map; public class DynamoDbEnhancedClientQuery { private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build(); private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(DynamoDbEnhancedClientQuery.YourItem.class)); private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientQuery.class); private void query() { PageIterable<YourItem> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder() .filterExpression(Expression.builder() .expression("#name = :name_val") .expressionNames(Map.of("#name", "name")) .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName"))) .build()) .limit(100) .queryConditional(QueryConditional.sortBeginsWith(Key.builder() .partitionValue("id#1") .sortValue("cart#") .build())) .scanIndexForward(false) .build()); LOGGER.info("nr of items: " + response.items().stream().count()); LOGGER.info("First item pk: " + response.items().iterator().next().getPk()); LOGGER.info("First item sk: " + response.items().iterator().next().getSk()); } @DynamoDbBean public static class YourItem { public YourItem() {} public YourItem(String pk, String sk, String name) { this.pk = pk; this.sk = sk; this.name = name; } private String pk; private String sk; private String name; @DynamoDbPartitionKey public void setPk(String pk) { this.pk = pk; } public String getPk() { return pk; } @DynamoDbSortKey public void setSk(String sk) { this.sk = sk; } public String getSk() { return sk; } public void setName(String name) { this.name = name; } public String getName() { return name; } } }
使用不可變資料類別的高階界面

當您Query使用高階不可變資料類別執行 時,程式碼會與高階介面範例相同,但實體類別YourItem或 的建構除外YourImmutableItem。如需詳細資訊,請參閱PutItem範例。

使用不可變資料類別和第三方樣板產生程式庫的高階界面

當您Query使用高階不可變資料類別執行 時,程式碼會與高階介面範例相同,但實體類別YourItem或 的建構除外YourImmutableLombokItem。如需詳細資訊,請參閱PutItem範例。

其他程式碼範例

如需如何搭配SDK適用於 Java 2.x 的 使用 DynamoDB 的其他範例,請參閱下列程式碼範例儲存庫:

同步和非同步程式設計

同時為 AWS SDK for Java 2.x 提供同步和非同步用戶端 AWS 服務,例如 DynamoDB。

DynamoDbClientDynamoDbEnhancedClient類別提供同步方法來封鎖執行緒的執行,直到用戶端收到來自 服務的回應。如果您不需要非同步操作,此用戶端是與 DynamoDB 互動的最直接方式。

DynamoDbAsyncClientDynamoDbEnhancedAsyncClient類別提供可立即傳回的非同步方法,並控制呼叫執行緒,而無需等待回應。非封鎖用戶端具有優勢,可用於幾個執行緒之間的高並行,以最低的運算資源有效率地處理 I/O 請求。這可改善輸送量和回應能力。

AWS SDK for Java 2.x 使用原生支援進行非封鎖 I/O。 AWS SDK for Java 1.x 必須模擬非封鎖輸入/輸出。

同步方法會在回應可用之前傳回,因此您需要一種在回應準備就緒時取得回應的方法。中的非同步方法會 AWS SDK for Java 傳回CompletableFuture物件,其中包含未來非同步操作的結果。當您在這些CompletableFuture物件join()上呼叫 get()或 時,您的程式碼會封鎖,直到結果可用為止。如果您在提出請求的同時呼叫這些 ,則行為類似於純同步呼叫。

如需非同步程式設計的詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的使用非同步程式設計

HTTP 用戶端

為了支援每個用戶端,有一個HTTP用戶端可處理與 的通訊 AWS 服務。您可以插入替代HTTP用戶端,選擇具有最適合您應用程式的特性的用戶端。有些更輕量;有些則有更多的組態選項。

有些HTTP用戶端僅支援同步使用,有些用戶端僅支援非同步使用。如需可協助您為工作負載選取最佳HTTP用戶端的流程圖,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的HTTP用戶端建議

下列清單顯示一些可能的HTTP用戶端:

以 Apache 為基礎的HTTP用戶端

ApacheHttpClient 類別支援同步服務用戶端。這是同步使用的預設HTTP用戶端。如需設定ApacheHttpClient類別的資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的設定 Apache 型HTTP用戶端

URLConnection型HTTP用戶端

UrlConnectionHttpClient 類別是同步用戶端的另一個選項。它比以 Apache 為基礎的HTTP用戶端載入更快,但功能較少。如需設定 UrlConnectionHttpClient類別的詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的設定 URLConnection型HTTP用戶端

Netty 型HTTP用戶端

NettyNioAsyncHttpClient 類別支援非同步用戶端。這是非同步使用的預設選擇。如需設定NettyNioAsyncHttpClient類別的相關資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的設定 Netty 型HTTP用戶端

AWS CRT型HTTP用戶端

來自 AWS Common Runtime (CRT) 程式庫的較新AwsCrtHttpClientAwsCrtAsyncHttpClient類別是支援同步和非同步用戶端的更多選項。相較於其他HTTP用戶端, AWS CRT 提供:

  • 更快速的SDK啟動時間

  • 記憶體佔用空間較小

  • 減少延遲時間

  • 連線運作狀態管理

  • DNS 負載平衡

如需設定 AwsCrtHttpClientAwsCrtAsyncHttpClient類別的詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的設定 AWS CRT型HTTP用戶端

AWS CRT基於 的HTTP用戶端不是預設值,因為這會破壞現有應用程式的回溯相容性。不過,對於 DynamoDB,我們建議您使用 AWS CRT型HTTP用戶端進行同步和非同步使用。

如需 AWS CRT型HTTP用戶端的簡介,請參閱《 AWS 開發人員工具部落格》中的宣布HTTP用戶端的 AWS CRT可用性 AWS SDK for Java 2.x

設定 HTTP 用戶端

設定用戶端時,您可以提供各種組態選項,包括:

  • 設定API呼叫不同層面的逾時。

  • 啟用TCP保持運作。

  • 遇到錯誤時控制重試政策。

  • 指定執行攔截器執行個體可以修改的執行屬性。執行攔截器可以編寫程式碼,攔截API請求和回應的執行。這可讓您執行任務,例如發佈指標和修改傳輸中的請求。

  • 新增或操作HTTP標頭。

  • 啟用用戶端效能指標的追蹤。使用此功能可協助您收集應用程式中服務用戶端的指標,並分析 Amazon 中的輸出 CloudWatch。

  • 指定要用於排程任務的替代執行器服務,例如非同步重試嘗試和逾時任務。

您可以透過提供ClientOverrideConfiguration物件給服務用戶端Builder類別來控制組態。您會在下列各節的一些程式碼範例中看到此問題。

ClientOverrideConfiguration 提供標準組態選擇。不同的可插入HTTP用戶端也有實作特定的組態可能性。

逾時組態

您可以調整用戶端組態,以控制與服務呼叫相關的各種逾時。DynamoDB 與其他 DynamoDB 相比,提供較低的延遲 AWS 服務。因此,您可能想要將這些屬性調整為較低的逾時值,以便在發生聯網問題時可以快速失敗。

您可以在 DynamoDB 用戶端ClientOverrideConfiguration上使用 自訂延遲相關行為,或在基礎HTTP用戶端實作上變更詳細的組態選項。

您可以使用 設定下列具影響力的屬性ClientOverrideConfiguration

  • apiCallAttemptTimeout – 在捨棄和逾時之前,等待HTTP請求完成一次嘗試的時間長度。

  • apiCallTimeout – 用戶端必須完全執行API呼叫的時間量。這包括由所有HTTP請求組成的請求處理常式執行,包括重試。

AWS SDK for Java 2.x 提供一些逾時選項的預設值,例如連線逾時和通訊端逾時。SDK 不提供API呼叫逾時或個別API呼叫嘗試逾時的預設值。如果未在 中設定這些逾時ClientOverrideConfiguration,則 SDK會使用通訊端逾時值,而非整體API呼叫逾時。通訊端逾時的預設值為 30 秒。

RetryMode

另一個與您應該考慮的逾時組態相關的組態是RetryMode組態物件。此組態物件包含重試行為的集合。

SDK for Java 2.x 支援下列重試模式:

  • legacy – 如果您未明確變更,則預設重試模式。此重試模式專屬於 Java SDK。其特徵為最多三次重試,或針對 DynamoDB 等服務進行多次重試,而 DynamoDB 最多有八次重試。

  • standard – 命名為「標準」,因為它與其他 更一致 AWS SDKs。此模式會等待從 0 毫秒到 1,000 毫秒的隨機時間量進行第一次重試。如果需要再次重試,則此模式會挑選從 0 毫秒到 1,000 毫秒的另一個隨機時間,並乘以 2。如果需要額外的重試,則會執行相同的隨機挑選乘以四,以此類推。每次等待的上限為 20 秒。相較於 legacy 模式,此模式會針對更多偵測到的失敗條件執行重試。對於 DynamoDB,除非您使用 覆寫,否則它最多會執行三次總計嘗試次數上限numRetries

  • adaptive – 以 standard 模式為基礎,並動態限制 AWS 請求率,以最大限度地提高成功率。這可能會產生請求延遲。當可預測延遲很重要時,我們不建議調整重試模式。

您可以在 AWS SDKs和 工具參考指南中的重試行為主題中找到這些重試模式的擴展定義。

重試政策

所有RetryMode組態都有 RetryPolicy,其建置是以一或多個RetryCondition組態為基礎。對 DynamoDB SDK用戶端實作的重試行為TokenBucketRetryCondition尤其重要。此條件會限制 使用字符儲存貯體演算法SDK進行的重試次數。根據選取的重試模式,調節例外狀況可能會也可能不會從 中減去權杖TokenBucket

當用戶端遇到可重試錯誤,例如限流例外狀況或暫時性伺服器錯誤時, SDK會自動重試請求。您可以控制這些重試的次數和速度。

設定用戶端時,您可以提供支援下列參數RetryPolicy的 :

  • numRetries – 請求被視為失敗之前應套用的重試次數上限。無論您使用的重試模式為何,預設值都是 8。

    警告

    請務必在適當考量後變更此預設值。

  • backoffStrategyBackoffStrategy套用至重試的 ,其FullJitterBackoffStrategy為預設策略。此策略會根據目前的數量或重試次數、基本延遲和最長退避時間,在額外的重試之間執行指數延遲。然後,它會新增抖動以提供一點隨機性。無論重試模式為何,指數延遲中使用的基本延遲為 25 毫秒。

  • retryConditionRetryCondition決定是否完全重試請求。根據預設,它會重試一組其認為可重試的特定HTTP狀態碼和例外狀況。在大多數情況下,預設組態應該足夠。

下列程式碼提供替代重試政策。它總共指定五個重試 (總共六個請求)。第一次重試應該在延遲大約 100 毫秒之後發生,每次額外的重試都會將該時間成指數倍增,最多延遲一秒鐘。

DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(ClientOverrideConfiguration.builder() .retryPolicy(RetryPolicy.builder() .backoffStrategy(FullJitterBackoffStrategy.builder() .baseDelay(Duration.ofMillis(100)) .maxBackoffTime(Duration.ofSeconds(1)) .build()) .numRetries(5) .build()) .build()) .build();

DefaultsMode

ClientOverrideConfigurationRetryMode不管理的逾時屬性通常透過指定 來隱含設定DefaultsMode

AWS SDK for Java 2.x (2.17.102 版或更新版本) 推出對 的支援DefaultsMode。此功能提供一組常見可配置設定的預設值,例如HTTP通訊設定、重試行為、服務區域端點設定,以及可能的任何 SDK相關組態。使用此功能時,您可以取得針對常見使用案例量身打造的新組態預設值。

預設模式會標準化所有 AWS SDKs。SDK for Java 2.x 支援下列預設模式:

  • legacy – 提供預設設定,其會因 AWS DefaultsMode 而不同,SDK且之前已存在。

  • standard – 提供大多數案例的預設非最佳化設定。

  • in-region – 以標準模式為基礎,並包含為 AWS 服務 在相同 內呼叫的應用程式量身打造的設定 AWS 區域。

  • cross-region – 以標準模式建置,並包含在不同 AWS 服務 區域中呼叫的應用程式具有高逾時的設定。

  • mobile – 以標準模式為基礎,並包含為具有較高延遲的行動應用程式量身打造的高逾時設定。

  • auto – 以標準模式建置,並包含實驗性功能。會SDK嘗試探索執行期環境,以自動判斷適當的設定。自動偵測是以啟發式為基礎,不提供 100% 的準確性。如果無法判斷執行時間環境,則會使用標準模式。自動偵測可能會查詢執行個體中繼資料和使用者資料,這可能會導致延遲。如果啟動延遲對您的應用程式至關重要,我們建議您DefaultsMode改為選擇明確。

您可以透過下列方式設定預設模式:

  • 直接在用戶端上,透過 AwsClientBuilder.Builder#defaultsMode(DefaultsMode)

  • 在組態設定檔上,透過defaults_mode設定檔檔案屬性。

  • 全域,透過aws.defaultsMode系統屬性。

  • 全域,透過AWS_DEFAULTS_MODE環境變數。

注意

對於 以外的任何模式legacy,已結束的預設值可能會隨著最佳實務的發展而變更。因此,如果您使用 以外的模式legacy,建議您在升級 時執行測試SDK。

AWS SDKs 和 工具參考指南中的智慧組態預設值提供不同預設模式中的組態屬性及其預設值清單。

您可以根據應用程式的特性和應用程式互動 AWS 服務 的 ,選擇預設模式值。

這些值設定時 AWS 服務 考量了 的廣泛選擇。對於 DynamoDB 資料表和應用程式都部署在一個區域中的典型 DynamoDB 部署,in-region預設模式在standard預設模式之間最為相關。

範例 DynamoDB SDK用戶端組態已針對低延遲呼叫進行調校

下列範例會將逾時調整為預期低延遲 DynamoDB 呼叫的較低值。

DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder() .defaultsMode(DefaultsMode.IN_REGION) .httpClientBuilder(AwsCrtAsyncHttpClient.builder()) .overrideConfiguration(ClientOverrideConfiguration.builder() .apiCallTimeout(Duration.ofSeconds(3)) .apiCallAttemptTimeout(Duration.ofMillis(500)) .build()) .build();

個別HTTP用戶端實作可能會為您提供對逾時和連線使用行為的更精細控制。例如,對於 AWS CRT型用戶端,您可以啟用 ConnectionHealthConfiguration,這可讓用戶端主動監控已使用連線的運作狀態。如需詳細資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的AWS CRT以 為基礎的HTTP用戶端進階組態

Keep-Alive 組態

啟用保持連線可透過重複使用連線來減少延遲。有兩種不同類型的保持運作:HTTP保持運作和TCP保持運作。

  • HTTP Keep-Alive 會嘗試維護用戶端和伺服器之間的HTTPS連線,以便稍後的請求可以重複使用該連線。這會略過稍後請求的重型HTTPS身分驗證。 HTTP在預設情況下,所有用戶端都會啟用 Keep-Alive。

  • TCP Keep-Alive 請求基礎作業系統透過通訊端連線傳送小封包,以額外確保通訊端保持運作狀態,並立即偵測任何下降。這可確保稍後的請求不會花時間嘗試使用捨棄的通訊端。根據預設,所有用戶端上的 TCP Keep-Alive 都會停用。下列程式碼範例示範如何在每個HTTP用戶端上啟用它。為所有非CRT 用戶端啟用時HTTP,實際的 Keep-Alive 機制取決於作業系統。因此,您必須透過作業系統設定其他 TCP Keep-Alive 值,例如逾時和封包數量。您可以在 Linux 或 macOS sysctl 上使用 ,或在 Windows 上使用登錄值。

範例 在 Apache 型HTTP用戶端上啟用 TCP Keep-Alive
DynamoDbClient client = DynamoDbClient.builder() .httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true)) .build();
URLConnection型HTTP用戶端

任何使用 URLConnection型用戶端的同步HTTP用戶端HttpURLConnection都沒有機制來啟用保持連線。

範例 在 Netty 型HTTP用戶端上啟用TCP保持運作
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder() .httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true)) .build();
範例 在 AWS CRT以 為基礎的HTTP用戶端上啟用 TCP Keep-Alive

使用 AWS CRT型HTTP用戶端,您可以啟用TCP保持連線並控制持續時間。

DynamoDbClient client = DynamoDbClient.builder() .httpClientBuilder(AwsCrtHttpClient.builder() .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder() .keepAliveInterval(Duration.ofSeconds(50)) .keepAliveTimeout(Duration.ofSeconds(5)) .build())) .build();

使用非同步 DynamoDB 用戶端時,您可以啟用 TCP Keep-Alive,如下列程式碼所示。

DynamoDbAsyncClient client = DynamoDbAsyncClient.builder() .httpClientBuilder(AwsCrtAsyncHttpClient.builder() .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder() .keepAliveInterval(Duration.ofSeconds(50)) .keepAliveTimeout(Duration.ofSeconds(5)) .build())) .build();

錯誤處理

處理例外狀況時, AWS SDK for Java 2.x 會使用執行時間 (未勾選) 例外狀況。

涵蓋所有SDK例外的基本例外狀況是 SdkServiceException,其延伸自 Java 未檢查的 RuntimeException。如果您發現這種情況,您將會發現擲SDK出的所有例外狀況。

SdkServiceException 有名為 的子類別AwsServiceException。此子類別表示與 通訊時的任何問題 AWS 服務。它有一個名為 的子類別DynamoDbException,表示與 DynamoDB 通訊時發生問題。如果您發現這種情況,您將會發現與 DynamoDB 相關的所有例外狀況,但不會發現其他SDK例外狀況。

在 下有更具體的例外狀況類型DynamoDbException。其中一些例外狀況類型適用於控制平面操作,例如 TableAlreadyExistsException。其他則適用於資料平面操作。以下是常見的資料平面例外狀況範例:

  • ConditionalCheckFailedException – 您在 請求中指定了評估為 false 的條件。例如,您可能已嘗試對項目執行條件式更新,但屬性的實際值不符合條件中的預期值。不會重試以此方式失敗的請求。

其他情況未定義特定例外狀況。例如,當您的請求受到節流時,特定 ProvisionedThroughputExceededException可能會擲出,而在其他情況下DynamoDbException擲出更通用的 。在任何一種情況下,您都可以檢查 是否isThrottlingException()傳回 ,以判斷限流是否導致例外狀況true

根據您的應用程式需求,您可以擷取所有 AwsServiceExceptionDynamoDbException執行個體。不過,在不同的情況下,您通常需要不同的行為。處理條件檢查失敗的邏輯與處理調節的邏輯不同。定義您要處理哪些例外路徑,並確保測試替代路徑。這可協助您確保可以處理所有相關案例。

如需您可能遇到的常見錯誤清單,請參閱 使用 DynamoDB 時發生錯誤。另請參閱 Amazon DynamoDB API參考中的常見錯誤。API 參考也提供每個API操作的確切錯誤,例如 Query操作。如需處理例外狀況的資訊,請參閱《 AWS SDK for Java 2.x 開發人員指南》中的 例外狀況處理 AWS SDK for Java 2.x

AWS 請求 ID

每個請求都包含一個請求 ID,如果您使用 AWS 支援 來診斷問題,這對於提取很有幫助。衍生自 的每個例外SdkServiceException狀況都有一個requestId()方法來擷取請求 ID。

日誌

使用 SDK提供的 日誌記錄,對於從用戶端程式庫擷取任何重要訊息以及更深入的偵錯目的都很有用。記錄器是階層式的,而 SDK會使用 software.amazon.awssdk做為其根記錄器。您可以使用 TRACEDEBUG、、、ALLINFO WARN ERROR或 之一來設定關卡OFF。設定的層級會套用到該記錄器,並向下到記錄器階層。

對於其記錄, AWS SDK for Java 2.x 使用適用於 Java 的 Simple Logging Façade (SLF4J)。這可做為其他記錄器周圍的抽象層,您可以使用它來插入您偏好的記錄器。如需在記錄器中插入 的說明,請參閱 SLF4J使用者手冊

每個記錄器都有特定的行為。根據預設,Log4j 2.x 記錄器會建立 ConsoleAppender,其會將日誌事件附加至 ,System.out並預設為ERROR日誌層級。

SLF4J 輸出中包含的 SimpleLogger 記錄器預設為 System.err,預設為 INFO記錄層級。

我們建議您WARNsoftware.amazon.awssdk針對任何生產部署將 的關卡設定為 ,以從 SDK用戶端程式庫擷取任何重要訊息,同時限制輸出數量。

如果 SLF4J 無法在類別路徑 (無SLF4J繫結) 上找到支援的記錄器,則會預設為無操作實作。此實作會記錄訊息,以System.err解釋SLF4J在 classpath 上找不到記錄器實作的情況。若要避免這種情況,您必須新增記錄器實作。若要這樣做,您可以在成品pom.xml上新增 Apache Maven 中的相依性,例如 org.slf4j.slf4j-simpleorg.apache.logging.log4j.log4j-slf4j2-imp

如需如何在 中設定記錄的資訊SDK,包括將記錄相依性新增至應用程式組態,請參閱《 AWS SDK for Java 開發人員指南》中的使用SDK適用於 Java 2.x 的 進行記錄

Log4j2.xml 檔案中的下列組態顯示,如果您使用 Apache Log4j 2 記錄器,如何調整記錄行為。此組態會將根記錄器層級設定為 WARN。階層中的所有記錄器都會繼承此記錄層級,包括software.amazon.awssdk記錄器。

根據預設,輸出會移至 System.out。在下列範例中,我們仍然覆寫預設輸出 Log4j 附加元件,以套用量身打造的 Log4jPatternLayout

Log4j2.xml組態檔案的範例

下列組態會將訊息記錄到 主控台的所有記錄器階層的 ERRORWARN層級。

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="WARN"> <AppenderRef ref="ConsoleAppender"/> </Root> </Loggers> </Configuration>

AWS 請求 ID 記錄

當發生問題時,您可以在例外狀況IDs中找到請求。不過,如果您想要IDs請求未產生例外狀況的請求,您可以使用 記錄。

software.amazon.awssdk.request 記錄器IDs會在DEBUG關卡輸出請求。下列範例擴展先前的 configuration example ,將根記錄器層級保持在 ERROR、層級 software.amazon.awssdkWARN和層級 software.amazon.awssdk.requestDEBUG。設定這些層級有助於擷取請求IDs和其他請求相關詳細資訊,例如端點和狀態碼。

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="ERROR"> <AppenderRef ref="ConsoleAppender"/> </Root> <Logger name="software.amazon.awssdk" level="WARN" /> <Logger name="software.amazon.awssdk.request" level="DEBUG" /> </Loggers> </Configuration>

以下為日誌輸出的範例:

2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[]) 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available

分頁

有些請求,例如 QueryScan,會限制單一請求上傳回的資料大小,並要求您重複提出請求以提取後續頁面。

您可以使用 Limit 參數控制每個頁面要讀取的項目數量上限。例如,您可以使用 Limit 參數,僅擷取最後 10 個項目。此限制指定套用任何篩選之前要從資料表讀取的項目數量。如果您在篩選後只想要 10 個項目,則無法指定該項目。您只能控制預先篩選的計數,並在實際擷取 10 個項目時檢查用戶端。無論限制為何,回應的大小一律上限為 1 MB。

回應中LastEvaluatedKey可能包含 API。這表示回應因為達到計數限制或大小限制而結束。此金鑰是針對該回應評估的最後一個金鑰。透過直接與 互動API,您可以擷取此 並將其LastEvaluatedKey傳遞至後續呼叫ExclusiveStartKey,以讀取該起點的下一個區塊。如果LastEvaluatedKey沒有傳回任何 ,表示沒有更多符合 QueryScanAPI呼叫的項目。

下列範例使用低階界面,根據 keyConditionExpression 參數將項目限制為 100。

QueryRequest.Builder queryRequestBuilder = QueryRequest.builder() .expressionAttributeValues(Map.of( ":pk_val", AttributeValue.fromS("123"), ":sk_val", AttributeValue.fromN("1000"))) .keyConditionExpression("pk = :pk_val AND sk > :sk_val") .limit(100) .tableName(TABLE_NAME); while (true) { QueryResponse queryResponse = DYNAMODB_CLIENT.query(queryRequestBuilder.build()); queryResponse.items().forEach(item -> { LOGGER.info("item PK: [" + item.get("pk") + "] and SK: [" + item.get("sk") + "]"); }); if (!queryResponse.hasLastEvaluatedKey()) { break; } queryRequestBuilder.exclusiveStartKey(queryResponse.lastEvaluatedKey()); }

AWS SDK for Java 2.x 可以透過提供自動移植方法,進行多次服務呼叫,以自動為您取得下頁的結果,簡化與 DynamoDB 的互動。這可簡化您的程式碼,但會取消一些控制,讓您手動讀取頁面來保留資源用量。

透過使用 DynamoDB 用戶端中可用的Iterable方法,例如 QueryPaginatorScanPaginator, SDK會負責分頁。這些方法的傳回類型是自訂可疊代,可用於在所有頁面中反覆運算。SDK 內部會為您處理服務呼叫。您可以使用 Java Stream API處理 的結果QueryPaginator,如下列範例所示。

QueryPublisher queryPublisher = DYNAMODB_CLIENT.queryPaginator(QueryRequest.builder() .expressionAttributeValues(Map.of( ":pk_val", AttributeValue.fromS("123"), ":sk_val", AttributeValue.fromN("1000"))) .keyConditionExpression("pk = :pk_val AND sk > :sk_val") .limit(100) .tableName("YourTableName") .build()); queryPublisher.items().subscribe(item -> System.out.println(item.get("itemData"))).join();

資料類別註釋

Java SDK提供數個註釋,您可以將這些註釋放在資料類別的屬性上。這些註釋會影響 與 屬性SDK的互動方式。透過新增註釋,您可以讓 屬性做為隱含原子計數器,維護自動產生的時間戳記值,或追蹤項目版本號碼。如需詳細資訊,請參閱 資料類別註釋

隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。