

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

# 適用於 Java 的 Amazon QLDB 驅動程式
<a name="getting-started.java"></a>

**重要**  
支援終止通知：現有客戶將可以使用 Amazon QLDB，直到 07/31/2025 的支援結束為止。如需詳細資訊，請參閱[將 Amazon QLDB Ledger 遷移至 Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/)。

若要使用 分類帳中的資料，您可以使用 AWS 提供的驅動程式，從 Java 應用程式連線至 Amazon QLDB。下列主題說明如何開始使用適用於 Java 的 QLDB 驅動程式。

**Topics**
+ [

## 驅動程式資源
](#getting-started.java.resources)
+ [

## 先決條件
](#getting-started.java.prereqs)
+ [

## 設定您的預設 AWS 登入資料和區域
](#getting-started.java.credentials)
+ [

## 安裝
](#getting-started.java.install)
+ [快速入門教學課程](driver-quickstart-java.md)
+ [技術指南參考](driver-cookbook-java.md)

## 驅動程式資源
<a name="getting-started.java.resources"></a>

如需 Java 驅動程式支援功能的詳細資訊，請參閱下列資源：
+ API 參考：[2.x](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/)、[1.x](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/1.1.0/index.html)
+ [驅動程式原始碼 (GitHub)](https://github.com/awslabs/amazon-qldb-driver-java)
+ [應用程式原始碼範例 (GitHub)](https://github.com/aws-samples/amazon-qldb-dmv-sample-java)
+ [Ledger 載入器架構 (GitHub)](https://github.com/awslabs/amazon-qldb-ledger-load-java)
+ [Amazon Ion 程式碼範例](ion.code-examples.md)

## 先決條件
<a name="getting-started.java.prereqs"></a>

開始使用適用於 Java 的 QLDB 驅動程式之前，您必須執行下列動作：

1. 請遵循 中的 AWS 設定指示[存取 Amazon QLDB](accessing.md)。這包含下列項目：

   1. 註冊 AWS。

   1. 建立具有適當 QLDB 許可的使用者。

   1. 授予開發的程式設計存取權。

1. 透過下載並安裝下列項目來設定 Java 開發環境：

   1. Java SE 開發套件 8，例如 [Amazon Corretto 8](https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/downloads-list.html)。

   1. （選用） 您選擇的 Java 整合開發環境 (IDE)，例如 [Eclipse](http://www.eclipse.org) 或 [IntelliJ](https://www.jetbrains.com/idea/)。

1. 透過 適用於 Java 的 AWS SDK 設定 的開發環境[設定您的預設 AWS 登入資料和區域](#getting-started.java.credentials)。

接下來，您可以下載完整的教學課程範例應用程式，或者您只能在 Java 專案中安裝驅動程式並執行短程式碼範例。
+ 若要在現有專案 適用於 Java 的 AWS SDK 中安裝 QLDB 驅動程式和 ，請繼續[安裝](#getting-started.java.install)。
+ 若要設定專案並執行示範分類帳上基本資料交易的簡短程式碼範例，請參閱 [快速入門教學課程](driver-quickstart-java.md)。
+ 若要在完整的教學課程範例應用程式中執行更深入的資料和管理 API 操作範例，請參閱 [Java 教學課程](getting-started.java.tutorial.md)。

## 設定您的預設 AWS 登入資料和區域
<a name="getting-started.java.credentials"></a>

QLDB 驅動程式和基礎 [適用於 Java 的 AWS SDK](https://aws.amazon.com/sdk-for-java)需要您在執行時間提供 AWS 登入資料給應用程式。本指南中的程式碼範例假設您使用的是 AWS 登入資料檔案，如 *AWS SDK for Java 2.x 開發人員指南*中的[設定預設登入資料和區域](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials)中所述。

在這些步驟中，您也應該設定預設值 AWS 區域 來判斷預設的 QLDB 端點。程式碼範例會連接到預設 中的 QLDB AWS 區域。如需可使用 QLDB 的區域完整清單，請參閱 中的 [Amazon QLDB 端點和配額](https://docs.aws.amazon.com/general/latest/gr/qldb.html)*AWS 一般參考*。

以下是名為 的 AWS 登入資料檔案範例`~/.aws/credentials`，其中的波浪字元 (`~`) 代表您的主目錄。

```
[default] 
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
```

將您自己的 AWS 登入資料值替換為 *your\$1access\$1key\$1id* 和 *your\$1secret\$1access\$1key* 的值。

## 安裝
<a name="getting-started.java.install"></a>

QLDB 支援下列 Java 驅動程式版本及其 AWS SDK 相依性。


****  

| 驅動程式版本 | AWS 開發套件 | Status | 最新發行日期 | 
| --- | --- | --- | --- | 
| [1.x](https://search.maven.org/artifact/software.amazon.qldb/amazon-qldb-driver-java/1.1.0/jar) | 適用於 Java 的 AWS SDK 1.x | 生產版本 | 2020 年 3 月 20 日 | 
| [2.x](https://search.maven.org/artifact/software.amazon.qldb/amazon-qldb-driver-java/2.3.1/jar) | AWS SDK for Java 2.x | 生產版本 | 2021 年 6 月 4 日 | 

若要安裝 QLDB 驅動程式，我們建議您使用相依性管理系統，例如 Gradle 或 Maven。例如，在 Java 專案中新增下列成品做為相依性。

------
#### [ 2.x ]

**漸層**

在`build.gradle`組態檔案中新增此相依性。

```
dependencies {
    compile group: 'software.amazon.qldb', name: 'amazon-qldb-driver-java', version: '2.3.1'
}
```

**Maven**

在`pom.xml`組態檔案中新增此相依性。

```
<dependencies>
  <dependency>
    <groupId>software.amazon.qldb</groupId>
    <artifactId>amazon-qldb-driver-java</artifactId>
    <version>2.3.1</version>
  </dependency>
</dependencies>
```

此成品會自動包含 AWS SDK for Java 2.x 核心模組、[Amazon Ion](ion.md) 程式庫和其他必要的相依性。

------
#### [ 1.x ]

**漸層**

在`build.gradle`組態檔案中新增此相依性。

```
dependencies {
    compile group: 'software.amazon.qldb', name: 'amazon-qldb-driver-java', version: '1.1.0'
}
```

**Maven**

在`pom.xml`組態檔案中新增此相依性。

```
<dependencies>
  <dependency>
    <groupId>software.amazon.qldb</groupId>
    <artifactId>amazon-qldb-driver-java</artifactId>
    <version>1.1.0</version>
  </dependency>
</dependencies>
```

此成品會自動包含 適用於 Java 的 AWS SDK 核心模組、[Amazon Ion](ion.md) 程式庫和其他必要的相依性。

**重要**  
**Amazon Ion 命名空間** – 在應用程式中匯入 Amazon Ion 類別時，您必須使用位於命名空間 下的套件`com.amazon.ion`。 適用於 Java 的 AWS SDK 取決於命名空間 下的另一個 Ion 套件`software.amazon.ion`，但這是與 QLDB 驅動程式不相容的舊版套件。

------

如需如何在分類帳上執行基本資料交易的簡短程式碼範例，請參閱 [技術指南參考](driver-cookbook-java.md)。

### 其他選用程式庫
<a name="getting-started.java.install-optional"></a>

您也可以選擇性地在專案中新增下列有用的程式庫。這些成品是[Java 教學課程](getting-started.java.tutorial.md)範例應用程式中的必要相依性。

1. [aws-java-sdk-qldb](https://search.maven.org/artifact/com.amazonaws/aws-java-sdk-qldb/1.11.785/jar) – 的 QLDB 模組 適用於 Java 的 AWS SDK。QLDB 支援的最小版本為 `1.11.785`。

   在應用程式中使用此模組，直接與 中列出的管理 API 操作互動[Amazon QLDB API 參考](api-reference.md)。

1. [jackson-dataformat-ion](https://search.maven.org/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-ion/2.10.0/bundle) – 適用於 Ion 的 FasterXML 的 Jackson 資料格式模組。範例應用程式需要 版本 `2.10.0` 或更新版本。

------
#### [ Gradle ]

在`build.gradle`組態檔案中新增這些相依性。

```
dependencies {
    compile group: 'com.amazonaws', name: 'aws-java-sdk-qldb', version: '1.11.785'
    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-ion', version: '2.10.0'
}
```

------
#### [ Maven ]

在`pom.xml`組態檔案中新增這些相依性。

```
<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-qldb</artifactId>
    <version>1.11.785</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-ion</artifactId>
    <version>2.10.0</version>
  </dependency>
</dependencies>
```

------

# 適用於 Java 的 Amazon QLDB 驅動程式 – 快速入門教學課程
<a name="driver-quickstart-java"></a>

**重要**  
支援終止通知：現有客戶將可以使用 Amazon QLDB，直到 07/31/2025 的支援結束為止。如需詳細資訊，請參閱[將 Amazon QLDB Ledger 遷移至 Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/)。

在本教學課程中，您將了解如何使用適用於 Java 的最新版本 Amazon QLDB 驅動程式來設定簡單的應用程式。本指南包含安裝驅動程式的步驟，以及基本*建立、讀取、更新和刪除* (CRUD) 操作的簡短程式碼範例。如需在完整範例應用程式中示範這些操作的更深入範例，請參閱 [Java 教學課程](getting-started.java.tutorial.md)。

**Topics**
+ [

## 先決條件
](#driver-quickstart-java.prereqs)
+ [

## 步驟 1：設定您的 專案
](#driver-quickstart-java.step-1)
+ [

## 步驟 2：初始化驅動程式
](#driver-quickstart-java.step-2)
+ [

## 步驟 3：建立資料表和索引
](#driver-quickstart-java.step-3)
+ [

## 步驟 4：插入文件
](#driver-quickstart-java.step-4)
+ [

## 步驟 5：查詢文件
](#driver-quickstart-java.step-5)
+ [

## 步驟 6：更新文件
](#driver-quickstart-java.step-6)
+ [

## 執行完整的應用程式
](#driver-quickstart-java.complete)

## 先決條件
<a name="driver-quickstart-java.prereqs"></a>

開始之前，請務必執行下列動作：

1. 如果您尚未執行此操作，請完成 Java 驅動程式[先決條件](getting-started.java.md#getting-started.java.prereqs)的 。這包括註冊 AWS、授予開發的程式設計存取權，以及安裝 Java 整合開發環境 (IDE)。

1. 建立名為 的分類帳`quick-start`。

   若要了解如何建立分類帳，請參閱 主控台入門[步驟 1：建立新的分類帳](getting-started-step-1.md)中的 [Amazon QLDB 分類帳的基本操作](ledger-management.basics.md)或 。 **

## 步驟 1：設定您的 專案
<a name="driver-quickstart-java.step-1"></a>

首先，設定您的 Java 專案。建議您在本教學課程中使用 [Maven](https://maven.apache.org/index.html) 相依性管理系統。

**注意**  
如果您使用具有自動化這些設定步驟功能的 IDE，您可以直接跳到 [步驟 2：初始化驅動程式](#driver-quickstart-java.step-2)。

1. 為您的應用程式建立資料夾。

   ```
   $ mkdir myproject
   $ cd myproject
   ```

1. 輸入下列命令，從 Maven 範本初始化您的專案。視需要將 *project-package*、*project-name* 和 *maven-template* 取代為您自己的值。

   ```
   $ mvn archetype:generate
     -DgroupId=project-package \
     -DartifactId=project-name \
     -DarchetypeArtifactId=maven-template \
     -DinteractiveMode=false
   ```

   對於 *maven-template*，您可以使用基本 Maven 範本： `maven-archetype-quickstart`

1. 若要將適用於 [Java 的 QLDB 驅動程式](https://search.maven.org/artifact/software.amazon.qldb/amazon-qldb-driver-java/2.3.1/jar)新增為專案相依性，請導覽至新建立`pom.xml`的檔案，並新增下列成品。

   ```
   <dependency>
       <groupId>software.amazon.qldb</groupId>
       <artifactId>amazon-qldb-driver-java</artifactId>
       <version>2.3.1</version>
   </dependency>
   ```

   此成品會自動包含[AWS SDK for Java 2.x](https://aws.amazon.com/sdk-for-java)核心模組、[Amazon Ion](ion.md) 程式庫和其他必要的相依性。您的`pom.xml`檔案現在看起來應該類似於以下內容。

   ```
   <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/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>software.amazon.qldb</groupId>
     <artifactId>qldb-quickstart</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>qldb-quickstart</name>
     <url>http://maven.apache.org</url>
     <dependencies>
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>software.amazon.qldb</groupId>
           <artifactId>amazon-qldb-driver-java</artifactId>
           <version>2.3.1</version>
       </dependency>
     </dependencies>
   </project>
   ```

1. 開啟 `App.java` 檔案。

   然後，在下列步驟中逐步新增程式碼範例，以嘗試一些基本的 CRUD 操作。或者，您可以略過step-by-step教學課程，改為執行[完整的應用程式](#driver-quickstart-java.complete)。

## 步驟 2：初始化驅動程式
<a name="driver-quickstart-java.step-2"></a>

初始化連接至名為 之分類帳的驅動程式執行個體`quick-start`。將下列程式碼新增至您的 `App.java` 檔案。

```
import java.util.*;
import com.amazon.ion.*;
import com.amazon.ion.system.*;
import software.amazon.awssdk.services.qldbsession.QldbSessionClient;
import software.amazon.qldb.*;

public final class App {
    public static IonSystem ionSys = IonSystemBuilder.standard().build();
    public static QldbDriver qldbDriver;

    public static void main(final String... args) {
        System.out.println("Initializing the driver");
        qldbDriver = QldbDriver.builder()
            .ledger("quick-start")
            .transactionRetryPolicy(RetryPolicy
                .builder()
                .maxRetries(3)
                .build())
            .sessionClientBuilder(QldbSessionClient.builder())
            .build();
    }
}
```

## 步驟 3：建立資料表和索引
<a name="driver-quickstart-java.step-3"></a>

下列程式碼範例示範如何執行 `CREATE TABLE`和 `CREATE INDEX`陳述式。

在 `main`方法中，新增下列程式碼，為該資料表上的 `lastName` 欄位建立名為 的資料表`People`和索引。需要[索引](ql-reference.create-index.md)才能最佳化查詢效能，並協助限制[樂觀並行控制 (OCC)](concurrency.md) 衝突例外狀況。

```
// Create a table and an index in the same transaction
qldbDriver.execute(txn -> {
    System.out.println("Creating a table and an index");
    txn.execute("CREATE TABLE People");
    txn.execute("CREATE INDEX ON People(lastName)");
});
```

## 步驟 4：插入文件
<a name="driver-quickstart-java.step-4"></a>

下列程式碼範例示範如何執行 `INSERT`陳述式。QLDB 支援 [PartiQL](ql-reference.md) 查詢語言 (SQL 相容） 和 [Amazon Ion](ion.md) 資料格式 (JSON 的超級集）。

新增下列程式碼，將文件插入`People`資料表。

```
// Insert a document
qldbDriver.execute(txn -> {
    System.out.println("Inserting a document");
    IonStruct person = ionSys.newEmptyStruct();
    person.put("firstName").newString("John");
    person.put("lastName").newString("Doe");
    person.put("age").newInt(32);
    txn.execute("INSERT INTO People ?", person);
});
```

此範例使用問號 (`?`) 做為變數預留位置，將文件資訊傳遞至 陳述式。使用預留位置時，您必須傳遞 類型的值`IonValue`。

**提示**  
若要使用單一[INSERT](ql-reference.insert.md)陳述式插入多個文件，您可以將 [IonList](driver-working-with-ion.md#driver-ion-list) 類型的參數 （明確轉換為 `IonValue`) 傳遞至陳述式，如下所示。  

```
// people is an IonList explicitly cast as an IonValue
txn.execute("INSERT INTO People ?", (IonValue) people);
```
傳遞 時，您不會將變數預留位置 (`?`) 括在雙角度括號 `<<...>>` ( ) 中`IonList`。在手動 PartiQL 陳述式中，雙角括號表示稱為*包*的未排序集合。

## 步驟 5：查詢文件
<a name="driver-quickstart-java.step-5"></a>

下列程式碼範例示範如何執行 `SELECT`陳述式。

新增下列程式碼，以查詢`People`資料表中的文件。

```
// Query the document
qldbDriver.execute(txn -> {
    System.out.println("Querying the table");
    Result result = txn.execute("SELECT * FROM People WHERE lastName = ?",
            ionSys.newString("Doe"));
    IonStruct person = (IonStruct) result.iterator().next();
    System.out.println(person.get("firstName")); // prints John
    System.out.println(person.get("lastName")); // prints Doe
    System.out.println(person.get("age")); // prints 32
});
```

## 步驟 6：更新文件
<a name="driver-quickstart-java.step-6"></a>

下列程式碼範例示範如何執行 `UPDATE`陳述式。

1. 新增下列程式碼，透過更新`age`至 來更新`People`資料表中的文件`42`。

   ```
   // Update the document
   qldbDriver.execute(txn -> {
       System.out.println("Updating the document");
       final List<IonValue> parameters = new ArrayList<>();
       parameters.add(ionSys.newInt(42));
       parameters.add(ionSys.newString("Doe"));
       txn.execute("UPDATE People SET age = ? WHERE lastName = ?", parameters);
   });
   ```

1. 再次查詢文件以查看更新的值。

   ```
   // Query the updated document
   qldbDriver.execute(txn -> {
       System.out.println("Querying the table for the updated document");
       Result result = txn.execute("SELECT * FROM People WHERE lastName = ?",
               ionSys.newString("Doe"));
       IonStruct person = (IonStruct) result.iterator().next();
       System.out.println(person.get("firstName")); // prints John
       System.out.println(person.get("lastName")); // prints Doe
       System.out.println(person.get("age")); // prints 32
   });
   ```

1. 使用 Maven 或您的 IDE 來編譯和執行 `App.java` 檔案。

## 執行完整的應用程式
<a name="driver-quickstart-java.complete"></a>

下列程式碼範例是`App.java`應用程式的完整版本。您也可以從頭到尾複製並執行此程式碼範例，而不是個別執行上述步驟。此應用程式會在名為 的分類帳上示範一些基本 CRUD 操作`quick-start`。

**注意**  
在您執行此程式碼之前，請確定您尚未在分類帳`People`中擁有名為 `quick-start` 的作用中資料表。  
在第一行，將 *project-package* 取代為您在 中用於 Maven 命令`groupId`的值[步驟 1：設定您的 專案](#driver-quickstart-java.step-1)。

```
package project-package;

import java.util.*;
import com.amazon.ion.*;
import com.amazon.ion.system.*;
import software.amazon.awssdk.services.qldbsession.QldbSessionClient;
import software.amazon.qldb.*;

public class App {
    public static IonSystem ionSys = IonSystemBuilder.standard().build();
    public static QldbDriver qldbDriver;

    public static void main(final String... args) {
        System.out.println("Initializing the driver");
        qldbDriver = QldbDriver.builder()
            .ledger("quick-start")
            .transactionRetryPolicy(RetryPolicy
                .builder()
                .maxRetries(3)
                .build())
            .sessionClientBuilder(QldbSessionClient.builder())
            .build();

        // Create a table and an index in the same transaction
        qldbDriver.execute(txn -> {
            System.out.println("Creating a table and an index");
            txn.execute("CREATE TABLE People");
            txn.execute("CREATE INDEX ON People(lastName)");
        });
        
        // Insert a document
        qldbDriver.execute(txn -> {
            System.out.println("Inserting a document");
            IonStruct person = ionSys.newEmptyStruct();
            person.put("firstName").newString("John");
            person.put("lastName").newString("Doe");
            person.put("age").newInt(32);
            txn.execute("INSERT INTO People ?", person);
        });
        
        // Query the document
        qldbDriver.execute(txn -> {
            System.out.println("Querying the table");
            Result result = txn.execute("SELECT * FROM People WHERE lastName = ?",
                    ionSys.newString("Doe"));
            IonStruct person = (IonStruct) result.iterator().next();
            System.out.println(person.get("firstName")); // prints John
            System.out.println(person.get("lastName")); // prints Doe
            System.out.println(person.get("age")); // prints 32
        });
        
        // Update the document
        qldbDriver.execute(txn -> {
            System.out.println("Updating the document");
            final List<IonValue> parameters = new ArrayList<>();
            parameters.add(ionSys.newInt(42));
            parameters.add(ionSys.newString("Doe"));
            txn.execute("UPDATE People SET age = ? WHERE lastName = ?", parameters);
        });
        
        // Query the updated document
        qldbDriver.execute(txn -> {
            System.out.println("Querying the table for the updated document");
            Result result = txn.execute("SELECT * FROM People WHERE lastName = ?",
                    ionSys.newString("Doe"));
            IonStruct person = (IonStruct) result.iterator().next();
            System.out.println(person.get("firstName")); // prints John
            System.out.println(person.get("lastName")); // prints Doe
            System.out.println(person.get("age")); // prints 42
        });
    }
}
```

使用 Maven 或您的 IDE 來編譯和執行 `App.java` 檔案。

# 適用於 Java 的 Amazon QLDB 驅動程式 – Cookbook 參考
<a name="driver-cookbook-java"></a>

**重要**  
支援終止通知：現有客戶將可以使用 Amazon QLDB，直到 07/31/2025 的支援結束為止。如需詳細資訊，請參閱[將 Amazon QLDB Ledger 遷移至 Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/)。

此參考指南顯示適用於 Java 的 Amazon QLDB 驅動程式的常見使用案例。它提供 Java 程式碼範例，示範如何使用驅動程式執行基本的*建立、讀取、更新和刪除* (CRUD) 操作。它也包含處理 Amazon Ion 資料的程式碼範例。此外，本指南重點介紹了建立交易等冪和實作唯一性限制的最佳實務。

**注意**  
在適用的情況下，某些使用案例對於適用於 Java 的 QLDB 驅動程式的每個支援主要版本都有不同的程式碼範例。

**Contents**
+ [

## 匯入驅動程式
](#cookbook-java.importing)
+ [

## 執行個體化驅動程式
](#cookbook-java.instantiating)
+ [

## CRUD 操作
](#cookbook-java.crud)
  + [

### 建立資料表
](#cookbook-java.crud.creating-tables)
  + [

### 建立索引
](#cookbook-java.crud.creating-indexes)
  + [

### 讀取文件
](#cookbook-java.crud.reading)
  + [

### 插入文件
](#cookbook-java.crud.inserting)
    + [

#### 在一個陳述式中插入多個文件
](#cookbook-java.crud.inserting.multiple)
  + [

### 更新文件
](#cookbook-java.crud.updating)
  + [

### 刪除文件
](#cookbook-java.crud.deleting)
  + [

### 在交易中執行多個陳述式
](#cookbook-java.crud.multi-statement)
  + [

### 重試邏輯
](#cookbook-java.crud.retry-logic)
  + [

### 實作唯一性限制
](#cookbook-java.crud.uniqueness-constraints)
+ [

## 使用 Amazon Ion
](#cookbook-java.ion)
  + [

### 匯入 Ion 套件
](#cookbook-java.ion.importing)
  + [

### 初始化 Ion
](#cookbook-java.ion.initializing)
  + [

### 建立 Ion 物件
](#cookbook-java.ion.creating)
  + [

### 讀取 Ion 物件
](#cookbook-java.ion.reading)

## 匯入驅動程式
<a name="cookbook-java.importing"></a>

下列程式碼範例會匯入驅動程式、QLDB 工作階段用戶端、Amazon Ion 套件和其他相關相依性。

------
#### [ 2.x ]

```
import com.amazon.ion.IonStruct;
import com.amazon.ion.IonSystem;
import com.amazon.ion.IonValue;
import com.amazon.ion.system.IonSystemBuilder;

import software.amazon.awssdk.services.qldbsession.QldbSessionClient;
import software.amazon.qldb.QldbDriver;
import software.amazon.qldb.Result;
```

------
#### [ 1.x ]

```
import com.amazon.ion.IonStruct;
import com.amazon.ion.IonSystem;
import com.amazon.ion.IonValue;
import com.amazon.ion.system.IonSystemBuilder;

import com.amazonaws.services.qldbsession.AmazonQLDBSessionClientBuilder;
import software.amazon.qldb.PooledQldbDriver;
import software.amazon.qldb.Result;
```

------

## 執行個體化驅動程式
<a name="cookbook-java.instantiating"></a>

下列程式碼範例會建立連接至指定分類帳名稱的驅動程式執行個體，並使用具有自訂重試限制的指定[重試邏輯](#cookbook-java.crud.retry-logic)。

**注意**  
此範例也會執行個體化 Amazon Ion 系統物件 (`IonSystem`)。您需要此物件，才能在此參考中執行某些資料操作時處理 Ion 資料。如需進一步了解，請參閱 [使用 Amazon Ion](#cookbook-java.ion)。

------
#### [ 2.x ]

```
QldbDriver qldbDriver = QldbDriver.builder()
    .ledger("vehicle-registration")
    .transactionRetryPolicy(RetryPolicy
        .builder()
        .maxRetries(3)
        .build())
    .sessionClientBuilder(QldbSessionClient.builder())
    .build();

IonSystem SYSTEM = IonSystemBuilder.standard().build();
```

------
#### [ 1.x ]

```
PooledQldbDriver qldbDriver = PooledQldbDriver.builder()
    .withLedger("vehicle-registration")
    .withRetryLimit(3)
    .withSessionClientBuilder(AmazonQLDBSessionClientBuilder.standard())
    .build();

IonSystem SYSTEM = IonSystemBuilder.standard().build();
```

------

## CRUD 操作
<a name="cookbook-java.crud"></a>

QLDB 會在交易中執行*建立、讀取、更新和刪除* (CRUD) 操作。

**警告**  
最佳實務是，讓您的寫入交易嚴格具有等冪性。

**使交易具有等冪性**

我們建議您將寫入交易設為等冪，以避免重試時發生任何非預期的副作用。如果交易可以多次執行，並且每次產生相同的結果，則表示交易是*等*冪的。

例如，請考慮將文件插入名為 的資料表的交易`Person`。交易應先檢查資料表中是否已存在該文件。如果沒有此檢查，資料表最終可能會顯示重複的文件。

假設 QLDB 在伺服器端成功遞交交易，但用戶端在等待回應時逾時。如果交易不等冪，在重試的情況下，相同的文件可以插入多次。

**使用索引以避免完整資料表掃描**

我們也建議您在索引欄位或文件 ID 上使用*等式*運算子，使用`WHERE`述詞子來執行陳述式；例如， `WHERE indexedField = 123`或 `WHERE indexedField IN (456, 789)`。如果沒有此索引查詢，QLDB 需要執行資料表掃描，這可能會導致交易逾時或*樂觀並行控制* (OCC) 衝突。

如需 OCC 的詳細資訊，請參閱 [Amazon QLDB 並行模型](concurrency.md)。

**隱含建立的交易**

[QldbDriver.execute](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/software/amazon/qldb/QldbDriver.html) 方法接受 lambda 函數，該函數會接收 [Executor](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/software/amazon/qldb/Executor.html) 的執行個體，您可以用來執行陳述式。`Executor` 執行個體會包裝隱含建立的交易。

您可以使用 `Executor.execute`方法在 lambda 函數中執行陳述式。當 lambda 函數傳回時，驅動程式會隱含遞交交易。

下列各節說明如何執行基本 CRUD 操作、指定自訂重試邏輯，以及實作唯一性限制條件。

**注意**  
如適用，這些區段提供使用內建 Ion 程式庫和 Jackson Ion 映射器程式庫處理 Amazon Ion 資料的程式碼範例。如需進一步了解，請參閱 [使用 Amazon Ion](#cookbook-java.ion)。

**Contents**
+ [

### 建立資料表
](#cookbook-java.crud.creating-tables)
+ [

### 建立索引
](#cookbook-java.crud.creating-indexes)
+ [

### 讀取文件
](#cookbook-java.crud.reading)
+ [

### 插入文件
](#cookbook-java.crud.inserting)
  + [

#### 在一個陳述式中插入多個文件
](#cookbook-java.crud.inserting.multiple)
+ [

### 更新文件
](#cookbook-java.crud.updating)
+ [

### 刪除文件
](#cookbook-java.crud.deleting)
+ [

### 在交易中執行多個陳述式
](#cookbook-java.crud.multi-statement)
+ [

### 重試邏輯
](#cookbook-java.crud.retry-logic)
+ [

### 實作唯一性限制
](#cookbook-java.crud.uniqueness-constraints)

### 建立資料表
<a name="cookbook-java.crud.creating-tables"></a>

```
qldbDriver.execute(txn -> {
    txn.execute("CREATE TABLE Person");
});
```

### 建立索引
<a name="cookbook-java.crud.creating-indexes"></a>

```
qldbDriver.execute(txn -> {
    txn.execute("CREATE INDEX ON Person(GovId)");
});
```

### 讀取文件
<a name="cookbook-java.crud.reading"></a>

```
// Assumes that Person table has documents as follows:
// { GovId: "TOYENC486FH", FirstName: "Brent" }

qldbDriver.execute(txn -> {
    Result result = txn.execute("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'");
    IonStruct person = (IonStruct) result.iterator().next();
    System.out.println(person.get("GovId")); // prints TOYENC486FH
    System.out.println(person.get("FirstName")); // prints Brent
});
```

**使用查詢參數**

下列程式碼範例使用 Ion 類型查詢參數。

```
qldbDriver.execute(txn -> {
    Result result = txn.execute("SELECT * FROM Person WHERE GovId = ?",
            SYSTEM.newString("TOYENC486FH"));
    IonStruct person = (IonStruct) result.iterator().next();
    System.out.println(person.get("GovId")); // prints TOYENC486FH
    System.out.println(person.get("FirstName")); // prints Brent
});
```

下列程式碼範例使用多個查詢參數。

```
qldbDriver.execute(txn -> {
    Result result = txn.execute("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?",
            SYSTEM.newString("TOYENC486FH"),
            SYSTEM.newString("Brent"));
    IonStruct person = (IonStruct) result.iterator().next();
    System.out.println(person.get("GovId")); // prints TOYENC486FH
    System.out.println(person.get("FirstName")); // prints Brent
});
```

下列程式碼範例使用查詢參數的清單。

```
qldbDriver.execute(txn -> {
    final List<IonValue> parameters = new ArrayList<>();
    parameters.add(SYSTEM.newString("TOYENC486FH"));
    parameters.add(SYSTEM.newString("ROEE1"));
    parameters.add(SYSTEM.newString("YH844"));
    Result result = txn.execute("SELECT * FROM Person WHERE GovId IN (?,?,?)", parameters);
    IonStruct person = (IonStruct) result.iterator().next();
    System.out.println(person.get("GovId")); // prints TOYENC486FH
    System.out.println(person.get("FirstName")); // prints Brent
});
```

#### 使用 Jackson 映射器
<a name="cookbook-java.crud.reading.jackson"></a>

```
// Assumes that Person table has documents as follows:
// {GovId: "TOYENC486FH", FirstName: "Brent" }

qldbDriver.execute(txn -> {
    try {
        Result result = txn.execute("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'");
        Person person = MAPPER.readValue(result.iterator().next(), Person.class);
        System.out.println(person.getFirstName()); // prints Brent
        System.out.println(person.getGovId()); // prints TOYENC486FH
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

**使用查詢參數**

下列程式碼範例使用 Ion 類型查詢參數。

```
qldbDriver.execute(txn -> {
    try {
        Result result = txn.execute("SELECT * FROM Person WHERE GovId = ?",
                MAPPER.writeValueAsIonValue("TOYENC486FH"));
        Person person = MAPPER.readValue(result.iterator().next(), Person.class);
        System.out.println(person.getFirstName()); // prints Brent
        System.out.println(person.getGovId()); // prints TOYENC486FH
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

下列程式碼範例使用多個查詢參數。

```
qldbDriver.execute(txn -> {
    try {
        Result result = txn.execute("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?",
                MAPPER.writeValueAsIonValue("TOYENC486FH"),
                MAPPER.writeValueAsIonValue("Brent"));
        Person person = MAPPER.readValue(result.iterator().next(), Person.class);
        System.out.println(person.getFirstName()); // prints Brent
        System.out.println(person.getGovId()); // prints TOYENC486FH
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

下列程式碼範例使用查詢參數的清單。

```
qldbDriver.execute(txn -> {
    try {
        final List<IonValue> parameters = new ArrayList<>();
        parameters.add(MAPPER.writeValueAsIonValue("TOYENC486FH"));
        parameters.add(MAPPER.writeValueAsIonValue("ROEE1"));
        parameters.add(MAPPER.writeValueAsIonValue("YH844"));
        Result result = txn.execute("SELECT * FROM Person WHERE GovId IN (?,?,?)", parameters);
        Person person = MAPPER.readValue(result.iterator().next(), Person.class);
        System.out.println(person.getFirstName()); // prints Brent
        System.out.println(person.getGovId()); // prints TOYENC486FH
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

**注意**  
當您在沒有索引查詢的情況下執行查詢時，它會叫用完整的資料表掃描。在此範例中，我們建議在 `GovId` 欄位中具有[索引](ql-reference.create-index.md)，以最佳化效能。如果沒有 上的索引`GovId`，查詢可能會有更多延遲，也可能導致 OCC 衝突例外狀況或交易逾時。

### 插入文件
<a name="cookbook-java.crud.inserting"></a>

下列程式碼範例會插入 Ion 資料類型。

```
qldbDriver.execute(txn -> {
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    Result result = txn.execute("SELECT * FROM Person WHERE GovId = ?",
            SYSTEM.newString("TOYENC486FH"));
    // Check if there is a result
    if (!result.iterator().hasNext()) {
        IonStruct person = SYSTEM.newEmptyStruct();
        person.put("GovId").newString("TOYENC486FH");
        person.put("FirstName").newString("Brent");
        // Insert the document
        txn.execute("INSERT INTO Person ?", person);
    }
});
```

#### 使用 Jackson 映射器
<a name="cookbook-java.crud.inserting.jackson"></a>

下列程式碼範例會插入 Ion 資料類型。

```
qldbDriver.execute(txn -> {
    try {
        // Check if a document with GovId:TOYENC486FH exists
        // This is critical to make this transaction idempotent
        Result result = txn.execute("SELECT * FROM Person WHERE GovId = ?",
                MAPPER.writeValueAsIonValue("TOYENC486FH"));
        // Check if there is a result
        if (!result.iterator().hasNext()) {
            // Insert the document
            txn.execute("INSERT INTO Person ?",
                    MAPPER.writeValueAsIonValue(new Person("Brent", "TOYENC486FH")));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

此交易會將文件插入`Person`資料表。插入之前，它會先檢查文件是否已存在資料表中。**此檢查會讓交易具有等冪性質。**即使您多次執行此交易，也不會造成任何非預期的副作用。

**注意**  
在此範例中，我們建議在 `GovId` 欄位中具有索引，以最佳化效能。如果沒有 上的索引`GovId`，陳述式可能會有更多延遲，也可能導致 OCC 衝突例外狀況或交易逾時。

#### 在一個陳述式中插入多個文件
<a name="cookbook-java.crud.inserting.multiple"></a>

若要使用單一[INSERT](ql-reference.insert.md)陳述式插入多個文件，您可以將 [IonList](driver-working-with-ion.md#driver-ion-list) 類型的參數 （明確轉換為 `IonValue`) 傳遞至陳述式，如下所示。

```
// people is an IonList explicitly cast as an IonValue
txn.execute("INSERT INTO People ?", (IonValue) people);
```

傳遞 時，您不會將變數預留位置 (`?`) 括在雙角度括號 `<<...>>` ( ) 中`IonList`。在手動 PartiQL 陳述式中，雙角括號表示稱為*包*的未排序集合。

##### 為什麼需要明確轉換？
<a name="cookbook-java.crud.inserting.multiple.cast"></a>

[TransactionExecutor.execute](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/software/amazon/qldb/TransactionExecutor.html) 方法超載。它接受變數數量的`IonValue`引數 *（大體*) 或單一`List<IonValue>`引數。在 [ion-java](https://www.javadoc.io/doc/com.amazon.ion/ion-java/latest/index.html) 中， `IonList` 實作為 `List<IonValue>`。

當您呼叫過載方法時，Java 預設為最具體的方法實作。在此情況下，當您傳遞 `IonList` 參數時，它會預設為採用 的方法`List<IonValue>`。調用時，此方法實作會將清單的`IonValue`元素傳遞為不同的值。因此，若要改用 varargs 方法，您必須明確地將 `IonList` 參數轉換為 `IonValue`。

### 更新文件
<a name="cookbook-java.crud.updating"></a>

```
qldbDriver.execute(txn -> {
    final List<IonValue> parameters = new ArrayList<>();
    parameters.add(SYSTEM.newString("John"));
    parameters.add(SYSTEM.newString("TOYENC486FH"));
    txn.execute("UPDATE Person SET FirstName = ? WHERE GovId = ?", parameters);
});
```

#### 使用 Jackson 映射器
<a name="cookbook-java.crud.updating.jackson"></a>

```
qldbDriver.execute(txn -> {
    try {
        final List<IonValue> parameters = new ArrayList<>();
        parameters.add(MAPPER.writeValueAsIonValue("John"));
        parameters.add(MAPPER.writeValueAsIonValue("TOYENC486FH"));
        txn.execute("UPDATE Person SET FirstName = ? WHERE GovId = ?", parameters);
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

**注意**  
在此範例中，我們建議在 `GovId` 欄位中具有索引，以最佳化效能。如果沒有 上的索引`GovId`，陳述式可能會有更多延遲，也可能導致 OCC 衝突例外狀況或交易逾時。

### 刪除文件
<a name="cookbook-java.crud.deleting"></a>

```
qldbDriver.execute(txn -> {
    txn.execute("DELETE FROM Person WHERE GovId = ?",
            SYSTEM.newString("TOYENC486FH"));
});
```

#### 使用 Jackson 映射器
<a name="cookbook-java.crud.deleting.jackson"></a>

```
qldbDriver.execute(txn -> {
    try {
        txn.execute("DELETE FROM Person WHERE GovId = ?",
                MAPPER.writeValueAsIonValue("TOYENC486FH"));
    } catch (IOException e) {
        e.printStackTrace();
    }
});
```

**注意**  
在此範例中，我們建議在 `GovId` 欄位中具有索引，以最佳化效能。如果沒有 上的索引`GovId`，陳述式可能會有更多延遲，也可能導致 OCC 衝突例外狀況或交易逾時。

### 在交易中執行多個陳述式
<a name="cookbook-java.crud.multi-statement"></a>

```
// This code snippet is intentionally trivial. In reality you wouldn't do this because you'd
// set your UPDATE to filter on vin and insured, and check if you updated something or not.
public static boolean InsureCar(QldbDriver qldbDriver, final String vin) {
    final IonSystem ionSystem = IonSystemBuilder.standard().build();
    final IonString ionVin = ionSystem.newString(vin);

    return qldbDriver.execute(txn -> {
        Result result = txn.execute(
                "SELECT insured FROM Vehicles WHERE vin = ? AND insured = FALSE",
                ionVin);
        if (!result.isEmpty()) {
            txn.execute("UPDATE Vehicles SET insured = TRUE WHERE vin = ?", ionVin);
            return true;
        }
        return false;
    });
}
```

### 重試邏輯
<a name="cookbook-java.crud.retry-logic"></a>

驅動程式的 `execute`方法具有內建重試機制，可在發生可重試例外狀況 （例如逾時或 OCC 衝突） 時重試交易。

------
#### [ 2.x ]

重試嘗試次數上限和退避策略是可設定的。

預設重試限制為 `4`，預設退避策略為 [DefaultQldbTransactionBackoffStrategy](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/software/amazon/qldb/DefaultQldbTransactionBackoffStrategy.html)。您可以使用 [RetryPolicy](https://javadoc.io/doc/software.amazon.qldb/amazon-qldb-driver-java/latest/software/amazon/qldb/RetryPolicy.html) 的執行個體，設定每個驅動程式執行個體和每個交易的重試組態。

下列程式碼範例指定具有自訂重試限制的重試邏輯，以及驅動程式執行個體的自訂退避策略。

```
public void retry() {
    QldbDriver qldbDriver = QldbDriver.builder()
            .ledger("vehicle-registration")
            .transactionRetryPolicy(RetryPolicy.builder()
                    .maxRetries(2)
                    .backoffStrategy(new CustomBackOffStrategy()).build())
            .sessionClientBuilder(QldbSessionClient.builder())
            .build();
}

private class CustomBackOffStrategy implements BackoffStrategy {

    @Override
    public Duration calculateDelay(RetryPolicyContext retryPolicyContext) {
        return Duration.ofMillis(1000 * retryPolicyContext.retriesAttempted());
    }
}
```

下列程式碼範例指定具有自訂重試限制的重試邏輯，以及特定交易的自訂退避策略。此 組態會`execute`覆寫為驅動程式執行個體設定的重試邏輯。

```
public void retry() {
    Result result = qldbDriver.execute(txn -> { txn.execute("SELECT * FROM Person WHERE GovId = ?",
            SYSTEM.newString("TOYENC486FH")); },
            RetryPolicy.builder()
                    .maxRetries(2)
                    .backoffStrategy(new CustomBackOffStrategy())
                    .build());
}

private class CustomBackOffStrategy implements BackoffStrategy {

    // Configuring a custom backoff which increases delay by 1s for each attempt.
    @Override
    public Duration calculateDelay(RetryPolicyContext retryPolicyContext) {
        return Duration.ofMillis(1000 * retryPolicyContext.retriesAttempted());
    }
}
```

------
#### [ 1.x ]

重試嘗試次數上限是可設定的。您可以在初始化 時設定 `retryLimit` 屬性，以設定重試限制`PooledQldbDriver`。

預設重試限制為 `4`。

------

### 實作唯一性限制
<a name="cookbook-java.crud.uniqueness-constraints"></a>

QLDB 不支援唯一的索引，但您可以在應用程式中實作此行為。

假設您想要在`Person`資料表中的 `GovId` 欄位實作唯一性限制條件。若要執行此操作，您可以撰寫執行下列動作的交易：

1. 宣告資料表沒有具有指定 的現有文件`GovId`。

1. 如果聲明通過，請插入文件。

如果競爭交易同時通過聲明，則只有一個交易會成功遞交。另一個交易將失敗，但 OCC 衝突例外狀況。

下列程式碼範例示範如何實作此唯一性限制邏輯。

```
qldbDriver.execute(txn -> {
    Result result = txn.execute("SELECT * FROM Person WHERE GovId = ?",
            SYSTEM.newString("TOYENC486FH"));
    // Check if there is a result
    if (!result.iterator().hasNext()) {
        IonStruct person = SYSTEM.newEmptyStruct();
        person.put("GovId").newString("TOYENC486FH");
        person.put("FirstName").newString("Brent");
        // Insert the document
        txn.execute("INSERT INTO Person ?", person);
    }
});
```

**注意**  
在此範例中，我們建議在 `GovId` 欄位中具有索引，以最佳化效能。如果沒有 上的索引`GovId`，陳述式可能會有更多延遲，也可能導致 OCC 衝突例外狀況或交易逾時。

## 使用 Amazon Ion
<a name="cookbook-java.ion"></a>

有數種方式可以處理 QLDB 中的 Amazon Ion 資料。您可以從 [Ion 程式庫](https://github.com/amzn/ion-java)使用內建方法，視需要彈性地建立和修改文件。或者，您可以使用 FasterXML 的 [Jackson 資料格式模組，讓 Ion](https://github.com/FasterXML/jackson-dataformats-binary/tree/master/ion) 將 Ion 文件映射至*舊的 Java 物件* (POJO) 模型。

以下各節提供使用兩種技術處理 Ion 資料的程式碼範例。

**Contents**
+ [

### 匯入 Ion 套件
](#cookbook-java.ion.importing)
+ [

### 初始化 Ion
](#cookbook-java.ion.initializing)
+ [

### 建立 Ion 物件
](#cookbook-java.ion.creating)
+ [

### 讀取 Ion 物件
](#cookbook-java.ion.reading)

### 匯入 Ion 套件
<a name="cookbook-java.ion.importing"></a>

在 Java 專案中新增成品 [ion-java](https://search.maven.org/artifact/com.amazon.ion/ion-java/1.6.1/bundle) 做為相依性。

------
#### [ Gradle ]

```
dependencies {
    compile group: 'com.amazon.ion', name: 'ion-java', version: '1.6.1'
}
```

------
#### [ Maven ]

```
<dependencies>
  <dependency>
    <groupId>com.amazon.ion</groupId>
    <artifactId>ion-java</artifactId>
    <version>1.6.1</version>
  </dependency>
</dependencies>
```

------

匯入下列 Ion 套件。

```
import com.amazon.ion.IonStruct;
import com.amazon.ion.IonSystem;
import com.amazon.ion.system.IonSystemBuilder;
```

#### 使用 Jackson 映射器
<a name="cookbook-java.ion.importing.jackson"></a>

在 Java 專案中新增成品 [jackson-dataformat-ion](https://search.maven.org/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-ion/2.10.0/bundle) 做為相依性。QLDB 需要 版本 `2.10.0` 或更新版本。

------
#### [ Gradle ]

```
dependencies {
    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-ion', version: '2.10.0'
}
```

------
#### [ Maven ]

```
<dependencies>
  <dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-ion</artifactId>
    <version>2.10.0</version>
  </dependency>
</dependencies>
```

------

匯入下列 Ion 套件。

```
import com.amazon.ion.IonReader;
import com.amazon.ion.IonStruct;
import com.amazon.ion.system.IonReaderBuilder;
import com.amazon.ion.system.IonSystemBuilder;

import com.fasterxml.jackson.dataformat.ion.IonObjectMapper;
import com.fasterxml.jackson.dataformat.ion.ionvalue.IonValueMapper;
```

### 初始化 Ion
<a name="cookbook-java.ion.initializing"></a>

```
IonSystem SYSTEM = IonSystemBuilder.standard().build();
```

#### 使用 Jackson 映射器
<a name="cookbook-java.ion.initializing.jackson"></a>

```
IonObjectMapper MAPPER = new IonValueMapper(IonSystemBuilder.standard().build());
```

### 建立 Ion 物件
<a name="cookbook-java.ion.creating"></a>

下列程式碼範例使用 `IonStruct` 界面及其內建方法建立 Ion 物件。

```
IonStruct ionStruct = SYSTEM.newEmptyStruct();

ionStruct.put("GovId").newString("TOYENC486FH");
ionStruct.put("FirstName").newString("Brent");

System.out.println(ionStruct.toPrettyString()); // prints a nicely formatted copy of ionStruct
```

#### 使用 Jackson 映射器
<a name="cookbook-java.ion.creating.jackson"></a>

假設您有名為 的 JSON 映射模型類別`Person`，如下所示。

```
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public static class Person {
    private final String firstName;
    private final String govId;

    @JsonCreator
    public Person(@JsonProperty("FirstName") final String firstName,
                  @JsonProperty("GovId") final String govId) {
        this.firstName = firstName;
        this.govId = govId;
    }

    @JsonProperty("FirstName")
    public String getFirstName() {
        return firstName;
    }

    @JsonProperty("GovId")
    public String getGovId() {
        return govId;
    }
}
```

下列程式碼範例會從 執行個體建立`IonStruct`物件`Person`。

```
IonStruct ionStruct = (IonStruct) MAPPER.writeValueAsIonValue(new Person("Brent", "TOYENC486FH"));
```

### 讀取 Ion 物件
<a name="cookbook-java.ion.reading"></a>

下列程式碼範例會列印`ionStruct`執行個體的每個欄位。

```
// ionStruct is an instance of IonStruct
System.out.println(ionStruct.get("GovId")); // prints TOYENC486FH
System.out.println(ionStruct.get("FirstName")); // prints Brent
```

#### 使用 Jackson 映射器
<a name="cookbook-java.ion.reading.jackson"></a>

下列程式碼範例會讀取`IonStruct`物件，並將其對應至 的執行個體`Person`。

```
// ionStruct is an instance of IonStruct
IonReader reader = IonReaderBuilder.standard().build(ionStruct);
Person person = MAPPER.readValue(reader, Person.class);
System.out.println(person.getFirstName()); // prints Brent
System.out.println(person.getGovId()); // prints TOYENC486FH
```

如需使用 Ion 的詳細資訊，請參閱 GitHub 上的 [Amazon Ion 文件](http://amzn.github.io/ion-docs/)。如需在 QLDB 中使用 Ion 的更多程式碼範例，請參閱 [在 Amazon QLDB 中使用 Amazon Ion 資料類型](driver-working-with-ion.md)。