

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Pemrograman dengan DynamoDB dan AWS SDKs
<a name="Programming"></a>

Bagian ini mencakup topik terkait developer. Jika Anda ingin menjalankan contoh kode, lihat [Menjalankan contoh kode dalam Panduan Developer ini](CodeSamples.md). 

**catatan**  
Pada bulan Desember 2017, AWS memulai proses migrasi semua titik akhir Amazon DynamoDB untuk menggunakan sertifikat aman yang dikeluarkan oleh Amazon Trust Services (ATS). Untuk informasi selengkapnya, lihat [Memecahkan masalah pembuatan SSL/TLS koneksi dengan DynamoDB](ats-certs.md). 

**Topics**
+ [Ikhtisar dukungan AWS SDK untuk DynamoDB](Programming.SDKOverview.md)
+ [Pemrograman Amazon DynamoDB dengan Python dan Boto3](programming-with-python.md)
+ [Pemrograman Amazon DynamoDB dengan JavaScript](programming-with-javascript.md)
+ [Pemrograman DynamoDB dengan AWS SDK for Java 2.x](ProgrammingWithJava.md)
+ [Penanganan kesalahan dengan DynamoDB](Programming.Errors.md)
+ [Menggunakan DynamoDB dengan SDK AWS](sdk-general-information-section.md)

# Ikhtisar dukungan AWS SDK untuk DynamoDB
<a name="Programming.SDKOverview"></a>

Diagram berikut memberikan gambaran tingkat tinggi pemrograman aplikasi Amazon DynamoDB menggunakan file. AWS SDKs

![\[Model pemrograman untuk menggunakan DynamoDB dengan. AWS SDKs\]](http://docs.aws.amazon.com/id_id/amazondynamodb/latest/developerguide/images/SDKSupport.png)


1. Anda menulis aplikasi menggunakan AWS SDK untuk bahasa pemrograman Anda.

1. Setiap AWS SDK menyediakan satu atau lebih antarmuka terprogram untuk bekerja dengan DynamoDB. Antarmuka spesifik yang tersedia bergantung pada bahasa pemrograman dan AWS SDK yang Anda gunakan. Opsinya meliputi:
   + [Antarmuka tingkat rendah yang bekerja dengan DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.LowLevel)
   + [Antarmuka dokumen yang bekerja dengan DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Document)
   + [Antarmuka persistensi objek yang bekerja dengan DynamoDB](Programming.SDKs.Interfaces.md#Programming.SDKs.Interfaces.Mapper)
   + [Antarmuka Tingkat Tinggi](HigherLevelInterfaces.md)

1.  AWS SDK membuat permintaan HTTP (S) untuk digunakan dengan API DynamoDB tingkat rendah.

1.  AWS SDK mengirimkan permintaan ke titik akhir DynamoDB.

1. DynamoDB menjalankan permintaan. Jika permintaan berhasil, DynamoDB mengembalikan kode respons HTTP 200 (OK). Jika permintaan tidak berhasil, DynamoDB mengembalikan kode galat dan pesan kesalahan HTTP.

1.  AWS SDK memproses respons dan menyebarkannya kembali ke aplikasi Anda.

Masing-masing AWS SDKs menyediakan layanan penting untuk aplikasi Anda, termasuk yang berikut:
+ Memformat permintaan HTTP(S) dan menyerialisasi parameter permintaan.
+ Menghasilkan tanda tangan kriptografi untuk setiap permintaan.
+ Meneruskan permintaan ke titik akhir DynamoDB dan menerima respons dari DynamoDB.
+ Mengekstraksi hasil dari respons tersebut.
+ Menerapkan logika coba lagi dasar dalam kasus kesalahan.

Anda tidak perlu menulis kode untuk semua tugas ini.

**catatan**  
Untuk informasi selengkapnya AWS SDKs, termasuk petunjuk penginstalan dan dokumentasi, lihat [Alat untuk Amazon Web Services](https://aws.amazon.com/tools).

## Dukungan SDK dari endpoint berbasis AWS akun
<a name="Programming.SDKs.endpoints"></a>

AWS meluncurkan dukungan SDK untuk AWS titik akhir berbasis akun untuk DynamoDB, dimulai dengan SDK for AWS Java V1 pada 4 September 2024. Titik akhir baru ini membantu AWS memastikan kinerja dan skalabilitas yang tinggi. Yang diperbarui SDKs akan secara otomatis menggunakan titik akhir baru, yang memiliki format`https://(account-id).ddb.(region).amazonaws.com`.

Jika Anda menggunakan satu instance klien SDK untuk membuat permintaan ke beberapa akun, aplikasi Anda akan memiliki lebih sedikit kesempatan untuk menggunakan kembali koneksi. AWS merekomendasikan untuk memodifikasi aplikasi Anda untuk terhubung ke lebih sedikit akun per instans klien SDK. Alternatifnya adalah menyetel klien SDK Anda untuk terus menggunakan titik akhir Regional menggunakan `ACCOUNT_ID_ENDPOINT_MODE` pengaturan, seperti yang didokumentasikan dalam Panduan [https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html).

# Antarmuka terprogram yang bekerja dengan DynamoDB
<a name="Programming.SDKs.Interfaces"></a>

Setiap [AWS SDK](https://aws.amazon.com/tools) menyediakan satu atau lebih antarmuka program untuk bekerja dengan Amazon DynamoDB. Antarmuka ini memiliki rentang dari pembungkus DynamoDB level rendah sederhana hingga lapisan persistensi berorientasi objek. Antarmuka yang tersedia bervariasi tergantung pada AWS SDK dan bahasa pemrograman yang Anda gunakan.

![\[Antarmuka terprogram tersedia dalam berbagai cara AWS SDKs untuk bekerja dengan DynamoDB.\]](http://docs.aws.amazon.com/id_id/amazondynamodb/latest/developerguide/images/SDKSupport.SDKInterfaces.png)


Bagian berikut menyoroti beberapa antarmuka yang tersedia, menggunakan AWS SDK untuk Java sebagai contoh. (Tidak semua antarmuka tersedia di semua AWS SDKs.)

**Topics**
+ [Antarmuka tingkat rendah yang bekerja dengan DynamoDB](#Programming.SDKs.Interfaces.LowLevel)
+ [Antarmuka dokumen yang bekerja dengan DynamoDB](#Programming.SDKs.Interfaces.Document)
+ [Antarmuka persistensi objek yang bekerja dengan DynamoDB](#Programming.SDKs.Interfaces.Mapper)

## Antarmuka tingkat rendah yang bekerja dengan DynamoDB
<a name="Programming.SDKs.Interfaces.LowLevel"></a>

Setiap AWS SDK khusus bahasa menyediakan antarmuka tingkat rendah untuk Amazon DynamoDB, dengan metode yang sangat mirip dengan permintaan API DynamoDB tingkat rendah.

Dalam beberapa kasus, Anda akan perlu untuk mengidentifikasi jenis data dari atribut-atribut tersebut menggunakan [Deskriptor jenis data](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors), seperti `S` untuk string, atau `N` untuk angka.

**catatan**  
Antarmuka tingkat rendah tersedia dalam setiap AWS SDK khusus bahasa.

Program Java berikut menggunakan antarmuka AWS SDK untuk Java tingkat rendah. 

### Contoh antarmuka tingkat rendah
<a name="low-level-example"></a>

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal>

                Where:
                    tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3).\s
                    key - The key used in the Amazon DynamoDB table (for example, Artist).\s
                    keyval - The key value that represents the item to get (for example, Famous Band).
                """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName);
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        getDynamoDBItem(ddb, tableName, key, keyVal);
        ddb.close();
    }

    public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) {
        HashMap<String, AttributeValue> keyToGet = new HashMap<>();
        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal)
                .build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            // If there is no matching item, GetItem does not return any data.
            Map<String, AttributeValue> returnedItem = ddb.getItem(request).item();
            if (returnedItem.isEmpty())
                System.out.format("No item found with the key %s!\n", key);
            else {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");
                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

## Antarmuka dokumen yang bekerja dengan DynamoDB
<a name="Programming.SDKs.Interfaces.Document"></a>

Banyak yang AWS SDKs menyediakan antarmuka dokumen, memungkinkan Anda untuk melakukan operasi bidang data (membuat, membaca, memperbarui, menghapus) pada tabel dan indeks. Dengan antarmuka dokumen, Anda tidak perlu menentukan [Deskriptor jenis data](Programming.LowLevelAPI.md#Programming.LowLevelAPI.DataTypeDescriptors). Jenis data yang tersirat oleh semantik data itu sendiri. Ini AWS SDKs juga menyediakan metode untuk dengan mudah mengonversi dokumen JSON ke dan dari tipe data Amazon DynamoDB asli.

**catatan**  
Antarmuka dokumen tersedia di AWS SDKs untuk [Java](https://aws.amazon.com/sdk-for-java), [.NET](https://aws.amazon.com/sdk-for-net), [Node.js](https://aws.amazon.com/sdk-for-node-js), dan [JavaScriptSDK](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/).

Program Java berikut menggunakan antarmuka dokumen AWS SDK untuk Java. Program ini menciptakan objek `Table` yang merepresentasikan tabel `Music`, lalu meminta objek tersebut untuk menggunakan `GetItem` guna mengambil lagu. Program ini selanjutnya mencetak tahun lagu tersebut dirilis.

Kelas `software.amazon.dynamodb.document.DynamoDB` mengimplementasikan antarmuka dokumen DynamoDB. Perhatikan bagaimana `DynamoDB` berfungsi sebagai pembungkus di sekitar klien tingkat rendah (`AmazonDynamoDB`).

### Contoh antarmuka dokumen
<a name="document-level-example"></a>

```
package com.amazonaws.codesamples.gsg;

import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.document.DynamoDB;
import software.amazon.dynamodb.document.GetItemOutcome;
import software.amazon.dynamodb.document.Table;

public class MusicDocumentDemo {

    public static void main(String[] args) {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
        DynamoDB docClient = new DynamoDB(client);

        Table table = docClient.getTable("Music");
        GetItemOutcome outcome = table.getItemOutcome(
                "Artist", "No One You Know",
                "SongTitle", "Call Me Today");

        int year = outcome.getItem().getInt("Year");
        System.out.println("The song was released in " + year);

    }
}
```

## Antarmuka persistensi objek yang bekerja dengan DynamoDB
<a name="Programming.SDKs.Interfaces.Mapper"></a>

Beberapa AWS SDKs menyediakan antarmuka persistensi objek di mana Anda tidak secara langsung melakukan operasi bidang data. Sebagai gantinya, Anda akan membuat objek yang mewakili item dalam tabel dan indeks Amazon DynamoDB, dan hanya berinteraksi dengan objek tersebut. Ini memungkinkan Anda menulis kode yang berfokus pada objek, bukan kode yang berfokus pada basis data.

**catatan**  
Antarmuka persistensi objek tersedia di AWS SDKs untuk Java dan .NET. Untuk informasi selengkapnya, lihat [Antarmuka pemrograman tingkat tinggi untuk DynamoDB](HigherLevelInterfaces.md) DynamoDB.

### Contoh antarmuka ketekunan objek
<a name="mapper-level-example"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key. Be sure one of the id values is `id101`
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table. These values
 *                        need to be in the form of `YYYY-MM-DDTHH:mm:ssZ`, such as 2022-07-11T00:00:00Z
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedGetItem {
    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        getItem(enhancedClient);
        ddb.close();
    }

    public static String getItem(DynamoDbEnhancedClient enhancedClient) {
        Customer result = null;
        try {
            DynamoDbTable<Customer> table = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key = Key.builder()
                    .partitionValue("id101").sortValue("tred@noserver.com")
                    .build();

            // Get the item by using the key.
            result = table.getItem(
                    (GetItemEnhancedRequest.Builder requestBuilder) -> requestBuilder.key(key));
            System.out.println("******* The description value is " + result.getCustName());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return result.getCustName();
    }
}
```

# Antarmuka pemrograman tingkat tinggi untuk DynamoDB
<a name="HigherLevelInterfaces"></a>

 AWS SDKs Menyediakan aplikasi dengan antarmuka tingkat rendah untuk bekerja dengan Amazon DynamoDB. Metode dan kelas sisi klien ini berkaitan langsung dengan DynamoDB API tingkat rendah. Namun, banyak developer mengalami putusnya koneksi, atau *ketidakcocokan impedansi*, ketika mereka perlu memetakan jenis data yang kompleks untuk item dalam tabel basis data. Dengan antarmuka basis data tingkat rendah, developer harus menulis metode untuk membaca atau menulis data objek ke tabel basis data, dan sebaliknya. Jumlah kode tambahan yang diperlukan untuk setiap kombinasi jenis objek dan tabel basis data dapat terlihat sangat banyak.

Untuk menyederhanakan pengembangan, AWS SDKs untuk Java dan .NET menyediakan antarmuka tambahan dengan tingkat abstraksi yang lebih tinggi. Antarmuka tingkat yang lebih tinggi untuk DynamoDB memungkinkan Anda menentukan hubungan di antara objek dalam program Anda dan tabel basis data yang menyimpan data objek tersebut. Setelah menentukan pemetaan ini, Anda memanggil metode objek sederhana seperti `save`, `load`, atau `delete`, dan operasi DynamoDB tingkat rendah yang mendasarinya akan dipanggil secara otomatis atas nama Anda. Ini memungkinkan Anda menulis kode yang berfokus pada objek, bukan kode yang berfokus pada basis data.

Antarmuka pemrograman tingkat tinggi untuk DynamoDB tersedia di untuk Java dan .NET. AWS SDKs 

**Java**
+ [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md)
+ [Java 2.x: DynamoDB Enhanced Client](DynamoDBEnhanced.md)

**.NET**
+ [Bekerja dengan model dokumen.NET di DynamoDB](DotNetSDKMidLevel.md)
+ [Bekerja dengan model persistensi objek.NET dan DynamoDB](DotNetSDKHighLevel.md)

# Java 1.x: Dinamo DBMapper
<a name="DynamoDBMapper"></a>

**catatan**  
SDK for Java memiliki dua versi: 1.x dan 2.x. end-of-supportUntuk 1.x [diumumkan](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) pada 12 Januari 2024. Itu akan dan akan jatuh tempo pada 31 Desember 2025. end-of-support Untuk pengembangan baru, kami sangat menyarankan Anda menggunakan 2.x.

 AWS SDK untuk Java Ini menyediakan `DynamoDBMapper` kelas, memungkinkan Anda untuk memetakan kelas sisi klien Anda ke tabel Amazon DynamoDB. Untuk menggunakan `DynamoDBMapper`, tentukan hubungan antara item dalam tabel DynamoDB dan instans objek yang sesuai dalam kode Anda. Kelas `DynamoDBMapper` memungkinkan Anda melakukan berbagai operasi buat, baca, perbarui, dan hapus (CRUD) pada item, dan menjalankan kueri serta memindai tabel.

**Topics**
+ [Kelas Dynamo DBMapper](DynamoDBMapper.Methods.md)
+ [Tipe data yang didukung untuk Dynamo DBMapper untuk Java](DynamoDBMapper.DataTypes.md)
+ [Anotasi Java untuk DynamoDB](DynamoDBMapper.Annotations.md)
+ [Pengaturan konfigurasi opsional untuk Dynamo DBMapper](DynamoDBMapper.OptionalConfig.md)
+ [DynamoDB dan penguncian optimis dengan nomor versi](DynamoDBMapper.OptimisticLocking.md)
+ [Memetakan data arbitrer di DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md)
+ [Contoh Dynamo DBMapper](DynamoDBMapper.Examples.md)

**catatan**  
Kelas `DynamoDBMapper` tidak memungkinkan Anda membuat, memperbarui, atau menghapus tabel. Untuk melakukan tugas tersebut, gunakan antarmuka SDK untuk Java tingkat rendah.

SDK untuk Java menyediakan serangkaian jenis anotasi agar Anda dapat memetakan kelas ke tabel. Misalnya, pertimbangkan tabel `ProductCatalog` yang memiliki `Id` sebagai kunci partisi. 

```
ProductCatalog(Id, ...)
```

Anda dapat memetakan kelas di aplikasi klien ke tabel `ProductCatalog` seperti yang ditunjukkan dalam kode Java berikut. Kode ini menentukan plain old Java object (POJO) bernama `CatalogItem`, yang menggunakan anotasi untuk memetakan bidang objek ke nama atribut DynamoDB.

**Example**  

```
package com.amazonaws.codesamples;

import java.util.Set;

import software.amazon.dynamodb.datamodeling.DynamoDBAttribute;
import software.amazon.dynamodb.datamodeling.DynamoDBHashKey;
import software.amazon.dynamodb.datamodeling.DynamoDBIgnore;
import software.amazon.dynamodb.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) {this.id = id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN; }

    @DynamoDBAttribute(attributeName="Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp; }
    public void setSomeProp(String someProp) { this.someProp = someProp; }
}
```

Dalam kode sebelumnya, anotasi `@DynamoDBTable` memetakan kelas `CatalogItem` ke tabel `ProductCatalog`. Anda dapat menyimpan masing-masing instans kelas sebagai item dalam tabel. Dalam definisi kelas, anotasi `@DynamoDBHashKey` memetakan properti `Id` ke kunci primer. 

Secara default, properti kelas memetakan atribut nama yang sama dalam tabel. Properti `Title` dan `ISBN` memetakan atribut nama yang sama di tabel. 

Anotasi `@DynamoDBAttribute` bersifat opsional saat nama atribut DynamoDB cocok dengan nama properti yang dinyatakan di kelas. Jika namanya berbeda, gunakan anotasi ini dengan parameter `attributeName` untuk menentukan atribut DynamoDB yang sesuai dengan properti ini. 

Dalam contoh sebelumnya, `@DynamoDBAttribute` anotasi ditambahkan ke setiap properti untuk memastikan bahwa nama properti cocok persis dengan tabel yang dibuat pada langkah sebelumnya, dan agar konsisten dengan nama atribut yang digunakan dalam contoh kode lain dalam panduan ini. 

Definisi kelas Anda dapat memiliki properti yang tidak dipetakan ke setiap atribut dalam tabel. Anda mengidentifikasi properti ini dengan menambahkan anotasi `@DynamoDBIgnore`. Dalam contoh sebelumnya, properti `SomeProp` ditandai dengan anotasi `@DynamoDBIgnore`. Saat Anda mengunggah instans `CatalogItem` ke tabel, instans `DynamoDBMapper` tidak menyertakan properti `SomeProp`. Selain itu, pemeta tidak mengembalikan atribut ini ketika Anda mengambil item dari tabel. 

Setelah menentukan kelas pemetaan, Anda dapat menggunakan metode `DynamoDBMapper` untuk menulis instans kelas tersebut untuk item yang sesuai dalam tabel `Catalog`. Contoh kode berikut mendemonstrasikan teknik ini.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapper mapper = new DynamoDBMapper(client);

CatalogItem item = new CatalogItem();
item.setId(102);
item.setTitle("Book 102 Title");
item.setISBN("222-2222222222");
item.setBookAuthors(new HashSet<String>(Arrays.asList("Author 1", "Author 2")));
item.setSomeProp("Test");

mapper.save(item);
```

Contoh kode berikut menunjukkan cara mengambil item dan mengakses beberapa atributnya.

```
CatalogItem partitionKey = new CatalogItem();

partitionKey.setId(102);
DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
    .withHashKeyValues(partitionKey);

List<CatalogItem> itemList = mapper.query(CatalogItem.class, queryExpression);

for (int i = 0; i < itemList.size(); i++) {
    System.out.println(itemList.get(i).getTitle());
    System.out.println(itemList.get(i).getBookAuthors());
}
```

`DynamoDBMapper` menawarkan cara natural yang intuitif untuk menggunakan data DynamoDB dalam Java. Ini juga menyediakan beberapa fitur bawaan, seperti penguncian optimis, transaksi ACID, nilai kunci urutan dan kunci partisi yang dibuat secara otomatis, serta objek penentuan versi.

# Kelas Dynamo DBMapper
<a name="DynamoDBMapper.Methods"></a>



Kelas `DynamoDBMapper` adalah titik masuk ke Amazon DynamoDB. Kelas ini menyediakan akses ke titik akhir DynamoDB dan memungkinkan Anda mengakses data Anda dalam berbagai tabel. Kelas ini juga memungkinkan Anda melakukan berbagai operasi buat, baca, perbarui, dan hapus (CRUD) pada item, dan menjalankan kueri serta memindai tabel. Kelas ini menyediakan metode berikut agar berfungsi dengan DynamoDB.

*Untuk dokumentasi Javadoc yang sesuai, lihat [Dynamo DBMapper](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) di Referensi API.AWS SDK untuk Java *

**Topics**
+ [save](#DynamoDBMapper.Methods.save)
+ [muat](#DynamoDBMapper.Methods.load)
+ [hapus](#DynamoDBMapper.Methods.delete)
+ [kueri](#DynamoDBMapper.Methods.query)
+ [queryPage](#DynamoDBMapper.Methods.queryPage)
+ [scan](#DynamoDBMapper.Methods.scan)
+ [scanPage](#DynamoDBMapper.Methods.scanPage)
+ [parallelScan](#DynamoDBMapper.Methods.parallelScan)
+ [batchSave](#DynamoDBMapper.Methods.batchSave)
+ [batchLoad](#DynamoDBMapper.Methods.batchLoad)
+ [batchDelete](#DynamoDBMapper.Methods.batchDelete)
+ [batchWrite](#DynamoDBMapper.Methods.batchWrite)
+ [transactionWrite](#DynamoDBMapper.Methods.transactionWrite)
+ [transactionLoad](#DynamoDBMapper.Methods.transactionLoad)
+ [count](#DynamoDBMapper.Methods.count)
+ [generateCreateTablePermintaan](#DynamoDBMapper.Methods.generateCreateTableRequest)
+ [createS3Link](#DynamoDBMapper.Methods.createS3Link)
+ [GetS3 ClientCache](#DynamoDBMapper.Methods.getS3ClientCache)

## save
<a name="DynamoDBMapper.Methods.save"></a>

Menyimpan objek tertentu ke tabel. Objek yang ingin Anda simpan adalah satu-satunya parameter yang diperlukan untuk metode ini. Anda dapat memberikan parameter konfigurasi opsional menggunakan objek `DynamoDBMapperConfig`. 

Jika item yang memiliki kunci primer yang sama tidak ada, metode ini akan membuat item baru dalam tabel. Jika item yang memiliki kunci primer yang sama ada, item yang ada akan diperbarui. Jika kunci partisi dan kunci urutan berupa String jenis dan dianotasikan dengan `@DynamoDBAutoGeneratedKey`, kunci tersebut diberi pengidentifikasi unik universal acak (UUID) jika tidak diinisialisasi. Bidang versi yang diberi anotasi dengan `@DynamoDBVersionAttribute` bertambah satu. Selain itu, jika bidang versi diperbarui atau kunci dibuat, objek yang diteruskan akan diperbarui sebagai hasil operasi. 

Secara default, hanya atribut yang sesuai dengan properti kelas yang dipetakan yang akan diperbarui. Atribut tambahan yang ada pada item tidak akan terpengaruh. Namun, jika menentukan `SaveBehavior.CLOBBER`, Anda dapat memaksa item untuk ditimpa sepenuhnya.

```
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
    .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER).build();
        
mapper.save(item, config);
```

Jika penentuan versi diaktifkan, versi item sisi klien dan sisi server harus cocok. Namun, versi tidak harus cocok jika opsi `SaveBehavior.CLOBBER` digunakan. Untuk informasi selengkapnya tentang penentuan versi, lihat [DynamoDB dan penguncian optimis dengan nomor versi](DynamoDBMapper.OptimisticLocking.md).

## muat
<a name="DynamoDBMapper.Methods.load"></a>

Mengambil item dari tabel. Anda harus menyediakan kunci primer item yang ingin Anda ambil. Anda dapat memberikan parameter konfigurasi opsional menggunakan objek `DynamoDBMapperConfig`. Misalnya, Anda secara opsional dapat meminta bacaan sangat konsisten untuk memastikan bahwa metode ini hanya mengambil nilai item terbaru seperti yang ditunjukkan dalam pernyataan Java berikut. 

```
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
    .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT).build();

CatalogItem item = mapper.load(CatalogItem.class, item.getId(), config);
```

Secara default, DynamoDB akan mengembalikan item yang memiliki nilai yang akhirnya konsisten. Untuk informasi tentang model konsistensi akhir DynamoDB, lihat [DynamoDB membaca konsistensi](HowItWorks.ReadConsistency.md).

## hapus
<a name="DynamoDBMapper.Methods.delete"></a>

Menghapus item dari tabel. Anda harus meneruskan instans objek dari kelas yang dipetakan. 

Jika penentuan versi diaktifkan, versi item sisi klien dan sisi server harus cocok. Namun, versi tidak harus cocok jika opsi `SaveBehavior.CLOBBER` digunakan. Untuk informasi selengkapnya tentang penentuan versi, lihat [DynamoDB dan penguncian optimis dengan nomor versi](DynamoDBMapper.OptimisticLocking.md). 

## kueri
<a name="DynamoDBMapper.Methods.query"></a>

Mengkueri tabel atau indeks sekunder.

Misalnya, Anda memiliki tabel, `Reply`, yang menyimpan balasan utas forum. Setiap subjek utas dapat berisi nol atau beberapa balasan. Kunci primer tabel `Reply` terdiri dari bidang `Id` dan `ReplyDateTime`, dengan `Id` sebagai kunci partisi dan `ReplyDateTime` sebagai kunci urutan kunci primer.

```
Reply ( Id, ReplyDateTime, ... )
```

Misalnya, Anda membuat pemetaan antara kelas `Reply` dan tabel `Reply` yang sesuai di DynamoDB. Kode Java berikut menggunakan `DynamoDBMapper` untuk menemukan semua balasan dalam dua minggu terakhir untuk subjek utas tertentu.

**Example**  

```
String forumName = "&DDB;";
String forumSubject = "&DDB; Thread 1";
String partitionKey = forumName + "#" + forumSubject;

long twoWeeksAgoMilli = (new Date()).getTime() - (14L*24L*60L*60L*1000L);
Date twoWeeksAgo = new Date();
twoWeeksAgo.setTime(twoWeeksAgoMilli);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String twoWeeksAgoStr = df.format(twoWeeksAgo);

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS(partitionKey));
eav.put(":v2",new AttributeValue().withS(twoWeeksAgoStr.toString()));

DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>()
    .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2")
    .withExpressionAttributeValues(eav);

List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);
```

Kueri ini mengembalikan koleksi objek `Reply`. 

Secara default, metode `query` mengembalikan koleksi "lazy-loaded". Metode ini awalnya hanya mengembalikan satu halaman hasil, lalu membuat panggilan layanan untuk halaman berikutnya jika diperlukan. Untuk mendapatkan semua item yang cocok, iterasikan ke koleksi `latestReplies`. 

Perhatikan bahwa memanggil metode `size()` pada koleksi akan memuat setiap hasil untuk memberikan jumlah yang akurat. Hal ini dapat mengakibatkan penggunaan banyak throughput yang disediakan, dan bahkan bisa menghabiskan semua memori di JVM Anda pada tabel yang sangat besar.

Untuk mencari indeks, Anda harus membuat model indeks sebagai kelas pemeta terlebih dahulu. Misalkan `Reply` tabel memiliki indeks sekunder global bernama *PostedBy-Message-Index*. Kunci partisi untuk indeks ini adalah `PostedBy`, dan kunci urutannya adalah `Message`. Definisi kelas untuk item dalam indeks akan tampak seperti berikut ini.

```
@DynamoDBTable(tableName="Reply")
public class PostedByMessage {
    private String postedBy;
    private String message;

    @DynamoDBIndexHashKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "PostedBy")
    public String getPostedBy() { return postedBy; }
    public void setPostedBy(String postedBy) { this.postedBy = postedBy; }

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "Message")
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }

   // Additional properties go here.
}
```

Anotasi `@DynamoDBTable` menunjukkan bahwa indeks ini terkait dengan tabel `Reply`. `@DynamoDBIndexHashKey`Anotasi menunjukkan kunci partisi (*PostedBy*) dari indeks, dan `@DynamoDBIndexRangeKey` menunjukkan kunci sortir (*Pesan*) indeks.

Sekarang, Anda dapat menggunakan `DynamoDBMapper` untuk mengkueri indeks, mengambil subset pesan yang diposting oleh pengguna tertentu. Anda tidak perlu menentukan nama indeks jika Anda tidak memiliki pemetaan yang bertentangan di seluruh tabel dan indeks serta pemetaan sudah dibuat di mapper. Pemeta akan menyimpulkan berdasarkan kunci primer dan kunci urutan. Kode berikut mengkueri indeks sekunder global. Karena indeks sekunder global mendukung bacaan akhir konsisten tetapi bukan bacaan sangat konsisten, Anda harus menentukan `withConsistentRead(false)`.

```
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1",  new AttributeValue().withS("User A"));
eav.put(":v2",  new AttributeValue().withS("DynamoDB"));

DynamoDBQueryExpression<PostedByMessage> queryExpression = new DynamoDBQueryExpression<PostedByMessage>()
    .withIndexName("PostedBy-Message-Index")
    .withConsistentRead(false)
    .withKeyConditionExpression("PostedBy = :v1 and begins_with(Message, :v2)")
    .withExpressionAttributeValues(eav);

List<PostedByMessage> iList =  mapper.query(PostedByMessage.class, queryExpression);
```

Kueri ini mengembalikan koleksi objek `PostedByMessage`.

## queryPage
<a name="DynamoDBMapper.Methods.queryPage"></a>

Mengkueri tabel atau indeks sekunder dan mengembalikan satu halaman hasil yang cocok. Seperti metode `query`, Anda harus menentukan nilai kunci partisi dan filter kueri yang diterapkan pada atribut kunci urutan. Namun, `queryPage` hanya mengembalikan “halaman” pertama data, yaitu jumlah data yang sesuai dalam ukuran 1 MB 

## scan
<a name="DynamoDBMapper.Methods.scan"></a>

Memindai seluruh tabel atau indeks sekunder. Anda dapat menentukan `FilterExpression` untuk memfilter kumpulan hasil secara opsional.

Misalnya, Anda memiliki tabel, `Reply`, yang menyimpan balasan utas forum. Setiap subjek utas dapat berisi nol atau beberapa balasan. Kunci primer tabel `Reply` terdiri dari bidang `Id` dan `ReplyDateTime`, dengan `Id` sebagai kunci partisi dan `ReplyDateTime` sebagai kunci urutan kunci primer.

```
Reply ( Id, ReplyDateTime, ... )
```

Jika memetakan kelas Java ke tabel `Reply`, Anda dapat menggunakan `DynamoDBMapper` untuk memindai tabel. Misalnya, kode Java berikut memindai seluruh tabel `Reply`, sehingga hanya mengembalikan balasan untuk tahun tertentu.

**Example**  

```
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS("2015"));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withFilterExpression("begins_with(ReplyDateTime,:v1)")
    .withExpressionAttributeValues(eav);

List<Reply> replies =  mapper.scan(Reply.class, scanExpression);
```

Secara default, metode `scan` mengembalikan koleksi "lazy-loaded". Metode ini awalnya hanya mengembalikan satu halaman hasil, lalu membuat panggilan layanan untuk halaman berikutnya jika diperlukan. Untuk mendapatkan semua item yang cocok, iterasikan ke koleksi `replies`.

Perhatikan bahwa memanggil metode `size()` pada koleksi akan memuat setiap hasil untuk memberikan jumlah yang akurat. Hal ini dapat mengakibatkan penggunaan banyak throughput yang disediakan, dan bahkan bisa menghabiskan semua memori di JVM Anda pada tabel yang sangat besar.

Untuk memindai indeks, Anda harus membuat model indeks sebagai kelas pemeta terlebih dahulu. Misalkan tabel `Reply` memiliki indeks sekunder global bernama `PostedBy-Message-Index`. Kunci partisi untuk indeks ini adalah `PostedBy`, dan kunci urutannya adalah `Message`. Kelas pemeta untuk indeks ini ditampilkan di bagian [kueri](#DynamoDBMapper.Methods.query). Kelas ini menggunakan anotasi `@DynamoDBIndexHashKey` dan `@DynamoDBIndexRangeKey` untuk menentukan kunci partisi indeks dan kunci urutan.

Contoh kode berikut memindai `PostedBy-Message-Index`. Contoh kode ini tidak menggunakan filter pemindaian, sehingga semua item dalam indeks dikembalikan kepada Anda.

```
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withIndexName("PostedBy-Message-Index")
    .withConsistentRead(false);

    List<PostedByMessage> iList =  mapper.scan(PostedByMessage.class, scanExpression);
    Iterator<PostedByMessage> indexItems = iList.iterator();
```

## scanPage
<a name="DynamoDBMapper.Methods.scanPage"></a>

Memindai tabel atau indeks sekunder dan mengembalikan satu halaman hasil yang cocok. Seperti halnya metode `scan`, Anda dapat menentukan `FilterExpression` untuk memfilter kumpulan hasil secara opsional. Namun, `scanPage` hanya mengembalikan “halaman” pertama data, yaitu jumlah data yang sesuai dalam ukuran 1 MB.

## parallelScan
<a name="DynamoDBMapper.Methods.parallelScan"></a>

Melakukan pemindaian paralel dari seluruh tabel atau indeks sekunder. Anda menentukan sejumlah segmen logis untuk tabel, beserta ekspresi pemindaian untuk memfilter hasil. `parallelScan` membagi tugas pemindaian antara beberapa pekerja, satu tugas untuk setiap segmen logis; pekerja akan memproses data secara paralel dan mengembalikan hasilnya.

Contoh kode Java berikut melakukan pemindaian paralel pada tabel `Product`.

```
int numberOfThreads = 4;

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":n", new AttributeValue().withN("100"));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withFilterExpression("Price <= :n")
    .withExpressionAttributeValues(eav);

List<Product> scanResult = mapper.parallelScan(Product.class, scanExpression, numberOfThreads);
```

## batchSave
<a name="DynamoDBMapper.Methods.batchSave"></a>

Menyimpan objek ke satu atau beberapa tabel menggunakan satu atau beberapa panggilan ke metode `AmazonDynamoDB.batchWriteItem`. Metode ini tidak memberikan jaminan transaksi.

Kode Java berikut menyimpan dua item (buku) ke tabel `ProductCatalog`.

```
Book book1 = new Book();
book1.setId(901);
book1.setProductCategory("Book");
book1.setTitle("Book 901 Title");

Book book2 = new Book();
book2.setId(902);
book2.setProductCategory("Book");
book2.setTitle("Book 902 Title");

mapper.batchSave(Arrays.asList(book1, book2));
```

## batchLoad
<a name="DynamoDBMapper.Methods.batchLoad"></a>

Mengambil beberapa item dari satu atau beberapa tabel menggunakan kunci primernya.

Kode Java berikut akan mengambil dua item dari dua tabel yang berbeda.

```
ArrayList<Object> itemsToGet = new ArrayList<Object>();

ForumItem forumItem = new ForumItem();
forumItem.setForumName("Amazon DynamoDB");
itemsToGet.add(forumItem);

ThreadItem threadItem = new ThreadItem();
threadItem.setForumName("Amazon DynamoDB");
threadItem.setSubject("Amazon DynamoDB thread 1 message text");
itemsToGet.add(threadItem);

Map<String, List<Object>> items = mapper.batchLoad(itemsToGet);
```

## batchDelete
<a name="DynamoDBMapper.Methods.batchDelete"></a>

Menghapus objek dari satu atau beberapa tabel menggunakan satu atau beberapa panggilan ke metode `AmazonDynamoDB.batchWriteItem`. Metode ini tidak memberikan jaminan transaksi. 

Kode Java berikut akan menghapus dua item (buku) dari tabel `ProductCatalog`.

```
Book book1 = mapper.load(Book.class, 901);
Book book2 = mapper.load(Book.class, 902);
mapper.batchDelete(Arrays.asList(book1, book2));
```

## batchWrite
<a name="DynamoDBMapper.Methods.batchWrite"></a>

Menyimpan objek ke dan menghapus objek dari satu atau beberapa tabel menggunakan satu atau beberapa panggilan ke metode `AmazonDynamoDB.batchWriteItem`. Metode ini tidak memberikan jaminan transaksi atau penentuan versi dukungan (penempatan atau penghapusan bersyarat).

Kode Java berikut menulis item baru ke tabel `Forum`, menulis item baru ke tabel `Thread`, dan menghapus item dari tabel `ProductCatalog`.

```
// Create a Forum item to save
Forum forumItem = new Forum();
forumItem.setName("Test BatchWrite Forum");

// Create a Thread item to save
Thread threadItem = new Thread();
threadItem.setForumName("AmazonDynamoDB");
threadItem.setSubject("My sample question");

// Load a ProductCatalog item to delete
Book book3 = mapper.load(Book.class, 903);

List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem);
List<Book> objectsToDelete = Arrays.asList(book3);

mapper.batchWrite(objectsToWrite, objectsToDelete);
```

## transactionWrite
<a name="DynamoDBMapper.Methods.transactionWrite"></a>

Menyimpan objek ke dan menghapus objek dari satu atau beberapa tabel menggunakan satu panggilan ke metode `AmazonDynamoDB.transactWriteItems`. 

[Untuk daftar pengecualian khusus transaksi, lihat kesalahan. TransactWriteItems ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html#API_TransactWriteItems_Errors) 

Untuk informasi selengkapnya tentang transaksi DynamoDB dan jaminan atomisitas, konsistensi, isolasi, dan durabilitas atau atomicity, consistency, isolation, and durability (ACID), lihat [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

**catatan**  
 Metode ini tidak mendukung hal berikut:  
[Konfigurasi DynamoDBMapper. SaveBehavior](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptionalConfig.html).

Kode Java berikut menulis item baru ke setiap tabel `Forum` dan `Thread`, secara transaksional.

```
Thread s3ForumThread = new Thread();
s3ForumThread.setForumName("S3 Forum");
s3ForumThread.setSubject("Sample Subject 1");
s3ForumThread.setMessage("Sample Question 1");

Forum s3Forum = new Forum();
s3Forum.setName("S3 Forum");
s3Forum.setCategory("Amazon Web Services");
s3Forum.setThreads(1);

TransactionWriteRequest transactionWriteRequest = new TransactionWriteRequest();
transactionWriteRequest.addPut(s3Forum);
transactionWriteRequest.addPut(s3ForumThread);
mapper.transactionWrite(transactionWriteRequest);
```

## transactionLoad
<a name="DynamoDBMapper.Methods.transactionLoad"></a>

Memuat objek dari satu atau beberapa tabel menggunakan satu panggilan ke metode `AmazonDynamoDB.transactGetItems`. 

[Untuk daftar pengecualian khusus transaksi, lihat kesalahan. TransactGetItems ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html#API_TransactGetItems_Errors) 

Untuk informasi selengkapnya tentang transaksi DynamoDB dan jaminan atomisitas, konsistensi, isolasi, dan durabilitas atau atomicity, consistency, isolation, and durability (ACID), lihat [Amazon DynamoDB Transactions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html). 

Kode Java berikut akan memuat satu item dari setiap tabel `Forum` dan `Thread`, secara transaksional.

```
Forum dynamodbForum = new Forum();
dynamodbForum.setName("DynamoDB Forum");
Thread dynamodbForumThread = new Thread();
dynamodbForumThread.setForumName("DynamoDB Forum");

TransactionLoadRequest transactionLoadRequest = new TransactionLoadRequest();
transactionLoadRequest.addLoad(dynamodbForum);
transactionLoadRequest.addLoad(dynamodbForumThread);
mapper.transactionLoad(transactionLoadRequest);
```

## count
<a name="DynamoDBMapper.Methods.count"></a>

Mengevaluasi ekspresi pemindaian yang ditentukan dan mengembalikan jumlah item yang cocok. Tidak ada data item yang dikembalikan.

## generateCreateTablePermintaan
<a name="DynamoDBMapper.Methods.generateCreateTableRequest"></a>

Mengurai kelas POJO yang mewakili tabel DynamoDB, dan mengembalikan `CreateTableRequest` untuk tabel tersebut.

## createS3Link
<a name="DynamoDBMapper.Methods.createS3Link"></a>

Membuat tautan ke objek di Amazon S3. Anda harus menentukan nama bucket dan nama kunci, yang secara unik mengidentifikasi objek di bucket.

Untuk menggunakan `createS3Link`, kelas pemeta Anda harus menentukan metode getter dan setter. Contoh kode berikut menggambarkan hal ini dengan menambahkan atribut dan getter/setter metode baru ke `CatalogItem` kelas.

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    ...

    public S3Link productImage;

    ....

    @DynamoDBAttribute(attributeName = "ProductImage")
    public S3Link getProductImage() {
            return productImage;
    }

    public void setProductImage(S3Link productImage) {
        this.productImage = productImage;
    }

...
}
```

Kode Java berikut mendefinisikan item baru yang akan ditulis ke tabel `Product`. Item tersebut termasuk link ke gambar produk; data gambar diunggah ke Amazon S3.

```
CatalogItem item = new CatalogItem();

item.setId(150);
item.setTitle("Book 150 Title");

String amzn-s3-demo-bucket = "amzn-s3-demo-bucket";
String myS3Key = "productImages/book_150_cover.jpg";
item.setProductImage(mapper.createS3Link(amzn-s3-demo-bucket, myS3Key));

item.getProductImage().uploadFrom(new File("/file/path/book_150_cover.jpg"));

mapper.save(item);
```

Kelas `S3Link` menyediakan banyak metode lain untuk memanipulasi objek di Amazon S3. Untuk informasi selengkapnya, lihat [Javadocs untuk `S3Link`](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/S3Link.html).

## GetS3 ClientCache
<a name="DynamoDBMapper.Methods.getS3ClientCache"></a>

Mengembalikan `S3ClientCache` yang mendasarinya untuk mengakses Amazon S3. `S3ClientCache` adalah Peta cerdas untuk objek `AmazonS3Client`. Jika Anda memiliki banyak klien, an `S3ClientCache` dapat membantu Anda menjaga klien tetap terorganisir berdasarkan AWS Wilayah, dan dapat membuat klien Amazon S3 baru sesuai permintaan.

# Tipe data yang didukung untuk Dynamo DBMapper untuk Java
<a name="DynamoDBMapper.DataTypes"></a>

Bagian ini menjelaskan jenis data Java primitif, koleksi, dan jenis data arbitrer yang didukung di Amazon DynamoDB. 

Amazon DynamoDB mendukung jenis data Java primitif dan kelas pembungkus primitif berikut. 
+ `String`
+ `Boolean`, `boolean`
+ `Byte`, `byte`
+ `Date` (sebagai string [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) millisecond-precision, yang beralih ke UTC)
+ `Calendar` (sebagai string [ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601) millisecond-precision, yang beralih ke UTC)
+ `Long`, `long`
+ `Integer`, `int`
+ `Double`, `double`
+ `Float`, `float`
+ `BigDecimal`
+ `BigInteger`

**catatan**  
Untuk informasi selengkapnya tentang aturan penamaan DynamoDB dan berbagai jenis data yang didukung, lihat [Jenis data dan aturan penamaan yang didukung di Amazon DynamoDB](HowItWorks.NamingRulesDataTypes.md). 
Nilai biner kosong didukung oleh DynamoDBMapper.
Nilai String kosong didukung oleh AWS SDK for Java 2.x.  
Dalam AWS SDK for Java 1.x, DBMapper Dynamo mendukung pembacaan nilai atribut String kosong, namun, itu tidak akan menulis nilai atribut String kosong karena atribut ini dijatuhkan dari permintaan.

DynamoDB mendukung jenis koleksi [Kumpulan](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html), [Daftar](http://docs.oracle.com/javase/6/docs/api/java/util/List.html), dan [Peta](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html) Java. Tabel berikut merangkum bagaimana jenis Java ini dipetakan untuk jenis DynamoDB.


****  

| Jenis Java | Jenis DynamoDB | 
| --- | --- | 
|  Semua jenis angka  |  `N` (jenis angka)  | 
|  String  |  `S` (jenis string)   | 
|  Boolean  |  `BOOL` (jenis Boolean), 0 atau 1.  | 
|  ByteBuffer  |  `B` (jenis biner)  | 
|  Tanggal  |  `S` (jenis string). Nilai data disimpan sebagai string berformat ISO-8601.  | 
| Jenis koleksi [Kumpulan](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html) |  Jenis `SS` (kumpulan biner), jenis `NS` (kumpulan angka), atau jenis `BS` (kumpulan biner).  | 

 Antarmuka `DynamoDBTypeConverter` memungkinkan Anda memetakan jenis data arbitrer Anda sendiri ke jenis data yang secara asli didukung oleh DynamoDB. Untuk informasi selengkapnya, lihat [Memetakan data arbitrer di DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md). 

# Anotasi Java untuk DynamoDB
<a name="DynamoDBMapper.Annotations"></a>

Bagian ini menjelaskan anotasi yang tersedia untuk memetakan kelas dan properti ke tabel dan atribut di Amazon DynamoDB.

Untuk dokumentasi Javadoc yang sesuai, lihat [Ringkasan Jenis Anotasi](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/package-summary.html) di [Referensi API AWS SDK untuk Java](https://docs.aws.amazon.com/sdk-for-java/latest/reference/).

**catatan**  
Dalam anotasi berikut, hanya `DynamoDBTable` dan `DynamoDBHashKey` yang diperlukan. 

**Topics**
+ [Dinamo DBAttribute](#DynamoDBMapper.Annotations.DynamoDBAttribute)
+ [Dinamo DBAuto GeneratedKey](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey)
+ [Dinamo DBAuto GeneratedTimestamp](#DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp)
+ [Dinamo DBDocument](#DynamoDBMapper.Annotations.DynamoDBDocument)
+ [Kunci Dynamo DBHash](#DynamoDBMapper.Annotations.DynamoDBHashKey)
+ [Dinamo DBIgnore](#DynamoDBMapper.Annotations.DynamoDBIgnore)
+ [Dinamo DBIndex HashKey](#DynamoDBMapper.Annotations.DynamoDBIndexHashKey)
+ [Dinamo DBIndex RangeKey](#DynamoDBMapper.Annotations.DynamoDBIndexRangeKey)
+ [Kunci Dynamo DBRange](#DynamoDBMapper.Annotations.DynamoDBRangeKey)
+ [Dinamo DBTable](#DynamoDBMapper.Annotations.DynamoDBTable)
+ [Dynamo Dikonversi DBType](#DynamoDBMapper.Annotations.DynamoDBTypeConverted)
+ [Dinamo DBTyped](#DynamoDBMapper.Annotations.DynamoDBTyped)
+ [Atribut Dynamo DBVersion](#DynamoDBMapper.Annotations.DynamoDBVersionAttribute)

## Dinamo DBAttribute
<a name="DynamoDBMapper.Annotations.DynamoDBAttribute"></a>

Memetakan properti ke atribut tabel. Secara default, setiap properti kelas dipetakan ke atribut item dengan nama yang sama. Namun, jika nama tidak sama, Anda dapat menggunakan anotasi ini untuk memetakan properti ke atribut. Dalam cuplikan Java berikut, `DynamoDBAttribute` memetakan properti `BookAuthors` ke nama atribut `Authors` dalam tabel.

```
@DynamoDBAttribute(attributeName = "Authors")
public List<String> getBookAuthors() { return BookAuthors; }
public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; }
```

`DynamoDBMapper` menggunakan `Authors` sebagai nama atribut saat menyimpan objek ke tabel. 

## Dinamo DBAuto GeneratedKey
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedKey"></a>

Menandai kunci partisi atau properti kunci urutan sebagai dibuat otomatis. `DynamoDBMapper` membuat [UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html) acak saat menyimpan atribut ini. Hanya properti String yang dapat ditandai sebagai kunci yang dibuat otomatis. 

Contoh berikut mendemonstrasikan menggunakan kunci yang dibuat otomatis.

```
@DynamoDBTable(tableName="AutoGeneratedKeysExample")
public class AutoGeneratedKeys {
    private String id;
    private String payload;

    @DynamoDBHashKey(attributeName = "Id")
    @DynamoDBAutoGeneratedKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    @DynamoDBAttribute(attributeName="payload")
    public String getPayload() { return this.payload; }
    public void setPayload(String payload) { this.payload = payload; }

    public static void saveItem() {
        AutoGeneratedKeys obj = new AutoGeneratedKeys();
        obj.setPayload("abc123");

        // id field is null at this point
        DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
        mapper.save(obj);

        System.out.println("Object was saved with id " + obj.getId());
    }
}
```

## Dinamo DBAuto GeneratedTimestamp
<a name="DynamoDBMapper.Annotations.DynamoDBAutoGeneratedTimestamp"></a>

Membuat stempel waktu secara otomatis.

```
@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.ALWAYS)
public Date getLastUpdatedDate() { return lastUpdatedDate; }
public void setLastUpdatedDate(Date lastUpdatedDate) { this.lastUpdatedDate = lastUpdatedDate; }
```

Secara opsional, strategi pembuatan otomatis dapat didefinisikan dengan menyediakan atribut strategi. Nilai default-nya `ALWAYS`.

## Dinamo DBDocument
<a name="DynamoDBMapper.Annotations.DynamoDBDocument"></a>

Menunjukkan bahwa kelas dapat diserialisasi sebagai dokumen Amazon DynamoDB.

Misalnya, katakanlah Anda ingin memetakan dokumen JSON ke atribut DynamoDB untuk jenis Peta (`M`). Contoh kode berikut mendefinisikan item yang berisi atribut bersarang (Gambar) untuk jenis Peta.

```
public class ProductCatalogItem {

    private Integer id;  //partition key
    private Pictures pictures;
    /* ...other attributes omitted... */

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id;}
    public void setId(Integer id) {this.id = id;}

    @DynamoDBAttribute(attributeName="Pictures")
    public Pictures getPictures() { return pictures;}
    public void setPictures(Pictures pictures) {this.pictures = pictures;}

    // Additional properties go here.

    @DynamoDBDocument
    public static class Pictures {
        private String frontView;
        private String rearView;
        private String sideView;

        @DynamoDBAttribute(attributeName = "FrontView")
        public String getFrontView() { return frontView; }
        public void setFrontView(String frontView) { this.frontView = frontView; }

        @DynamoDBAttribute(attributeName = "RearView")
        public String getRearView() { return rearView; }
        public void setRearView(String rearView) { this.rearView = rearView; }

        @DynamoDBAttribute(attributeName = "SideView")
        public String getSideView() { return sideView; }
        public void setSideView(String sideView) { this.sideView = sideView; }

     }
}
```

Kemudian, Anda dapat menyimpan item `ProductCatalog`, dengan `Pictures`, seperti yang ditunjukkan dalam contoh berikut.

```
ProductCatalogItem item = new ProductCatalogItem();

Pictures pix = new Pictures();
pix.setFrontView("http://example.com/products/123_front.jpg");
pix.setRearView("http://example.com/products/123_rear.jpg");
pix.setSideView("http://example.com/products/123_left_side.jpg");
item.setPictures(pix);

item.setId(123);

mapper.save(item);
```

Item `ProductCatalog` yang dihasilkan akan tampak seperti berikut (dalam format JSON).

```
{
  "Id" : 123
  "Pictures" : {
    "SideView" : "http://example.com/products/123_left_side.jpg",
    "RearView" : "http://example.com/products/123_rear.jpg",
    "FrontView" : "http://example.com/products/123_front.jpg"
  }
}
```

## Kunci Dynamo DBHash
<a name="DynamoDBMapper.Annotations.DynamoDBHashKey"></a>

Memetakan properti kelas ke kunci partisi tabel. Properti harus berupa salah satu string skalar, angka, atau jenis biner. Properti tidak dapat berupa jenis koleksi. 

Asumsikan bahwa Anda memiliki tabel, `ProductCatalog`, yang memiliki `Id` sebagai kunci primer. Kode Java berikut mendefinisikan kelas `CatalogItem` dan memetakan properti `Id`-nya ke kunci primer dari tabel `ProductCatalog` menggunakan tanda `@DynamoDBHashKey`.

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
    private Integer Id;
   @DynamoDBHashKey(attributeName="Id")
   public Integer getId() {
        return Id;
   }
   public void setId(Integer Id) {
        this.Id = Id;
   }
   // Additional properties go here.
}
```

## Dinamo DBIgnore
<a name="DynamoDBMapper.Annotations.DynamoDBIgnore"></a>

Menunjukkan ke instans `DynamoDBMapper` bahwa properti terkait harus diabaikan. Saat menyimpan data ke tabel, `DynamoDBMapper` tidak menyimpan properti ini ke tabel.

 Diterapkan pada metode getter atau bidang kelas untuk properti yang tidak dimodelkan. Jika anotasi diterapkan langsung ke bidang kelas, getter dan setter yang sesuai harus dinyatakan di kelas yang sama. 

## Dinamo DBIndex HashKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexHashKey"></a>

Memetakan properti kelas ke kunci partisi untuk indeks sekunder global. Properti harus berupa salah satu string skalar, angka, atau jenis biner. Properti tidak dapat berupa jenis koleksi. 

Gunakan anotasi ini jika Anda perlu `Query` indeks sekunder global. Anda harus menentukan nama indeks (`globalSecondaryIndexName`). Jika nama properti kelas berbeda dari kunci partisi indeks, Anda juga harus menentukan nama atribut indeks (`attributeName`).

## Dinamo DBIndex RangeKey
<a name="DynamoDBMapper.Annotations.DynamoDBIndexRangeKey"></a>

Memetakan properti kelas untuk kunci urutan indeks sekunder global atau indeks sekunder lokal. Properti harus berupa salah satu string skalar, angka, atau jenis biner. Properti tidak dapat berupa jenis koleksi. 

Gunakan anotasi ini jika anda perlu `Query` indeks sekunder lokal atau indeks sekunder global dan ingin menyempurnakan hasil menggunakan kunci urutan indeks. Anda harus menentukan nama indeks (baik `globalSecondaryIndexName` maupun `localSecondaryIndexName`). Jika nama properti kelas berbeda dari kunci urutan indeks, Anda juga harus menentukan nama atribut indeks (`attributeName`).

## Kunci Dynamo DBRange
<a name="DynamoDBMapper.Annotations.DynamoDBRangeKey"></a>

Memetakan properti kelas untuk kunci urutan tabel. Properti harus berupa salah satu string skalar, angka, atau jenis biner. Properti ini tidak boleh berupa jenis koleksi. 

Jika kunci primer adalah komposit (kunci partisi dan kunci urutan), Anda dapat menggunakan tanda ini untuk memetakan bidang kelas Anda ke kunci urutan. Misalnya, Anda memiliki tabel `Reply` yang menyimpan balasan untuk utas forum. Setiap utas dapat berisi banyak balasan. Jadi, kunci primer tabel ini adalah `ThreadId` dan `ReplyDateTime`. `ThreadId` adalah kunci partisinya, dan `ReplyDateTime` adalah kunci urutannya. 

Kode Java berikut akan mendefinisikan `Reply` dan memetakannya ke tabel `Reply`. Kode tersebut menggunakan tanda `@DynamoDBHashKey` dan `@DynamoDBRangeKey` untuk mengidentifikasi properti kelas yang dipetakan ke kunci primer.

```
@DynamoDBTable(tableName="Reply")
public class Reply {
    private Integer id;
    private String replyDateTime;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }

    @DynamoDBRangeKey(attributeName="ReplyDateTime")
    public String getReplyDateTime() { return replyDateTime; }
    public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; }

   // Additional properties go here.
}
```

## Dinamo DBTable
<a name="DynamoDBMapper.Annotations.DynamoDBTable"></a>

Mengidentifikasi tabel target di DynamoDB. Misalnya, kode Java berikut menentukan kelas `Developer` dan memetakannya ke tabel `People` di DynamoDB. 

```
@DynamoDBTable(tableName="People")
public class Developer { ...}
```

Anotasi `@DynamoDBTable` dapat diwariskan. Setiap kelas baru yang diwariskan dari kelas `Developer` juga dipetakan ke tabel `People` yang sama. Misalnya, Anda membuat kelas `Lead` yang diwariskan dari kelas `Developer`. Karena Anda memetakan kelas `Developer` ke tabel `People`, objek kelas `Lead` juga disimpan dalam tabel yang sama.

`@DynamoDBTable` juga dapat diganti. Setiap kelas baru yang diwariskan dari kelas `Developer` secara default dipetakan ke tabel `People` yang sama. Namun, Anda dapat mengganti pemetaan default ini. Misalnya, jika Anda membuat kelas yang diwariskan dari kelas `Developer`, Anda dapat secara eksplisit memetakannya ke tabel lain dengan menambahkan anotasi `@DynamoDBTable` seperti yang ditunjukkan dalam contoh kode Java berikut.

```
@DynamoDBTable(tableName="Managers")
public class Manager extends Developer { ...}
```

## Dynamo Dikonversi DBType
<a name="DynamoDBMapper.Annotations.DynamoDBTypeConverted"></a>

Anotasi untuk menandai properti sebagai menggunakan konverter jenis khusus. Dapat dianotasikan pada anotasi yang ditetapkan pengguna untuk meneruskan properti tambahan ke `DynamoDBTypeConverter`. 

 Antarmuka `DynamoDBTypeConverter` memungkinkan Anda memetakan jenis data arbitrer Anda sendiri ke jenis data yang secara asli didukung oleh DynamoDB. Untuk informasi selengkapnya, lihat [Memetakan data arbitrer di DynamoDB](DynamoDBMapper.ArbitraryDataMapping.md).

## Dinamo DBTyped
<a name="DynamoDBMapper.Annotations.DynamoDBTyped"></a>

Anotasi untuk menimpa pengikatan jenis atribut standar. Jenis standar tidak memerlukan anotasi jika menerapkan pengikatan atribut default untuk jenis tersebut. 

## Atribut Dynamo DBVersion
<a name="DynamoDBMapper.Annotations.DynamoDBVersionAttribute"></a>

Mengidentifikasi properti kelas untuk menyimpan nomor versi penguncian optimis. `DynamoDBMapper` menetapkan nomor versi untuk properti ini ketika menyimpan item baru, dan menambahkannya setiap kali Anda memperbarui item. Hanya jenis skalar nomor yang didukung. Untuk informasi selengkapnya tentang jenis data, lihat [Jenis Data](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes). Untuk informasi selengkapnya tentang penentuan versi, lihat [DynamoDB dan penguncian optimis dengan nomor versi](DynamoDBMapper.OptimisticLocking.md).

# Pengaturan konfigurasi opsional untuk Dynamo DBMapper
<a name="DynamoDBMapper.OptionalConfig"></a>

Saat Anda membuat instans `DynamoDBMapper`, instans tersebut memiliki perilaku default tertentu; Anda dapat menimpa pengaturan default ini menggunakan kelas `DynamoDBMapperConfig`. 

Cuplikan kode berikut akan membuat `DynamoDBMapper` dengan pengaturan kustom:

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
        .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER)
        .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
        .withTableNameOverride(null)
        .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
    .build();

DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);
```

Untuk informasi selengkapnya, lihat [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.html) di Referensi API [AWS SDK untuk Java .](https://docs.aws.amazon.com/sdk-for-java/latest/reference/)

Anda dapat menggunakan argumen berikut untuk instans `DynamoDBMapperConfig`:
+ Nilai enumerasi `DynamoDBMapperConfig.ConsistentReads`:
  + `EVENTUAL`—instans pemeta menggunakan permintaan bacaan akhir konsisten.
  + `CONSISTENT`—instans pemeta menggunakan permintaan bacaan sangat konsisten. Anda dapat menggunakan pengaturan opsional ini dengan operasi `load`, `query`, atau `scan`. Bacaan sangat konsisten memiliki implikasi terhadap performa dan penagihan; lihat [halaman detail produk](https://aws.amazon.com/dynamodb) DynamoDB untuk informasi selengkapnya.

  Jika Anda tidak menentukan pengaturan konsistensi baca untuk instans pemeta Anda, pengaturan defaultnya adalah `EVENTUAL`.
**catatan**  
Nilai ini diterapkan dalam`query`,, `querypage``load`, dan `batch load` operasi DynamoDBMapper.
+ Nilai enumerasi `DynamoDBMapperConfig.PaginationLoadingStrategy`—Mengontrol cara instans pemeta memproses daftar data yang diberi nomor halaman, seperti hasil dari `query` atau `scan`:
  + `LAZY_LOADING`—instans pemeta memuat data jika memungkinkan, dan menyimpan semua hasil yang dimuat dalam memori.
  + `EAGER_LOADING`—instans pemeta memuat data segera setelah daftar diinisialisasi.
  + `ITERATION_ONLY`—Anda hanya dapat menggunakan Iterator untuk membaca dari daftar. Selama iterasi, daftar akan menghapus semua hasil lama sebelum memuat halaman berikutnya, sehingga daftar akan menyimpan maksimal satu halaman dari hasil yang dimuat dalam memori. Hal ini juga berarti bahwa daftar hanya dapat diiterasi satu kali. Strategi ini direkomendasikan saat menangani item besar, guna mengurangi overhead memori.

  Jika Anda tidak menentukan strategi pemuatan pemberian nomor halaman untuk instans pemeta Anda, pengaturan defaultnya adalah `LAZY_LOADING`.
+ Nilai enumerasi `DynamoDBMapperConfig.SaveBehavior` - Menentukan cara instans pemeta akan menangani atribut selama operasi simpan:
  + `UPDATE`—selama operasi simpan, semua atribut model diperbarui, dan atribut yang tidak dibuat modelnya tidak terpengaruh. Jenis angka primitif (byte, int, long) diatur ke 0. Jenis objek diatur ke null. 
  + `CLOBBER`—menghapus dan mengganti semua atribut, termasuk yang tidak dibuat modelnya, selama operasi simpan. Hal ini dilakukan dengan menghapus item lalu membuatnya kembali. Batasan bidang dengan versi juga diabaikan.

   Jika Anda tidak menentukan perilaku simpan untuk instans pemeta, pengaturan defaultnya adalah `UPDATE`.
**catatan**  
Operasi DBMapper transaksional Dynamo tidak mendukung pencacahan. `DynamoDBMapperConfig.SaveBehavior` 
+ Objek `DynamoDBMapperConfig.TableNameOverride`—Menginstruksikan instans pemeta untuk mengabaikan nama tabel yang ditentukan oleh anotasi `DynamoDBTable` kelas, dan menggunakan nama tabel lain yang Anda berikan. Ini berguna saat mempartisi data Anda menjadi beberapa tabel saat runtime. 

Anda dapat mengganti objek konfigurasi default untuk `DynamoDBMapper` per operasi, jika diperlukan.

# DynamoDB dan penguncian optimis dengan nomor versi
<a name="DynamoDBMapper.OptimisticLocking"></a>

*Penguncian optimis* adalah strategi untuk memastikan bahwa item sisi klien yang Anda perbarui (atau hapus) sama dengan item di Amazon DynamoDB. Jika Anda menggunakan strategi ini, penulisan basis data Anda dilindungi agar tidak ditimpa oleh penulisan orang lain, dan sebaliknya.

Dengan penguncian optimis, setiap item memiliki atribut yang berfungsi sebagai nomor versi. Jika Anda mengambil item dari tabel, aplikasi akan mencatat nomor versi item tersebut. Anda dapat memperbarui item, tetapi hanya jika nomor versi di sisi server tidak berubah. Jika ada ketidakcocokan versi, artinya orang lain telah mengubah item sebelum Anda melakukannya. Upaya pembaruan gagal, karena versi item Anda sudah usang. Jika ini terjadi, coba lagi dengan mengambil item dan kemudian mencoba memperbaruinya. Penguncian optimis mencegah Anda menimpa perubahan secara tidak sengaja yang dibuat oleh orang lain. Penguncian optimis juga mencegah orang lain menimpa perubahan Anda secara tidak sengaja.

Meskipun Anda dapat menerapkan strategi penguncian optimis Anda sendiri, AWS SDK untuk Java memberikan `@DynamoDBVersionAttribute` anotasi. Di kelas pemetaan untuk tabel, Anda menetapkan satu properti untuk menyimpan nomor versi, dan menandainya menggunakan anotasi ini. Saat Anda menyimpan objek, item terkait dalam tabel DynamoDB akan memiliki atribut yang menyimpan nomor versi. `DynamoDBMapper` menetapkan nomor versi saat Anda pertama kali menyimpan objek, dan otomatis menambahkan nomor versi setiap kali Anda memperbarui item. Permintaan perbarui atau hapus Anda hanya akan berhasil jika versi objek sisi klien cocok dengan nomor versi item yang sesuai dalam tabel DynamoDB.

 `ConditionalCheckFailedException` ditampilkan jika: 
+  Anda menggunakan penguncian optimis dengan `@DynamoDBVersionAttribute` dan nilai versi pada server yang berbeda dari nilai pada sisi klien. 
+  Anda menentukan batasan bersyarat Anda sendiri saat menyimpan data menggunakan `DynamoDBMapper` dengan `DynamoDBSaveExpression` dan batasan ini gagal. 

**catatan**  
Tabel global DynamoDB menggunakan rekonsiliasi “penulis terakhir menang” antara pembaruan bersamaan. Jika Anda menggunakan tabel global, kebijakan penulis terakhir akan menang. Jadi dalam hal ini, strategi penguncian tidak berfungsi seperti yang diharapkan.
Operasi tulis transaksional `DynamoDBMapper` tidak mendukung ekspresi syarat dan anotasi `@DynamoDBVersionAttribute` pada objek yang sama. Jika sebuah objek dalam penulisan transaksional dianotasi dengan `@DynamoDBVersionAttribute` dan juga memiliki ekspresi kondisi, maka akan dilemparkan. SdkClientException 

Misalnya, kode Java berikut mendefinisikan kelas `CatalogItem` yang memiliki beberapa properti. Properti `Version` ditandai dengan anotasi `@DynamoDBVersionAttribute`.

**Example**  

```
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {

    private Integer id;
    private String title;
    private String ISBN;
    private Set<String> bookAuthors;
    private String someProp;
    private Long version;

    @DynamoDBHashKey(attributeName="Id")
    public Integer getId() { return id; }
    public void setId(Integer Id) { this.id = Id; }

    @DynamoDBAttribute(attributeName="Title")
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    @DynamoDBAttribute(attributeName="ISBN")
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN;}

    @DynamoDBAttribute(attributeName = "Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }

    @DynamoDBIgnore
    public String getSomeProp() { return someProp;}
    public void setSomeProp(String someProp) {this.someProp = someProp;}

    @DynamoDBVersionAttribute
    public Long getVersion() { return version; }
    public void setVersion(Long version) { this.version = version;}
}
```

Anda dapat menerapkan anotasi `@DynamoDBVersionAttribute` untuk jenis yang dapat dinihilkan yang diberikan oleh kelas pembungkus primitif yang menyediakan jenis yang dapat di-null-kan, seperti `Long` dan `Integer`. 

Penguncian optimis memiliki dampak sebagai berikut pada metode `DynamoDBMapper` ini:
+ `save` — Untuk item baru, `DynamoDBMapper` menetapkan nomor versi awal 1. Jika Anda mengambil item, memperbarui satu atau beberapa propertinya, dan mencoba untuk menyimpan perubahan, operasi simpan hanya akan berhasil jika nomor versi di sisi klien dan sisi server cocok. `DynamoDBMapper` menambah nomor versi secara otomatis.
+ `delete` — Metode `delete` mengambil sebuah objek sebagai parameter, dan `DynamoDBMapper` melakukan pemeriksaan versi sebelum menghapus item. Pemeriksaan versi dapat dinonaktifkan jika `DynamoDBMapperConfig.SaveBehavior.CLOBBER` ditentukan dalam permintaan.

  Implementasi internal penguncian optimis dalam `DynamoDBMapper` menggunakan pembaruan bersyarat dan dukungan penghapusan bersyarat yang disediakan oleh DynamoDB. 
+ `transactionWrite` —
  + `Put` — Untuk item baru, `DynamoDBMapper` menetapkan nomor versi awal 1. Jika Anda mengambil item, memperbarui satu atau beberapa propertinya, dan mencoba untuk menyimpan perubahan, operasi masukkan hanya akan berhasil jika nomor versi di sisi klien dan sisi server cocok. `DynamoDBMapper` menambah nomor versi secara otomatis.
  + `Update` — Untuk item baru, `DynamoDBMapper` menetapkan nomor versi awal 1. Jika Anda mengambil item, memperbarui satu atau beberapa propertinya, dan mencoba untuk menyimpan perubahan, operasi perbarui hanya akan berhasil jika nomor versi di sisi klien dan sisi server cocok. `DynamoDBMapper` menambah nomor versi secara otomatis.
  + `Delete` — `DynamoDBMapper` melakukan pemeriksaan versi sebelum menghapus item. Operasi hapus hanya akan berhasil jika nomor versi pada sisi klien dan sisi server cocok.
  + `ConditionCheck` — Anotasi `@DynamoDBVersionAttribute` tidak didukung untuk operasi `ConditionCheck`. An SdkClientException akan dilemparkan ketika `ConditionCheck` item dianotasi dengan. `@DynamoDBVersionAttribute` 

## Menonaktifkan penguncian optimis
<a name="DynamoDBMapper.OptimisticLocking.Disabling"></a>

Untuk menonaktifkan penguncian optimis, Anda dapat mengubah nilai enumerasi `DynamoDBMapperConfig.SaveBehavior` dari `UPDATE` menjadi `CLOBBER`. Anda dapat melakukannya dengan membuat instans `DynamoDBMapperConfig` yang melewatkan pemeriksaan versi dan menggunakan instans ini untuk semua permintaan Anda. Untuk informasi tentang `DynamoDBMapperConfig.SaveBehavior` dan parameter `DynamoDBMapper` opsional lainnya, lihat [Pengaturan konfigurasi opsional untuk Dynamo DBMapper](DynamoDBMapper.OptionalConfig.md). 

Anda juga dapat mengatur perilaku penguncian untuk operasi tertentu saja. Misalnya, cuplikan Java berikut menggunakan `DynamoDBMapper` untuk menyimpan item katalog. Cuplikan ini menentukan `DynamoDBMapperConfig.SaveBehavior` dengan menambahkan parameter `DynamoDBMapperConfig` opsional untuk metode `save`. 

**catatan**  
Metode TransactionWrite tidak mendukung Dynamo Config. DBMapper SaveBehaviorkonfigurasi. Menonaktifkan penguncian optimis untuk transactionWrite tidak didukung.

**Example**  

```
DynamoDBMapper mapper = new DynamoDBMapper(client);

// Load a catalog item.
CatalogItem item = mapper.load(CatalogItem.class, 101);
item.setTitle("This is a new title for the item");
...
// Save the item.
mapper.save(item,
    new DynamoDBMapperConfig(
        DynamoDBMapperConfig.SaveBehavior.CLOBBER));
```

# Memetakan data arbitrer di DynamoDB
<a name="DynamoDBMapper.ArbitraryDataMapping"></a>

Selain jenis Java yang didukung (lihat [Tipe data yang didukung untuk Dynamo DBMapper untuk Java](DynamoDBMapper.DataTypes.md)), Anda dapat menggunakan jenis di aplikasi Anda yang tidak memiliki pemetaan langsung ke jenis Amazon DynamoDB. Untuk memetakan jenis ini, Anda harus menyediakan implementasi yang mengonversi jenis kompleks Anda ke jenis yang didukung DynamoDB dan sebaliknya, serta menganotasi metode penilai jenis kompleks menggunakan anotasi `@DynamoDBTypeConverted`. Kode konverter mengubah data ketika objek disimpan atau dimuat. Kode ini juga digunakan untuk semua operasi yang mengonsumsi jenis kompleks. Perhatikan bahwa saat membandingkan data selama operasi kueri dan pindai, perbandingan pada data yang disimpan dalam DynamoDB akan dilakukan.

Misalnya, pertimbangkan kelas `CatalogItem` berikut yang mendefinisikan properti, `Dimension`, yaitu `DimensionType`. Properti ini menyimpan dimensi item sebagai tinggi, lebar, dan ketebalan. Misalnya Anda memutuskan untuk menyimpan dimensi item ini sebagai string (seperti 8.5x11x.05) dalam DynamoDB. Contoh berikut memberikan kode konverter yang mengonversi objek `DimensionType` menjadi string dan string menjadi `DimensionType`.



**catatan**  
Contoh kode ini mengasumsikan bahwa Anda telah memuat data ke DynamoDB untuk akun Anda dengan mengikuti petunjuk di bagian [Membuat tabel dan memuat data untuk contoh kode di DynamoDB](SampleData.md).  
Untuk step-by-step instruksi untuk menjalankan contoh berikut, lihat[Contoh kode Java](CodeSamples.Java.md).

**Example**  

```
public class DynamoDBMapperExample {

    static AmazonDynamoDB client;

    public static void main(String[] args) throws IOException {

        // Set the AWS region you want to access.
        Regions usWest2 = Regions.US_WEST_2;
        client = AmazonDynamoDBClientBuilder.standard().withRegion(usWest2).build();

        DimensionType dimType = new DimensionType();
        dimType.setHeight("8.00");
        dimType.setLength("11.0");
        dimType.setThickness("1.0");

        Book book = new Book();
        book.setId(502);
        book.setTitle("Book 502");
        book.setISBN("555-5555555555");
        book.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author2")));
        book.setDimensions(dimType);

        DynamoDBMapper mapper = new DynamoDBMapper(client);
        mapper.save(book);

        Book bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Book info: " + "\n" + bookRetrieved);

        bookRetrieved.getDimensions().setHeight("9.0");
        bookRetrieved.getDimensions().setLength("12.0");
        bookRetrieved.getDimensions().setThickness("2.0");

        mapper.save(bookRetrieved);

        bookRetrieved = mapper.load(Book.class, 502);
        System.out.println("Updated book info: " + "\n" + bookRetrieved);
    }

    @DynamoDBTable(tableName = "ProductCatalog")
    public static class Book {
        private int id;
        private String title;
        private String ISBN;
        private Set<String> bookAuthors;
        private DimensionType dimensionType;

        // Partition key
        @DynamoDBHashKey(attributeName = "Id")
        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        @DynamoDBAttribute(attributeName = "Title")
        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        @DynamoDBAttribute(attributeName = "ISBN")
        public String getISBN() {
            return ISBN;
        }

        public void setISBN(String ISBN) {
            this.ISBN = ISBN;
        }

        @DynamoDBAttribute(attributeName = "Authors")
        public Set<String> getBookAuthors() {
            return bookAuthors;
        }

        public void setBookAuthors(Set<String> bookAuthors) {
            this.bookAuthors = bookAuthors;
        }

        @DynamoDBTypeConverted(converter = DimensionTypeConverter.class)
        @DynamoDBAttribute(attributeName = "Dimensions")
        public DimensionType getDimensions() {
            return dimensionType;
        }

        @DynamoDBAttribute(attributeName = "Dimensions")
        public void setDimensions(DimensionType dimensionType) {
            this.dimensionType = dimensionType;
        }

        @Override
        public String toString() {
            return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors + ", dimensionType= "
                    + dimensionType.getHeight() + " X " + dimensionType.getLength() + " X "
                    + dimensionType.getThickness()
                    + ", Id=" + id + ", Title=" + title + "]";
        }
    }

    static public class DimensionType {

        private String length;
        private String height;
        private String thickness;

        public String getLength() {
            return length;
        }

        public void setLength(String length) {
            this.length = length;
        }

        public String getHeight() {
            return height;
        }

        public void setHeight(String height) {
            this.height = height;
        }

        public String getThickness() {
            return thickness;
        }

        public void setThickness(String thickness) {
            this.thickness = thickness;
        }
    }

    // Converts the complex type DimensionType to a string and vice-versa.
    static public class DimensionTypeConverter implements DynamoDBTypeConverter<String, DimensionType> {

        @Override
        public String convert(DimensionType object) {
            DimensionType itemDimensions = (DimensionType) object;
            String dimension = null;
            try {
                if (itemDimensions != null) {
                    dimension = String.format("%s x %s x %s", itemDimensions.getLength(), itemDimensions.getHeight(),
                            itemDimensions.getThickness());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dimension;
        }

        @Override
        public DimensionType unconvert(String s) {

            DimensionType itemDimension = new DimensionType();
            try {
                if (s != null && s.length() != 0) {
                    String[] data = s.split("x");
                    itemDimension.setLength(data[0].trim());
                    itemDimension.setHeight(data[1].trim());
                    itemDimension.setThickness(data[2].trim());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return itemDimension;
        }
    }
}
```

# Contoh Dynamo DBMapper
<a name="DynamoDBMapper.Examples"></a>

 AWS SDK for Java menyediakan `DynamoDBMapper` kelas, memungkinkan Anda untuk memetakan kelas sisi klien Anda ke tabel DynamoDB. Untuk menggunakan `DynamoDBMapper`, tentukan hubungan antara item dalam tabel DynamoDB dan instans objek yang sesuai dalam kode Anda. Kelas `DynamoDBMapper` memungkinkan Anda melakukan berbagai operasi buat, baca, perbarui, dan hapus (CRUD) pada item, dan menjalankan kueri serta memindai tabel.

*Untuk mempelajari lebih lanjut tentang cara menggunakan`DynamoDBMapper`, lihat [Contoh DynamoDB Menggunakan SDK AWS for Java di SDK for Java](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-dynamodb.html) 1.x Panduan AWS Pengembang.* 

# Java 2.x: DynamoDB Enhanced Client
<a name="DynamoDBEnhanced"></a>

Klien yang disempurnakan DynamoDB adalah pustaka tingkat tinggi yang merupakan bagian dari versi 2 ( AWS SDK untuk Java v2). Ini menawarkan cara mudah untuk memetakan kelas sisi klien ke tabel DynamoDB. Anda menentukan hubungan antara tabel dan kelas model yang sesuai dalam kode Anda. Setelah menentukan hubungan tersebut, Anda dapat melakukan berbagai operasi buat, baca, perbarui, atau hapus (CRUD) pada tabel atau item di DynamoDB.

Untuk informasi selengkapnya tentang bagaimana Anda dapat menggunakan klien yang disempurnakan dengan DynamoDB, lihat [Menggunakan DynamoDB Enhanced Client di 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html). AWS SDK untuk Java 

# Bekerja dengan model dokumen.NET di DynamoDB
<a name="DotNetSDKMidLevel"></a>

 AWS SDK untuk .NET Ini menyediakan kelas model dokumen yang membungkus beberapa operasi Amazon DynamoDB tingkat rendah, yang selanjutnya menyederhanakan pengkodean Anda. Dalam model dokumen, kelas utamanya adalah `Table` dan `Document`. Kelas `Table` menyediakan metode operasi data seperti `PutItem`, `GetItem`, dan `DeleteItem`. Kelas ini juga menyediakan metode `Query` dan `Scan`. Kelas `Document` mewakili satu item dalam tabel.

Kelas model dokumen sebelumnya tersedia di namespace `Amazon.DynamoDBv2.DocumentModel`.

**catatan**  
Anda tidak dapat menggunakan kelas model dokumen untuk membuat, memperbarui, dan menghapus tabel. Namun, model dokumen mendukung operasi data yang paling umum.

**Topics**
+ [Jenis data yang didukung](#MidLevelAPILimitations.SupportedTypes)

## Jenis data yang didukung
<a name="MidLevelAPILimitations.SupportedTypes"></a>

Model dokumen mendukung serangkaian jenis data .NET primitif dan jenis data koleksi. Model ini mendukung jenis data primitif berikut. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Guid`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

Tabel berikut merangkum pemetaan jenis .NET sebelumnya untuk jenis DynamoDB.


****  

| Jenis .NET primitif | Jenis DynamoDB | 
| --- | --- | 
|  Semua jenis angka  |  `N` (jenis angka)  | 
|  Semua jenis string  |  `S` (jenis string)   | 
|  MemoryStream, byte []  |  `B` (jenis biner)   | 
| bool | N (jenis angka). 0 mewakili false dan 1 mewakili true. | 
| DateTime | S (jenis string). Nilai DateTime disimpan sebagai string berformat ISO-8601. | 
| Guid | S (jenis string). | 
| Jenis koleksi (Daftar, HashSet, dan array) | Jenis BS (set biner), jenis SS (set string), dan jenis NS (set angka) | 

AWS SDK untuk .NET mendefinisikan tipe untuk memetakan tipe Boolean, null, list, dan map DynamoDB ke API model dokumen.NET:
+ Gunakan `DynamoDBBool` untuk jenis Boolean.
+ Gunakan `DynamoDBNull` untuk jenis null.
+ Gunakan `DynamoDBList` untuk jenis daftar.
+ Gunakan `Document` untuk jenis peta.

**catatan**  
Nilai biner kosong didukung.
Pembacaan nilai string kosong didukung. Nilai atribut string kosong didukung dalam nilai atribut string dari jenis Set saat menulis ke DynamoDB. Nilai atribut string kosong dari jenis string dan nilai string kosong dalam jenis Daftar atau Peta dihilangkan dari permintaan tulis

# Bekerja dengan model persistensi objek.NET dan DynamoDB
<a name="DotNetSDKHighLevel"></a>

 AWS SDK untuk .NET Ini menyediakan model persistensi objek yang memungkinkan Anda memetakan kelas sisi klien Anda ke tabel Amazon DynamoDB. Kemudian, setiap instans objek dipetakan ke item dalam tabel yang sesuai. Untuk menyimpan objek sisi klien ke tabel, model persistensi objek menyediakan kelas `DynamoDBContext`, yaitu titik masuk ke DynamoDB. Kelas ini menyediakan koneksi ke DynamoDB dan memungkinkan Anda mengakses tabel, melakukan berbagai operasi CRUD, dan menjalankan kueri.

Model persistensi objek menyediakan satu set atribut untuk memetakan kelas sisi klien ke tabel, dan properties/fields ke atribut tabel.

**catatan**  
Model persistensi objek tidak menyediakan API untuk membuat, memperbarui, atau menghapus tabel. Model ini hanya menyediakan operasi data. Anda hanya dapat menggunakan API AWS SDK untuk .NET tingkat rendah untuk membuat, memperbarui, dan menghapus tabel.

Contoh berikut menunjukkan cara kerja model persistensi objek. Contoh ini dimulai dengan tabel `ProductCatalog`. Contoh ini memiliki `Id` sebagai kunci primernya.

```
ProductCatalog(Id, ...)
```

Katakanlah Anda memiliki kelas `Book` yang berisi properti `Title`, `ISBN`, dan `Authors`. Anda dapat memetakan kelas `Book` ke tabel `ProductCatalog` dengan menambahkan atribut yang didefinisikan oleh model persistensi objek, seperti yang ditunjukkan dalam kode contoh C\$1 berikut.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]
    public int Id { get; set; }

    public string Title { get; set; }
    public int ISBN { get; set; }

    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }

    [DynamoDBIgnore]
    public string CoverPage { get; set; }
  }
```

Dalam contoh sebelumnya, atribut `DynamoDBTable` memetakan kelas `Book` ke tabel `ProductCatalog`.

Model persistensi objek mendukung pemetaan eksplisit dan default antara properti kelas dan atribut tabel.
+ **Pemetaan eksplisit—**Untuk memetakan properti ke kunci primer, Anda harus menggunakan atribut model persistensi objek `DynamoDBHashKey` dan `DynamoDBRangeKey`. Selain itu, untuk atribut kunci nonprimer, jika nama properti di kelas Anda dan atribut tabel terkait yang ingin Anda petakan tidak sama, Anda harus mendefinisikan pemetaan dengan menambahkan atribut `DynamoDBProperty` secara eksplisit.

  Dalam contoh sebelumnya, properti `Id` dipetakan ke kunci primer dengan nama yang sama, dan properti `BookAuthors` dipetakan ke atribut `Authors` dalam tabel `ProductCatalog`.
+ **Pemetaan default—**Secara default, model persistensi objek memetakan properti kelas ke atribut dengan nama yang sama dalam tabel.

  Dalam contoh sebelumnya, properti `Title` dan `ISBN` dipetakan ke atribut dengan nama yang sama dalam tabel `ProductCatalog`.

Anda tidak perlu memetakan setiap properti kelas tunggal. Anda mengidentifikasi properti ini dengan menambahkan atribut `DynamoDBIgnore`. Ketika Anda menyimpan instans `Book` ke tabel, `DynamoDBContext` tidak menyertakan properti `CoverPage`. Instans tersebut juga tidak mengembalikan properti ini saat Anda mengambil instans buku.

Anda dapat memetakan properti jenis .NET primitif seperti int dan string. Anda juga dapat memetakan setiap jenis data arbitrer selama Anda memberikan konverter yang sesuai untuk memetakan data arbitrer ke salah satu jenis DynamoDB. Untuk mempelajari cara memetakan jenis arbitrer, lihat [Memetakan data arbitrer dengan DynamoDB menggunakan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.ArbitraryDataMapping.md).

Model persistensi objek mendukung penguncian optimis. Selama operasi pembaruan, model ini memastikan bahwa Anda memiliki salinan terbaru dari item yang akan Anda perbarui. Untuk informasi selengkapnya, lihat [Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.VersionSupport.md).

Untuk informasi selengkapnya, lihat topik di bawah.

**Topics**
+ [Jenis data yang didukung](#DotNetDynamoDBContext.SupportedTypes)
+ [Atribut DynamoDB dari model persistensi objek.NET](DeclarativeTagsList.md)
+ [DBContext Kelas Dynamo dari model persistensi objek.NET](DotNetDynamoDBContext.md)
+ [Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.VersionSupport.md)
+ [Memetakan data arbitrer dengan DynamoDB menggunakan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.ArbitraryDataMapping.md)

## Jenis data yang didukung
<a name="DotNetDynamoDBContext.SupportedTypes"></a>

Model persistensi objek mendukung sekumpulan jenis data .NET primitif, koleksi, dan jenis data arbitrer. Model ini mendukung jenis data primitif berikut. 
+ `bool`
+ `byte` 
+ `char`
+ `DateTime`
+ `decimal`
+ `double`
+ `float`
+ `Int16`
+ `Int32`
+ `Int64`
+ `SByte`
+ `string`
+ `UInt16`
+ `UInt32`
+ `UInt64`

Model persistensi objek juga mendukung jenis koleksi.NET. `DynamoDBContext`mampu mengkonversi jenis koleksi beton dan sederhana Plain Old CLR Objects (POCOs).

Tabel berikut merangkum pemetaan jenis .NET sebelumnya untuk jenis DynamoDB.


****  

| Jenis .NET primitif | Jenis DynamoDB | 
| --- | --- | 
|  Semua jenis angka  |  `N` (jenis angka)  | 
|  Semua jenis string  |  `S` (jenis string)   | 
|  MemoryStream, byte []  |  `B` (jenis biner)   | 
| bool | N (jenis angka). 0 mewakili false dan 1 mewakili true. | 
| Jenis koleksi | Jenis BS (kumpulan biner), jenis SS (kumpulan string), dan jenis NS (kumpulan angka). | 
| DateTime | S (jenis string). Nilai DateTime disimpan sebagai string berformat ISO-8601. | 

Model persistensi objek juga mendukung jenis data arbitrer. Namun, Anda harus menyediakan kode konverter untuk memetakan jenis kompleks ke jenis DynamoDB.

**catatan**  
Nilai biner kosong didukung.
Pembacaan nilai string kosong didukung. Nilai atribut string kosong didukung dalam nilai atribut string dari jenis Set saat menulis ke DynamoDB. Nilai atribut string kosong dari jenis string dan nilai string kosong dalam jenis Daftar atau Peta dihilangkan dari permintaan tulis

# Atribut DynamoDB dari model persistensi objek.NET
<a name="DeclarativeTagsList"></a>

Bagian ini menjelaskan atribut yang ditawarkan model persistensi objek agar Anda dapat memetakan kelas dan properti ke tabel dan atribut DynamoDB.

**catatan**  
Dalam atribut berikut, hanya `DynamoDBTable` dan `DynamoDBHashKey` yang diperlukan.

## Dinamo DBGlobal SecondaryIndexHashKey
<a name="w2aac17b9c21c23c37b7"></a>

Memetakan properti kelas ke kunci partisi untuk indeks sekunder global. Gunakan atribut ini jika Anda perlu `Query` indeks sekunder global.

## Dinamo DBGlobal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37b9"></a>

Memetakan properti kelas ke kunci urutan indeks sekunder global. Gunakan atribut ini jika Anda perlu `Query` indeks sekunder global dan ingin menyempurnakan hasil menggunakan kunci urutan indeks.

## Kunci Dynamo DBHash
<a name="w2aac17b9c21c23c37c11"></a>

Memetakan properti kelas ke kunci partisi untuk kunci primer tabel. Atribut kunci primer tidak boleh berupa jenis koleksi.

Contoh kode C\$1 berikut memetakan kelas `Book` ke tabel `ProductCatalog`, dan properti `Id` ke kunci partisi kunci kunci primer tabel.

```
[DynamoDBTable("ProductCatalog")]
public class Book 
{
    [DynamoDBHashKey]
    public int Id { get; set; }

    // Additional properties go here.
}
```

## Dinamo DBIgnore
<a name="w2aac17b9c21c23c37c13"></a>

Menunjukkan bahwa properti terkait harus diabaikan. Jika tidak ingin menyimpan properti kelas, Anda dapat menambahkan atribut ini untuk meminta agar `DynamoDBContext` tidak menyertakan properti ini saat menyimpan objek ke tabel.

## Dinamo DBLocal SecondaryIndexRangeKey
<a name="w2aac17b9c21c23c37c15"></a>

Memetakan properti kelas ke kunci urutan indeks sekunder lokal. Gunakan atribut ini jika Anda perlu `Query` indeks sekunder lokal dan ingin menyempurnakan hasil menggunakan kunci urutan indeks.

## Dinamo DBProperty
<a name="w2aac17b9c21c23c37c17"></a>

Memetakan properti kelas ke atribut tabel. Jika properti kelas dipetakan ke atribut tabel dengan nama yang sama, Anda tidak perlu menentukan atribut ini. Namun, jika nama tidak sama, Anda dapat menggunakan tanda ini untuk memberikan pemetaan. Dalam pernyataan C\$1 berikut, `DynamoDBProperty` memetakan properti `BookAuthors` ke atribut `Authors` dalam tabel. 

```
[DynamoDBProperty("Authors")]
public List<string> BookAuthors { get; set; }
```

`DynamoDBContext` menggunakan informasi pemetaan ini untuk membuat atribut `Authors` saat menyimpan data objek ke tabel yang sesuai.

## Dinamo DBRenamable
<a name="w2aac17b9c21c23c37c19"></a>

Menentukan nama alternatif untuk properti kelas. Langkah ini berguna jika Anda menulis konverter khusus untuk memetakan data arbitrer ke tabel DynamoDB yang nama properti kelasnya berbeda dengan atribut tabel.

## Kunci Dynamo DBRange
<a name="w2aac17b9c21c23c37c21"></a>

Memetakan properti kelas ke kunci urutan untuk kunci primer tabel. Jika tabel memiliki kunci primer komposit (kunci partisi dan kunci urutan), Anda harus menentukan atribut `DynamoDBHashKey` dan `DynamoDBRangeKey` dalam pemetaan kelas Anda.

Misalnya, tabel sampel `Reply` memiliki kunci primer yang dibuat dari kunci partisi `Id` dan kunci urutan `Replenishment`. Contoh kode C\$1 berikut memetakan kelas `Reply` ke tabel `Reply`. Definisi kelas juga menunjukkan bahwa dua propertinya dipetakan ke kunci primer.

```
[DynamoDBTable("Reply")]
public class Reply 
{
   [DynamoDBHashKey]
   public int ThreadId { get; set; }
   [DynamoDBRangeKey]
   public string Replenishment { get; set; }
   
   // Additional properties go here.
}
```

## Dinamo DBTable
<a name="w2aac17b9c21c23c37c23"></a>

Mengidentifikasi tabel target di DynamoDB tempat kelas dipetakan. Misalnya, contoh kode C\$1 berikut memetakan kelas `Developer` ke tabel `People` di DynamoDB.

```
[DynamoDBTable("People")]
public class Developer { ...}
```

Atribut ini dapat diwariskan atau diganti.
+ Atribut `DynamoDBTable` dapat diwariskan. Dalam contoh sebelumnya, jika Anda menambahkan kelas baru, yaitu `Lead`, yang diwariskan dari kelas `Developer`, kelas tersebut juga dipetakan ke tabel `People`. Objek `Developer` dan `Lead` disimpan dalam tabel `People`.
+ Atribut `DynamoDBTable` juga dapat diganti. Dalam contoh kode C\$1 berikut, kelas `Manager` diwariskan dari kelas `Developer`. Namun, penambahan eksplisit atribut `DynamoDBTable` memetakan kelas ke tabel lainnya (`Managers`).

  ```
  [DynamoDBTable("Managers")]
  public class Manager : Developer { ...}
  ```

 Anda dapat menambahkan parameter opsional, yaitu `LowerCamelCaseProperties`, untuk meminta DynamoDB menulis huruf pertama dari nama properti dalam huruf kecil ketika menyimpan objek ke tabel, seperti yang ditunjukkan dalam contoh C\$1 berikut.

```
[DynamoDBTable("People", LowerCamelCaseProperties=true)]
public class Developer 
{
    string DeveloperName;
    ...
}
```

Ketika menyimpan instans kelas `Developer`, `DynamoDBContext` menyimpan properti `DeveloperName` sebagai `developerName`.

## Dinamo DBVersion
<a name="w2aac17b9c21c23c37c25"></a>

Mengidentifikasi properti kelas untuk menyimpan nomor versi item. Untuk informasi selengkapnya tentang penentuan versi, lihat [Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.VersionSupport.md).

# DBContext Kelas Dynamo dari model persistensi objek.NET
<a name="DotNetDynamoDBContext"></a>

Kelas `DynamoDBContext` adalah titik masuk ke basis data Amazon DynamoDB. Kelas ini menyediakan koneksi ke DynamoDB dan memungkinkan Anda mengakses data dalam berbagai tabel, melakukan berbagai operasi CRUD, dan menjalankan kueri. Kelas `DynamoDBContext` menyediakan metode berikut.

**Topics**
+ [Buat MultiTable BatchGet](#w2aac17b9c21c23c39b7)
+ [Buat MultiTable BatchWrite](#w2aac17b9c21c23c39b9)
+ [CreateBatchGet](#w2aac17b9c21c23c39c11)
+ [CreateBatchWrite](#w2aac17b9c21c23c39c13)
+ [Delete](#w2aac17b9c21c23c39c15)
+ [Dispose](#w2aac17b9c21c23c39c17)
+ [ExecuteBatchGet](#w2aac17b9c21c23c39c19)
+ [ExecuteBatchWrite](#w2aac17b9c21c23c39c21)
+ [FromDocument](#w2aac17b9c21c23c39c23)
+ [FromQuery](#w2aac17b9c21c23c39c25)
+ [FromScan](#w2aac17b9c21c23c39c27)
+ [GetTargetTable](#w2aac17b9c21c23c39c29)
+ [Muat](#w2aac17b9c21c23c39c31)
+ [Kueri](#w2aac17b9c21c23c39c33)
+ [Save](#w2aac17b9c21c23c39c35)
+ [Pindai](#w2aac17b9c21c23c39c37)
+ [ToDocument](#w2aac17b9c21c23c39c39)
+ [Menentukan parameter opsional untuk Dynamo DBContext](#OptionalConfigParams)

## Buat MultiTable BatchGet
<a name="w2aac17b9c21c23c39b7"></a>

Membuat objek `MultiTableBatchGet`, yang terdiri dari beberapa objek `BatchGet` individual. Setiap objek `BatchGet` dapat digunakan untuk mengambil item dari tabel DynamoDB tunggal.

Untuk mengambil item dari tabel, gunakan metode `ExecuteBatchGet`, dengan meneruskan objek `MultiTableBatchGet` sebagai parameter.

## Buat MultiTable BatchWrite
<a name="w2aac17b9c21c23c39b9"></a>

Membuat objek `MultiTableBatchWrite`, yang terdiri dari beberapa objek `BatchWrite` individual. Setiap objek `BatchWrite` dapat digunakan untuk menulis atau menghapus item dalam tabel DynamoDB tunggal.

Untuk menulis ke tabel, gunakan metode `ExecuteBatchWrite`, dengan meneruskan objek `MultiTableBatchWrite` sebagai parameter.

## CreateBatchGet
<a name="w2aac17b9c21c23c39c11"></a>

Membuat objek `BatchGet` yang dapat Anda gunakan untuk mengambil beberapa item dari tabel. 

## CreateBatchWrite
<a name="w2aac17b9c21c23c39c13"></a>

Membuat objek `BatchWrite` yang dapat Anda gunakan untuk menempatkan beberapa item ke dalam tabel, atau untuk menghapus beberapa item dari tabel. 

## Delete
<a name="w2aac17b9c21c23c39c15"></a>

Menghapus item dari tabel. Metode ini memerlukan kunci primer dari item yang ingin Anda hapus. Anda dapat memberikan nilai kunci primer maupun objek sisi klien yang berisi nilai kunci primer sebagai parameter untuk metode ini.
+ Jika Anda menentukan objek sisi klien sebagai parameter dan Anda telah mengaktifkan penguncian optimis, penghapusan hanya akan berhasil jika versi sisi klien dan sisi server objek cocok.
+ Jika Anda hanya menetapkan nilai kunci primer sebagai parameter, penghapusan akan berhasil terlepas dari apakah Anda telah mengaktifkan penguncian optimis atau tidak.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `DeleteAsync`.

## Dispose
<a name="w2aac17b9c21c23c39c17"></a>

Membuang semua sumber daya yang dikelola dan tidak dikelola.

## ExecuteBatchGet
<a name="w2aac17b9c21c23c39c19"></a>

Membaca data dari satu atau beberapa tabel, yang memproses semua objek `BatchGet` dalam `MultiTableBatchGet`.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `ExecuteBatchGetAsync`.

## ExecuteBatchWrite
<a name="w2aac17b9c21c23c39c21"></a>

Menulis atau menghapus data dalam satu atau beberapa tabel, yang memproses semua objek `BatchWrite` dalam `MultiTableBatchWrite`.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `ExecuteBatchWriteAsync`.

## FromDocument
<a name="w2aac17b9c21c23c39c23"></a>

Mengingat instans `Document`, metode `FromDocument` akan mengembalikan instans dari kelas sisi klien.

Langkah ini membantu jika Anda ingin menggunakan kelas model dokumen bersama dengan model persistensi objek untuk melakukan operasi data. Untuk informasi selengkapnya tentang kelas model dokumen yang disediakan oleh AWS SDK untuk .NET, lihat[Bekerja dengan model dokumen.NET di DynamoDB](DotNetSDKMidLevel.md).

Misalkan Anda memiliki objek `Document` bernama `doc`, yang berisi representasi item `Forum`. (Untuk mengetahui cara membuat objek ini, lihat deskripsi untuk metode `ToDocument` nanti dalam topik ini.) Anda dapat menggunakan `FromDocument` untuk mengambil item `Forum` dari `Document`, seperti yang ditunjukkan dalam contoh kode C\$1 berikut.

**Example**  

```
forum101 = context.FromDocument<Forum>(101);
```

**catatan**  
Jika objek `Document` mengimplementasikan antarmuka `IEnumerable`, Anda dapat menggunakan metode `FromDocuments` sebagai gantinya. Metode ini memungkinkan Anda melakukan iterasi pada semua instans kelas dalam `Document`.

## FromQuery
<a name="w2aac17b9c21c23c39c25"></a>

Menjalankan operasi `Query`, dengan parameter kueri yang didefinisikan dalam objek `QueryOperationConfig`.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `FromQueryAsync`.

## FromScan
<a name="w2aac17b9c21c23c39c27"></a>

Menjalankan operasi `Scan`, dengan parameter pemindaian yang didefinisikan dalam objek `ScanOperationConfig`.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `FromScanAsync`.

## GetTargetTable
<a name="w2aac17b9c21c23c39c29"></a>

Mengambil tabel target untuk jenis yang ditentukan. Langkah ini berguna jika Anda menulis konverter khusus untuk memetakan data arbitrer ke tabel DynamoDB, dan Anda perlu menentukan tabel yang terkait dengan jenis data khusus.

## Muat
<a name="w2aac17b9c21c23c39c31"></a>

Mengambil item dari tabel. Metode ini hanya memerlukan kunci primer dari item yang ingin Anda ambil. 

Secara default, DynamoDB akan mengembalikan item dengan nilai yang akhirnya konsisten. Untuk informasi tentang model konsistensi akhir, lihat [DynamoDB membaca konsistensi](HowItWorks.ReadConsistency.md).

`Load`atau `LoadAsync` metode memanggil [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)operasi, yang mengharuskan Anda untuk menentukan kunci utama untuk tabel. Karena `GetItem` mengabaikan `IndexName` parameter, Anda tidak dapat memuat item menggunakan partisi indeks atau kunci sortir. Oleh karena itu, Anda harus menggunakan kunci utama tabel untuk memuat item.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `LoadAsync`. Untuk melihat contoh penggunaan `LoadAsync` metode untuk melakukan operasi CRUD tingkat tinggi pada tabel DynamoDB, lihat contoh berikut.

```
    /// <summary>
    /// Shows how to perform high-level CRUD operations on an Amazon DynamoDB
    /// table.
    /// </summary>
    public class HighLevelItemCrud
    {
        public static async Task Main()
        {
            var client = new AmazonDynamoDBClient();
            DynamoDBContext context = new DynamoDBContext(client);
            await PerformCRUDOperations(context);
        }

        public static async Task PerformCRUDOperations(IDynamoDBContext context)
        {
            int bookId = 1001; // Some unique value.
            Book myBook = new Book
            {
                Id = bookId,
                Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
                Isbn = "111-1111111001",
                BookAuthors = new List<string> { "Author 1", "Author 2" },
            };

            // Save the book to the ProductCatalog table.
            await context.SaveAsync(myBook);

            // Retrieve the book from the ProductCatalog table.
            Book bookRetrieved = await context.LoadAsync<Book>(bookId);

            // Update some properties.
            bookRetrieved.Isbn = "222-2222221001";

            // Update existing authors list with the following values.
            bookRetrieved.BookAuthors = new List<string> { " Author 1", "Author x" };
            await context.SaveAsync(bookRetrieved);

            // Retrieve the updated book. This time, add the optional
            // ConsistentRead parameter using DynamoDBContextConfig object.
            await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            // Delete the book.
            await context.DeleteAsync<Book>(bookId);

            // Try to retrieve deleted book. It should return null.
            Book deletedBook = await context.LoadAsync<Book>(bookId, new DynamoDBContextConfig
            {
                ConsistentRead = true,
            });

            if (deletedBook == null)
            {
                Console.WriteLine("Book is deleted");
            }
        }
    }
```

## Kueri
<a name="w2aac17b9c21c23c39c33"></a>

Mengkueri tabel berdasarkan parameter kueri yang Anda berikan.

Anda dapat mengkueri tabel hanya jika memiliki kunci primer komposit (kunci partisi dan kunci urutan). Saat mengkueri, Anda harus menentukan kunci partisi dan syarat yang berlaku untuk kunci urutan.

Katakanlah Anda memiliki kelas `Reply` sisi klien yang dipetakan ke tabel `Reply` di DynamoDB. Contoh kode C\$1 berikut mengkueri tabel `Reply` untuk menemukan balasan utas dalam forum yang diposting dalam 15 hari terakhir. Tabel `Reply` memiliki kunci primer yang berisi kunci partisi `Id` dan kunci urutan `ReplyDateTime`.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

string replyId = "DynamoDB#DynamoDB Thread 1"; //Partition key
DateTime twoWeeksAgoDate = DateTime.UtcNow.Subtract(new TimeSpan(14, 0, 0, 0)); // Date to compare.
IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate);
```

Tabel ini mengembalikan koleksi objek `Reply`. 

Metode `Query` mengembalikan koleksi `IEnumerable` “lazy-loaded”. Metode ini awalnya hanya mengembalikan satu halaman hasil, lalu membuat panggilan layanan untuk halaman berikutnya jika diperlukan. Untuk mendapatkan semua item yang cocok, Anda perlu melakukan iterasi hanya pada `IEnumerable`.

Jika tabel Anda memiliki kunci primer sederhana (kunci partisi), Anda tidak dapat menggunakan metode `Query`. Sebaliknya, Anda dapat menggunakan metode `Load` dan menyediakan kunci partisi untuk mengambil item.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `QueryAsync`.

## Save
<a name="w2aac17b9c21c23c39c35"></a>

Menyimpan objek tertentu ke tabel. Jika kunci primer yang ditentukan dalam objek input tidak ada dalam tabel, metode akan menambahkan item baru ke tabel. Jika kunci primer ada, metode akan memperbarui item yang ada.

Jika Anda mengonfigurasi penguncian optimis, pembaruan hanya akan berhasil jika versi klien dan sisi server item cocok. Untuk informasi selengkapnya, lihat [Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.VersionSupport.md).

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `SaveAsync`.

## Pindai
<a name="w2aac17b9c21c23c39c37"></a>

Melakukan pemindaian pada seluruh tabel. 

Anda dapat memfilter hasil pemindaian dengan menentukan syarat pemindaian. Syarat ini dapat dievaluasi pada setiap atribut dalam tabel. Katakanlah Anda memiliki kelas sisi klien `Book` yang dipetakan ke tabel `ProductCatalog` di DynamoDB. Contoh C\$1 berikut memindai tabel dan hanya mengembalikan item buku dengan harga kurang dari 0.

**Example**  

```
IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>(
                    new ScanCondition("Price", ScanOperator.LessThan, price),
                    new ScanCondition("ProductCategory", ScanOperator.Equal, "Book")
      );
```

Metode `Scan` mengembalikan koleksi `IEnumerable` “lazy-loaded”. Metode ini awalnya hanya mengembalikan satu halaman hasil, lalu membuat panggilan layanan untuk halaman berikutnya jika diperlukan. Untuk mendapatkan semua item yang cocok, Anda hanya perlu melakukan iterasi pada `IEnumerable`.

Untuk alasan performa, Anda harus mencari tabel dan menghindari pemindaian tabel.

**catatan**  
Untuk melakukan operasi ini di latar belakang, gunakan metode `ScanAsync`.

## ToDocument
<a name="w2aac17b9c21c23c39c39"></a>

Mengembalikan instans untuk kelas model dokumen `Document` dari instans kelas Anda. 

Langkah ini membantu jika Anda ingin menggunakan kelas model dokumen bersama dengan model persistensi objek untuk melakukan operasi data. Untuk informasi selengkapnya tentang kelas model dokumen yang disediakan oleh AWS SDK untuk .NET, lihat[Bekerja dengan model dokumen.NET di DynamoDB](DotNetSDKMidLevel.md). 

Misalkan Anda memiliki kelas sisi klien yang dipetakan ke tabel `Forum` sampel. Anda kemudian dapat menggunakan `DynamoDBContext` untuk mendapatkan item sebagai objek `Document` dari tabel `Forum`, seperti yang ditunjukkan dalam contoh kode C\$1 berikut.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);

Forum forum101 = context.Load<Forum>(101); // Retrieve a forum by primary key.
Document doc = context.ToDocument<Forum>(forum101);
```

## Menentukan parameter opsional untuk Dynamo DBContext
<a name="OptionalConfigParams"></a>

Saat menggunakan model persistensi objek, Anda dapat menentukan parameter opsional berikut untuk `DynamoDBContext`.
+ **`ConsistentRead`—**Saat mengambil data menggunakan operasi `Load`, `Query`, atau `Scan`, Anda dapat menambahkan parameter opsional ini guna meminta nilai data terbaru.
+ **`IgnoreNullValues`—**Parameter ini memberi tahu `DynamoDBContext` untuk mengabaikan nilai null pada atribut selama operasi `Save`. Jika parameter ini adalah false (atau jika tidak diatur), nilai null ditafsirkan sebagai direktif untuk menghapus atribut tertentu. 
+ **`SkipVersionCheck`—** Parameter ini memberi tahu `DynamoDBContext` untuk tidak membandingkan versi saat menyimpan atau menghapus item. Untuk informasi selengkapnya tentang penentuan versi, lihat [Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET](DynamoDBContext.VersionSupport.md).
+ **`TableNamePrefix`—** Memberikan prefiks pada semua nama tabel dengan string tertentu. Jika parameter ini adalah null (atau jika tidak diatur), tidak ada prefiks yang digunakan.
+ `DynamoDBEntryConversion`- Menentukan skema konversi yang digunakan oleh klien. Anda dapat mengatur parameter ini ke versi V1 atau V2. V1 adalah versi default.

  Berdasarkan versi yang Anda tetapkan, perilaku parameter ini berubah. Contoh:
  + Di V1, tipe `bool` data dikonversi ke tipe `N` angka, di mana 0 mewakili false dan 1 mewakili true. Dalam V2, `bool` dikonversi ke`BOOL`.
  + Di V2, daftar dan array tidak dikelompokkan bersama. HashSets Daftar dan array numerik, tipe berbasis string, dan tipe berbasis biner dikonversi ke tipe `L` (Daftar), yang dapat dikirim kosong untuk memperbarui daftar. Ini tidak seperti V1, di mana daftar kosong tidak dikirim melalui kabel.

    Di V1, jenis koleksi, seperti Daftar, HashSet, dan array diperlakukan sama. Daftar, HashSet, dan array numerik dikonversi ke tipe `NS` (jumlah set). 

  Contoh berikut menetapkan versi skema konversi ke V2, yang mengubah perilaku konversi antara tipe.NET dan tipe data DynamoDB.

  ```
  var config = new DynamoDBContextConfig
  {
      Conversion = DynamoDBEntryConversion.V2
  };
  var contextV2 = new DynamoDBContext(client, config);
  ```

Contoh C \$1 berikut membuat yang baru `DynamoDBContext` dengan menentukan dua parameter opsional sebelumnya, dan. `ConsistentRead` `SkipVersionCheck`

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context =
       new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true});
```

`DynamoDBContext` menyertakan parameter opsional ini dengan setiap permintaan yang Anda kirimkan menggunakan konteks ini. 

Alih-alih mengatur parameter ini di tingkat `DynamoDBContext`, Anda dapat menentukannya untuk setiap operasi yang Anda jalankan menggunakan `DynamoDBContext`, seperti yang ditunjukkan dalam contoh kode C\$1 berikut. Contoh ini memuat item buku tertentu. `Load`Metode `DynamoDBContext` menentukan `ConsistentRead` dan parameter `SkipVersionCheck` opsional.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
...
DynamoDBContext context = new DynamoDBContext(client);
Book bookItem = context.Load<Book>(productId,new DynamoDBContextConfig{ ConsistentRead = true, SkipVersionCheck = true });
```

Dalam kasus ini, `DynamoDBContext` menyertakan parameter tersebut hanya ketika mengirimkan permintaan `Get`.

# Penguncian optimis menggunakan DynamoDB dan model persistensi objek AWS SDK untuk .NET
<a name="DynamoDBContext.VersionSupport"></a>

Dukungan penguncian optimis dalam model persistensi objek memastikan bahwa versi item untuk aplikasi Anda sama dengan versi item di sisi server sebelum memperbarui atau menghapus item. Misalkan Anda mengambil item untuk pembaruan. Namun, sebelum Anda mengirimkan pembaruan Anda kembali, beberapa aplikasi lain memperbarui item yang sama. Sekarang aplikasi Anda memiliki salinan item yang sudah usang. Tanpa penguncian optimis, setiap pembaruan yang Anda lakukan akan menimpa pembaruan yang dibuat oleh aplikasi lain. 

Fitur penguncian optimis model persistensi objek menyediakan tanda `DynamoDBVersion` yang dapat Anda gunakan untuk mengaktifkan penguncian optimis. Untuk menggunakan fitur ini, Anda menambahkan properti ke kelas Anda untuk menyimpan nomor versi. Anda menambahkan atribut `DynamoDBVersion` untuk properti. Ketika Anda pertama kali menyimpan objek, `DynamoDBContext` menetapkan nomor versi dan menambah nilai ini setiap kali Anda memperbarui item. 

Permintaan perbarui atau hapus Anda akan berhasil hanya jika versi objek sisi kliennya cocok dengan nomor versi item yang sesuai di sisi server. Jika aplikasi Anda memiliki salinan yang sudah usang, aplikasi tersebut harus mendapatkan versi terbaru dari server sebelum dapat memperbarui atau menghapus item.

Contoh kode C\$1 berikut mendefinisikan kelas `Book` dengan atribut persistensi objek yang memetakannya ke tabel `ProductCatalog`. Properti `VersionNumber` di kelas yang dilengkapi dengan atribut `DynamoDBVersion` menyimpan nilai nomor versi.

**Example**  

```
[DynamoDBTable("ProductCatalog")]
  public class Book
  {
    [DynamoDBHashKey]   //Partition key
    public int Id { get; set; }
    [DynamoDBProperty]
    public string Title { get; set; }
    [DynamoDBProperty]
    public string ISBN { get; set; }
    [DynamoDBProperty("Authors")]
    public List<string> BookAuthors { get; set; }
    [DynamoDBVersion]
    public int? VersionNumber { get; set; }
  }
```

**catatan**  
Anda dapat menerapkan atribut `DynamoDBVersion` hanya untuk jenis primitif numerik yang dapat di-null-kan (seperti `int?`). 

Penguncian optimis memiliki dampak berikut terhadap operasi `DynamoDBContext`:
+ Untuk item baru, `DynamoDBContext` menetapkan nomor versi awal 0. Jika Anda mengambil item yang ada, memperbarui satu atau beberapa properti, dan mencoba untuk menyimpan perubahan, operasi simpan hanya akan berhasil jika nomor versi di sisi klien dan sisi server cocok. `DynamoDBContext` menambahkan nomor versi. Anda tidak perlu mengatur nomor versi.
+ Metode `Delete` menyediakan beban berlebih yang dapat mengambil nilai kunci primer atau objek sebagai parameter, seperti yang ditunjukkan dalam contoh kode C\$1 berikut.  
**Example**  

  ```
  DynamoDBContext context = new DynamoDBContext(client);
  ...
  // Load a book.
  Book book = context.Load<ProductCatalog>(111);
  // Do other operations.
  // Delete 1 - Pass in the book object.
  context.Delete<ProductCatalog>(book);
  
  // Delete 2 - Pass in the Id (primary key)
  context.Delete<ProductCatalog>(222);
  ```

  Jika Anda menyediakan objek sebagai parameter, penghapusan berhasil hanya jika versi objek cocok dengan versi item sisi server yang sesuai. Namun, jika Anda memberikan nilai kunci primer sebagai parameter, `DynamoDBContext` tidak mengenali nomor versi apa pun, dan menghapus item tanpa melakukan pemeriksaan versi. 

  Perhatikan bahwa implementasi internal penguncian optimis dalam kode model persistensi objek menggunakan tindakan API pembaruan bersyarat dan penghapusan bersyarat di DynamoDB.

## Menonaktifkan penguncian optimis
<a name="DotNetDynamoDBContext.DisablingOptimisticLocking"></a>

Untuk menonaktifkan penguncian optimis, gunakan properti konfigurasi `SkipVersionCheck`. Anda dapat mengatur properti ini saat membuat `DynamoDBContext`. Dalam kasus ini, penguncian optimis dinonaktifkan untuk permintaan apa pun yang Anda buat menggunakan konteks. Untuk informasi selengkapnya, lihat [Menentukan parameter opsional untuk Dynamo DBContext](DotNetDynamoDBContext.md#OptionalConfigParams). 

Alih-alih menetapkan properti pada tingkat konteks, Anda dapat menonaktifkan penguncian optimis untuk operasi tertentu, seperti yang ditunjukkan dalam contoh kode C\$1 berikut. Contoh ini menggunakan konteks untuk menghapus item buku. Metode `Delete` menetapkan properti `SkipVersionCheck` opsional ke true, menonaktifkan pemeriksaan penentuan versi.

**Example**  

```
DynamoDBContext context = new DynamoDBContext(client);
// Load a book.
Book book = context.Load<ProductCatalog>(111);
...
// Delete the book.
context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true });
```

# Memetakan data arbitrer dengan DynamoDB menggunakan model persistensi objek AWS SDK untuk .NET
<a name="DynamoDBContext.ArbitraryDataMapping"></a>

Selain jenis .NET yang didukung (lihat [Jenis data yang didukung](DotNetSDKHighLevel.md#DotNetDynamoDBContext.SupportedTypes)), Anda dapat menggunakan jenis di aplikasi Anda yang tidak memiliki pemetaan langsung ke jenis Amazon DynamoDB. Model persistensi objek mendukung jenis penyimpanan data arbitrer selama Anda memberikan konverter untuk mengonversi data dari jenis arbitrer untuk jenis DynamoDB dan sebaliknya. Kode konverter mengubah data saat menyimpan dan memuat objek.

Anda dapat membuat jenis apa pun di sisi klien. Namun, data yang disimpan di tabel adalah salah satu jenis DynamoDB, dan selama kueri dan pemindaian, perbandingan data apa pun yang dibuat didasarkan pada data yang disimpan di DynamoDB.

Contoh kode C\$1 berikut mendefinisikan kelas `Book` dengan properti `Id`, `Title`, `ISBN`, dan `Dimension`. Properti `Dimension` adalah bagian dari `DimensionType` yang mendeskripsikan properti `Height`, `Width`, dan `Thickness`. Contoh kode ini menyediakan metode konverter `ToEntry` dan `FromEntry` untuk mengonversi data antara jenis string `DimensionType` dan DynamoDB. Misalnya, saat menyimpan instans `Book`, konverter membuat sebuah string `Dimension` buku seperti “8.5x11x.05". Saat Anda mengambil buku, konverter akan mengonversi string tersebut menjadi instans `DimensionType`.

Contoh ini memetakan jenis `Book` ke tabel `ProductCatalog`. Ini menyimpan instans `Book` sampel, mengambilnya, memperbarui dimensinya, dan menyimpan `Book` yang terbaru lagi.



Untuk step-by-step instruksi untuk menguji contoh berikut, lihat[Contoh kode .NET](CodeSamples.DotNet.md).

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class HighLevelMappingArbitraryData
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                DynamoDBContext context = new DynamoDBContext(client);

                // 1. Create a book.
                DimensionType myBookDimensions = new DimensionType()
                {
                    Length = 8M,
                    Height = 11M,
                    Thickness = 0.5M
                };

                Book myBook = new Book
                {
                    Id = 501,
                    Title = "AWS SDK for .NET Object Persistence Model Handling Arbitrary Data",
                    ISBN = "999-9999999999",
                    BookAuthors = new List<string> { "Author 1", "Author 2" },
                    Dimensions = myBookDimensions
                };

                context.Save(myBook);

                // 2. Retrieve the book.
                Book bookRetrieved = context.Load<Book>(501);

                // 3. Update property (book dimensions).
                bookRetrieved.Dimensions.Height += 1;
                bookRetrieved.Dimensions.Length += 1;
                bookRetrieved.Dimensions.Thickness += 0.2M;
                // Update the book.
                context.Save(bookRetrieved);

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }
    }
    [DynamoDBTable("ProductCatalog")]
    public class Book
    {
        [DynamoDBHashKey] //Partition key
        public int Id
        {
            get; set;
        }
        [DynamoDBProperty]
        public string Title
        {
            get; set;
        }
        [DynamoDBProperty]
        public string ISBN
        {
            get; set;
        }
        // Multi-valued (set type) attribute.
        [DynamoDBProperty("Authors")]
        public List<string> BookAuthors
        {
            get; set;
        }
        // Arbitrary type, with a converter to map it to DynamoDB type.
        [DynamoDBProperty(typeof(DimensionTypeConverter))]
        public DimensionType Dimensions
        {
            get; set;
        }
    }

    public class DimensionType
    {
        public decimal Length
        {
            get; set;
        }
        public decimal Height
        {
            get; set;
        }
        public decimal Thickness
        {
            get; set;
        }
    }

    // Converts the complex type DimensionType to string and vice-versa.
    public class DimensionTypeConverter : IPropertyConverter
    {
        public DynamoDBEntry ToEntry(object value)
        {
            DimensionType bookDimensions = value as DimensionType;
            if (bookDimensions == null) throw new ArgumentOutOfRangeException();

            string data = string.Format("{1}{0}{2}{0}{3}", " x ",
                            bookDimensions.Length, bookDimensions.Height, bookDimensions.Thickness);

            DynamoDBEntry entry = new Primitive
            {
                Value = data
            };
            return entry;
        }

        public object FromEntry(DynamoDBEntry entry)
        {
            Primitive primitive = entry as Primitive;
            if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value))
                throw new ArgumentOutOfRangeException();

            string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
            if (data.Length != 3) throw new ArgumentOutOfRangeException();

            DimensionType complexData = new DimensionType
            {
                Length = Convert.ToDecimal(data[0]),
                Height = Convert.ToDecimal(data[1]),
                Thickness = Convert.ToDecimal(data[2])
            };
            return complexData;
        }
    }
}
```

# Menjalankan contoh kode dalam Panduan Developer ini
<a name="CodeSamples"></a>

 AWS SDKs Memberikan dukungan luas untuk Amazon DynamoDB dalam bahasa berikut:
+ [ Java](https://aws.amazon.com/sdk-for-java)
+ [JavaScript di browser](https://aws.amazon.com/sdk-for-browser)
+ [.NET](https://aws.amazon.com/sdk-for-net)
+ [Node.js](https://aws.amazon.com/sdk-for-node-js)
+ [PHP](https://aws.amazon.com/sdk-for-php)
+ [Python](https://aws.amazon.com/sdk-for-python)
+ [Ruby](https://aws.amazon.com/sdk-for-ruby)
+ [C\$1\$1](https://aws.amazon.com/sdk-for-cpp)
+ [Go](https://aws.amazon.com/sdk-for-go)
+ [Android](https://aws.amazon.com/mobile/sdk/)
+ [iOS](https://aws.amazon.com/mobile/sdk/)

Contoh kode dalam panduan developer ini menyediakan cakupan yang lebih mendalam tentang operasi DynamoDB, menggunakan bahasa pemrograman berikut:
+ [Contoh kode Java](CodeSamples.Java.md)
+ [Contoh kode .NET](CodeSamples.DotNet.md)

Sebelum Anda dapat memulai dengan latihan ini, Anda perlu membuat AWS akun, mendapatkan kunci akses dan kunci rahasia, dan mengatur AWS Command Line Interface (AWS CLI) di komputer Anda. Untuk informasi selengkapnya, lihat [Menyiapkan DynamoDB (layanan web)](SettingUp.DynamoWebService.md).

**catatan**  
Jika Anda menggunakan versi DynamoDB yang dapat diunduh, Anda perlu menggunakan untuk membuat tabel AWS CLI dan data sampel. Anda juga perlu menentukan `--endpoint-url` parameter dengan setiap AWS CLI perintah. Untuk informasi selengkapnya, lihat [Mengatur Titik Akhir Lokal](DynamoDBLocal.UsageNotes.md#DynamoDBLocal.Endpoint).

# Membuat tabel dan memuat data untuk contoh kode di DynamoDB
<a name="SampleData"></a>

Lihat di bawah untuk dasar-dasar membuat tabel di DynamoDB, memuat sampel set data, membuat kueri data, dan memperbarui data.
+ [Langkah 1: Buat tabel di DynamoDB](getting-started-step-1.md)
+ [Langkah 2: Menulis data ke tabel DynamoDB](getting-started-step-2.md)
+ [Langkah 3: Baca data dari tabel DynamoDB](getting-started-step-3.md)
+ [Langkah 4: Perbarui data dalam tabel DynamoDB](getting-started-step-4.md)

# Contoh kode Java
<a name="CodeSamples.Java"></a>

**Topics**
+ [Java: Mengatur AWS kredensil Anda](#CodeSamples.Java.Credentials)
+ [Java: Mengatur AWS Wilayah dan titik akhir](#CodeSamples.Java.RegionAndEndpoint)

Panduan Pengembang ini berisi cuplikan kode Java dan ready-to-run program. Anda dapat menemukan contoh kode ini di bagian berikut:
+ [Bekerja dengan item dan atribut di DynamoDB](WorkingWithItems.md)
+ [Bekerja dengan tabel dan data di DynamoDB](WorkingWithTables.md)
+ [Menanyakan tabel di DynamoDB](Query.md)
+ [Memindai tabel di DynamoDB](Scan.md)
+ [Meningkatkan akses data dengan indeks sekunder di DynamoDB](SecondaryIndexes.md)
+ [Java 1.x: Dinamo DBMapper](DynamoDBMapper.md)
+ [Tangkapan data perubahan DynamoDB Streams](Streams.md)

Anda dapat memulai dengan cepat menggunakan Eclipse dengan [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/). Selain IDE berfitur lengkap, Anda juga mendapatkan pembaruan otomatis, dan templat AWS SDK untuk Java yang telah dikonfigurasi sebelumnya untuk membangun AWS aplikasi.

**Untuk menjalankan contoh kode Java (menggunakan Eclipse)**

1. Unduh dan instal IDE [Eclipse](http://www.eclipse.org).

1. Unduh dan instal [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/).

1. Mulai Eclipse, dan pada menu **Eclipse**, pilih **File**, **Baru**, lalu **Lainnya**.

1. Di **Pilih wizard**, pilih **AWS**, pilih **Proyek Java AWS **, lalu pilih **Selanjutnya**.

1. Di **Create an AWS Java**, lakukan hal berikut:

   1. Dalam **Nama proyek**, masukkan nama untuk proyek Anda.

   1. Di **Pilih Akun**, pilih profil kredensial Anda dari daftar.

      Jika ini adalah pertama kalinya Anda menggunakan [AWS Toolkit for Eclipse](https://aws.amazon.com/eclipse/), pilih **Konfigurasi AWS Akun** untuk menyiapkan AWS kredensil Anda.

1. Pilih **Selesai** untuk membuat proyek.

1. Dari menu **Eclipse**, pilih **File**, **Baru**, kemudian **Kelas**.

1. Dalam **Kelas Java**, masukkan nama untuk kelas Anda di **Nama** (menggunakan nama yang sama sebagai contoh kode yang ingin Anda jalankan), lalu pilih **Selesai** untuk membuat kelas.

1. Salin contoh kode dari halaman dokumentasi ke editor Eclipse.

1. Untuk menjalankan kode, pilih **Jalankan** pada menu Eclipse.

SDK untuk Java menyediakan klien thread-safe untuk bekerja dengan DynamoDB. Sebagai praktik terbaik, aplikasi Anda harus membuat satu klien dan menggunakan kembali klien di antara thread.

Untuk informasi selengkapnya, lihat [AWS SDK untuk Java](https://aws.amazon.com/sdk-for-java).

**catatan**  
Contoh kode dalam panduan ini dimaksudkan untuk digunakan dengan versi terbaru dari AWS SDK untuk Java.  
Jika Anda menggunakan AWS Toolkit for Eclipse, Anda dapat mengonfigurasi pembaruan otomatis untuk SDK for Java. Untuk melakukan ini di Eclipse, buka **Preferensi** dan pilih **AWS Toolkit**, **AWS SDK untuk Java**, **Unduh baru SDKs ** secara otomatis.

## Java: Mengatur AWS kredensil Anda
<a name="CodeSamples.Java.Credentials"></a>

SDK for Java mengharuskan Anda AWS memberikan kredensi ke aplikasi Anda saat runtime. *Contoh kode dalam panduan ini mengasumsikan bahwa Anda menggunakan file AWS kredensial, seperti yang dijelaskan dalam [Mengatur AWS kredensil Anda](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/set-up-creds.html) di Panduan Pengembang.AWS SDK untuk Java *

Berikut ini adalah contoh file AWS kredensial bernama`~/.aws/credentials`, di mana karakter tilde (`~`) mewakili direktori home Anda.

```
[default]
aws_access_key_id = AWS access key ID goes here
aws_secret_access_key = Secret key goes here
```

## Java: Mengatur AWS Wilayah dan titik akhir
<a name="CodeSamples.Java.RegionAndEndpoint"></a>

Secara default, contoh kode mengakses DynamoDB di Wilayah AS Barat (Oregon). Anda dapat mengubah Wilayah dengan memodifikasi properti `AmazonDynamoDB`.

Contoh kode berikut menginstansiasi `AmazonDynamoDB` baru.

```
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import com.amazonaws.regions.Regions;
...
// This client will default to US West (Oregon)
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.build();
```

Anda dapat menggunakan metode `withRegion` untuk menjalankan kode Anda terhadap DynamoDB di Wilayah ketersediaan mana pun. Untuk daftar lengkap, lihat [wilayah dan titik akhir AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) di *Referensi Umum Amazon Web Services*.

Jika Anda ingin menjalankan contoh kode menggunakan DynamoDB secara lokal pada komputer Anda, atur titik akhir sebagai berikut.

### AWS SDK V1
<a name="CodeSamples.Java.RegionAndEndpoint.V1"></a>

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
```

### AWS SDK V2
<a name="CodeSamples.Java.RegionAndEndpoint.V2"></a>

```
DynamoDbClient client = DynamoDbClient.builder()
    .endpointOverride(URI.create("http://localhost:8000"))
    // The region is meaningless for local DynamoDb but required for client builder validation
    .region(Region.US_EAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(
    AwsBasicCredentials.create("dummy-key", "dummy-secret")))
    .build();
```

# Contoh kode .NET
<a name="CodeSamples.DotNet"></a>

**Topics**
+ [.NET: Mengatur AWS kredensil Anda](#CodeSamples.DotNet.Credentials)
+ [.NET: Mengatur AWS Wilayah dan titik akhir](#CodeSamples.DotNet.RegionAndEndpoint)

Panduan ini berisi potongan kode .NET dan ready-to-run program. Anda dapat menemukan contoh kode ini di bagian berikut:
+ [Bekerja dengan item dan atribut di DynamoDB](WorkingWithItems.md)
+ [Bekerja dengan tabel dan data di DynamoDB](WorkingWithTables.md)
+ [Menanyakan tabel di DynamoDB](Query.md)
+ [Memindai tabel di DynamoDB](Scan.md)
+ [Meningkatkan akses data dengan indeks sekunder di DynamoDB](SecondaryIndexes.md)
+ [Bekerja dengan model dokumen.NET di DynamoDB](DotNetSDKMidLevel.md)
+ [Bekerja dengan model persistensi objek.NET dan DynamoDB](DotNetSDKHighLevel.md)
+ [Tangkapan data perubahan DynamoDB Streams](Streams.md)

Anda dapat memulai dengan cepat dengan menggunakan Toolkit for Visual Studio. AWS SDK untuk .NET 

**Untuk menjalankan contoh kode .NET (menggunakan Visual Studio)**

1. Unduh dan instal [Microsoft Visual Studio](https://www.visualstudio.com).

1. (Opsional) Unduh dan instal [Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/).

1. Siapkan AWS kredensil Anda. Konfigurasikan profil kredensial di file AWS kredensial bersama Anda (). `~/.aws/credentials` Untuk informasi selengkapnya, lihat [Mengonfigurasi kredensial AWS](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) di *Panduan Developer AWS SDK untuk .NET *.

1. Mulai Visual Studio. Pilih **File**, **Baru**, **Proyek**.

1. Cari **Aplikasi Konsol**, pilih templat C\$1 yang menargetkan .NET, lalu pilih **Berikutnya**. Konfigurasikan nama dan lokasi proyek Anda, lalu pilih **Buat**.

1. Tambahkan paket AWS SDK for NuGet DynamoDB ke project Anda:

   1. Di Solution Explorer, buka menu konteks (klik kanan) untuk proyek Anda, lalu pilih **Kelola NuGet Paket**.

   1. Di NuGet Package Manager, pilih **Browse**.

   1. Di kotak pencarian, masukkan **AWSSDK.DynamoDBv2**, lalu tunggu hingga pencarian selesai.

   1. **Pilih **AWSSDK.Dynamo DBv2**, dan kemudian pilih Install.**

1. Dalam proyek Visual Studio Anda, buka`Program.cs`. Ganti konten dengan contoh kode dari halaman dokumentasi yang ingin Anda jalankan.

1. Untuk menjalankan kode, pilih **Mulai** di toolbar Visual Studio.

 SDK untuk .NET Ini menyediakan klien thread-safe untuk bekerja dengan DynamoDB. Sebagai praktik terbaik, aplikasi Anda harus membuat satu klien dan menggunakan kembali klien di antara thread.

Untuk informasi selengkapnya, lihat [AWS SDK untuk .NET](https://aws.amazon.com/sdk-for-net).

**catatan**  
Contoh kode dalam panduan ini dimaksudkan untuk digunakan dengan versi terbaru dari AWS SDK untuk .NET.

## .NET: Mengatur AWS kredensil Anda
<a name="CodeSamples.DotNet.Credentials"></a>

Ini SDK untuk .NET mengharuskan Anda memberikan AWS kredensil ke aplikasi Anda saat runtime. *Contoh kode dalam panduan ini mengasumsikan bahwa Anda menggunakan SDK Store untuk mengelola file AWS kredensional Anda, seperti yang dijelaskan dalam [Menggunakan penyimpanan SDK di Panduan Pengembang](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#sdk-store).AWS SDK untuk .NET *

Toolkit for Visual Studio mendukung beberapa set kredensial dari sejumlah akun. Setiap set disebut sebagai *profil*. Visual Studio menambahkan entri ke `App.config` file proyek sehingga aplikasi Anda dapat menemukan AWS kredensialnya saat runtime.

Contoh berikut menunjukkan file `App.config` default yang dihasilkan ketika Anda membuat proyek baru menggunakan Toolkit for Visual Studio.

```
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
    <add key="AWSProfileName" value="default"/>
    <add key="AWSRegion" value="us-west-2" />
 </appSettings>
</configuration>
```

Saat runtime, program menggunakan `default` set AWS kredensil, seperti yang ditentukan oleh entri. `AWSProfileName` AWS Kredensialnya sendiri disimpan di SDK Store dalam bentuk terenkripsi. Toolkit for Visual Studio menyediakan antarmuka pengguna grafis untuk mengelola kredensial Anda, semua dari dalam Visual Studio. Untuk informasi selengkapnya, lihat [Menentukan kredensial](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv_setup.html#creds) dalam *Panduan Pengguna AWS Toolkit for Visual Studio *.

**catatan**  
Secara default, contoh kode mengakses DynamoDB di Wilayah AS Barat (Oregon). Anda dapat mengubah Wilayah dengan memodifikasi entri `AWSRegion` dalam file App.config. Anda dapat mengatur `AWSRegion` ke Wilayah mana pun tempat DynamoDB tersedia. Untuk daftar lengkap, lihat [wilayah dan titik akhir AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) di *Referensi Umum Amazon Web Services*.

## .NET: Mengatur AWS Wilayah dan titik akhir
<a name="CodeSamples.DotNet.RegionAndEndpoint"></a>

Secara default, contoh kode mengakses DynamoDB di Wilayah AS Barat (Oregon). Anda dapat mengubah Wilayah dengan memodifikasi entri `AWSRegion` dalam file `App.config`. Atau, Anda dapat mengubah Wilayah dengan memodifikasi properti `AmazonDynamoDBClient`.

Contoh kode berikut menginstansiasi `AmazonDynamoDBClient` baru. Klien dimodifikasi sehingga kode berjalan terhadap DynamoDB di Wilayah yang berbeda.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// This client will access the US East 1 region.
clientConfig.RegionEndpoint = RegionEndpoint.USEast1;
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

Untuk daftar lengkap Wilayah, lihat [wilayah dan titik akhir AWS](https://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region) di *Referensi Umum Amazon Web Services*.

Jika Anda ingin menjalankan contoh kode menggunakan DynamoDB secara lokal pada komputer Anda, atur titik akhir sebagai berikut.

```
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
// Set the endpoint URL
clientConfig.ServiceURL = "http://localhost:8000";
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
```

# API tingkat rendah DynamoDB
<a name="Programming.LowLevelAPI"></a>

*API tingkat rendah* Amazon DynamoDB adalah antarmuka tingkat protokol untuk DynamoDB. Pada tingkat ini, setiap permintaan HTTP(S) harus diformat dengan benar dan membawa tanda tangan digital yang valid.

 AWS SDKs Membangun permintaan API DynamoDB tingkat rendah atas nama Anda dan memproses tanggapan dari DynamoDB. Ini memungkinkan Anda berfokus pada logika aplikasi Anda, bukan detail tingkat rendah. Namun, Anda masih bisa mendapatkan keuntungan dari pengetahuan dasar tentang bagaimana DynamoDB API tingkat rendah bekerja.

Untuk informasi selengkapnya tentang DynamoDB API, lihat [Referensi Amazon DynamoDB API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**catatan**  
DynamoDB Streams memiliki API tingkat rendah sendiri, yang terpisah dari DynamoDB dan sepenuhnya didukung oleh. AWS SDKs  
Untuk informasi selengkapnya, lihat [Tangkapan data perubahan DynamoDB Streams](Streams.md). Untuk DynamoDB Streams API tingkat rendah, lihat [Referensi Amazon DynamoDB Streams API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html).

DynamoDB API tingkat rendah JavaScript menggunakan Object Notation (JSON) sebagai format protokol kawat. JSON menyajikan data dalam hierarki sehingga nilai data dan struktur data disampaikan secara bersamaan. Pasangan nama-nilai ditentukan dalam format `name:value`. Hierarki data ditentukan oleh tanda kurung berisi pasangan nama-nilai.

DynamoDB menggunakan JSON hanya sebagai protokol transportasi, bukan sebagai format penyimpanan. AWS SDKs Penggunaan JSON untuk mengirim data ke DynamoDB, dan DynamoDB merespons dengan JSON. DynamoDB tidak menyimpan data terus-menerus dalam format JSON.

**catatan**  
Untuk informasi selengkapnya tentang JSON, lihat [Memperkenalkan JSON](http://json.org) pada situs web `JSON.org`.

**Topics**
+ [Format permintaan](#Programming.LowLevelAPI.RequestFormat)
+ [Format respons](#Programming.LowLevelAPI.ResponseFormat)
+ [Deskriptor jenis data](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [Data numerik](#Programming.LowLevelAPI.Numbers)
+ [Data biner](#Programming.LowLevelAPI.Binary)

![\[DynamoDB API tingkat rendah dan AWS SDKs cara menangani permintaan dan respons tingkat protokol.\]](http://docs.aws.amazon.com/id_id/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## Format permintaan
<a name="Programming.LowLevelAPI.RequestFormat"></a>

API tingkat rendah DynamoDB menerima permintaan `POST` HTTP(S) sebagai masukan. AWS SDKs Bangun permintaan ini untuk Anda.

Misalkan Anda memiliki tabel bernama `Pets`, dengan skema kunci yang terdiri dari `AnimalType` (kunci partisi) dan `Name` (kunci urutan). Kedua atribut ini berjenis `string`. Untuk mengambil item dari`Pets`, AWS SDK membuat permintaan berikut.

```
POST / HTTP/1.1
Host: dynamodb.<region>.<domain>;
Accept-Encoding: identity
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.0
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature>
X-Amz-Date: <Date> 
X-Amz-Target: DynamoDB_20120810.GetItem

{
    "TableName": "Pets",
    "Key": {
        "AnimalType": {"S": "Dog"},
        "Name": {"S": "Fido"}
    }
}
```

Perhatikan hal berikut tentang permintaan ini:
+ Header `Authorization` berisi informasi yang diperlukan untuk DynamoDB guna mengautentikasi permintaan. Untuk informasi selengkapnya, lihat [Menandatangani permintaan AWS API](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) dan [proses penandatanganan Versi Tanda Tangan 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) di bagian *Referensi Umum Amazon Web Services*.
+ Header `X-Amz-Target` berisi nama operasi DynamoDB: `GetItem`. (Ini juga disertai dengan versi API tingkat rendah, dalam hal ini `20120810`.)
+ Muatan (isi) permintaan mengandungi parameter untuk operasi, dalam format JSON. Untuk operasi `GetItem`, parameternya adalah `TableName` dan `Key`.

## Format respons
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

Setelah menerima permintaan, DynamoDB memprosesnya dan mengembalikan respons. Untuk permintaan yang ditunjukkan sebelumnya, muatan respons HTTP(S) berisi hasil dari operasi, seperti yang ditunjukkan pada contoh berikut.

```
HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{
    "Item": {
        "Age": {"N": "8"},
        "Colors": {
            "L": [
                {"S": "White"},
                {"S": "Brown"},
                {"S": "Black"}
            ]
        },
        "Name": {"S": "Fido"},
        "Vaccinations": {
            "M": {
                "Rabies": {
                    "L": [
                        {"S": "2009-03-17"},
                        {"S": "2011-09-21"},
                        {"S": "2014-07-08"}
                    ]
                },
                "Distemper": {"S": "2015-10-13"}
            }
        },
        "Breed": {"S": "Beagle"},
        "AnimalType": {"S": "Dog"}
    }
}
```

Pada titik ini, AWS SDK mengembalikan data respons ke aplikasi Anda untuk diproses lebih lanjut.

**catatan**  
Jika DynamoDB tidak dapat memproses permintaan, DynamoDB akan mengembalikan kode kesalahan HTTP dan pesan. AWS SDK menyebarkannya untuk aplikasi Anda dalam bentuk pengecualian. Untuk informasi selengkapnya, lihat [Penanganan kesalahan dengan DynamoDB](Programming.Errors.md).

## Deskriptor jenis data
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

Protokol DynamoDB API tingkat rendah membutuhkan setiap atribut untuk disertai dengan deskriptor jenis data. *Deskriptor jenis data* adalah token yang memberi tahu DynamoDB cara menafsirkan setiap atribut.

Contoh di [Format permintaan](#Programming.LowLevelAPI.RequestFormat) dan [Format respons](#Programming.LowLevelAPI.ResponseFormat) menunjukkan contoh bagaimana deskriptor jenis data digunakan. Permintaan `GetItem` menentukan `S` untuk atribut skema kunci `Pets` (`AnimalType` dan `Name`), yang berjenis `string`. Respons `GetItem` berisi item *Pets* dengan atribut jenis `string` (`S`), `number` (`N`), `map` (`M`), dan `list` (`L`).

Berikut ini adalah daftar lengkap deskriptor jenis data DynamoDB:
+ **`S`** – String
+ **`N`** – Nomor
+ **`B`** – Biner
+ **`BOOL`** – Boolean
+ **`NULL`** – Null
+ **`M`** – Peta
+ **`L`** – Daftar
+ **`SS`** – Set String
+ **`NS`** – Set Nomor
+ **`BS`** – Set Biner

Tabel berikut menunjukkan format JSON yang benar untuk setiap deskriptor tipe data. Perhatikan bahwa angka direpresentasikan sebagai string untuk mempertahankan presisi, sedangkan boolean dan null menggunakan tipe JSON asli mereka.


| Deskriptor | Format JSON | Catatan | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | Nilai adalah string JSON. | 
| N | \$1"N": "123.45"\$1 | Nilai adalah string, bukan nomor JSON. Ini mempertahankan presisi di seluruh bahasa. | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | Nilai adalah string yang dikodekan base64. | 
| BOOL | \$1"BOOL": true\$1 | Nilai adalah boolean JSON (trueataufalse), bukan string. | 
| NULL | \$1"NULL": true\$1 | Nilai adalah boolean JSON true untuk menunjukkan nol. | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | Nilai adalah objek JSON dari pasangan nama-nilai atribut. | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | Nilai adalah array JSON dari nilai atribut. | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | Nilai adalah array JSON string. | 
| NS | \$1"NS": ["1", "2.5"]\$1 | Nilai adalah array JSON dari string nomor. | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | Nilai adalah array JSON dari string yang dikodekan base64. | 

**catatan**  
 Untuk deskripsi mendetail tentang jenis data DynamoDB, lihat [Jenis Data](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes).

## Data numerik
<a name="Programming.LowLevelAPI.Numbers"></a>

Bahasa pemrograman yang berbeda menawarkan tingkat dukungan yang berbeda untuk JSON. Dalam beberapa kasus, Anda mungkin memutuskan untuk menggunakan pustaka pihak ketiga untuk memvalidasi dan menguraikan dokumen JSON.

Beberapa pustaka pihak ketiga membangun jenis angka JSON, menyediakan jenisnya sendiri seperti `int`, `long`, atau `double`. Namun, jenis data angka asli di DynamoDB tidak memetakan persis untuk jenis data lainnya, sehingga perbedaan jenis ini dapat menyebabkan konflik. Selain itu, banyak pustaka JSON tidak menangani nilai numerik presisi tetap, dan secara otomatis menyimpulkan jenis data ganda untuk urutan digit yang berisi titik desimal.

Untuk mengatasi masalah ini, DynamoDB menyediakan jenis numerik tunggal tanpa kehilangan data. Untuk menghindari konversi implisit yang tidak diinginkan ke nilai ganda, DynamoDB menggunakan string untuk transfer data nilai numerik. Pendekatan ini memberikan fleksibilitas untuk memperbarui nilai atribut sekaligus mempertahankan semantik pengurutan yang tepat, seperti menempatkan nilai "01", "2", dan "03" dalam urutan yang tepat.

Jika presisi angka penting untuk aplikasi, Anda harus mengonversi nilai numerik untuk string tersebut sebelum meneruskannya ke DynamoDB.

## Data biner
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB mendukung atribut binari. Namun, JSON tidak secara native mendukung data biner pengodean. Untuk mengirim data biner dalam permintaan, Anda perlu untuk mengodekannya dalam format base64. Setelah menerima permintaan, DynamoDB mengodekan data base64 kembali ke biner. 

Skema pengodean base64 yang digunakan oleh DynamoDB dijelaskan di [RFC 4648](http://tools.ietf.org/html/rfc4648) di situs web Internet Engineering Task Force (IETF).

# Pemrograman Amazon DynamoDB dengan Python dan Boto3
<a name="programming-with-python"></a>

Panduan ini memberikan orientasi kepada programmer yang ingin menggunakan Amazon DynamoDB dengan Python. Pelajari tentang berbagai lapisan abstraksi, manajemen konfigurasi, penanganan kesalahan, pengendalian kebijakan coba lagi, pengelolaan keep-alive, dan banyak lagi.

**Topics**
+ [Tentang Boto](#programming-with-python-about)
+ [Menggunakan dokumentasi Boto](#programming-with-python-documentation)
+ [Memahami lapisan abstraksi klien dan sumber daya](#programming-with-python-client-resource)
+ [Menggunakan sumber daya tabel batch\$1writer](#programming-with-python-batch-writer)
+ [Contoh kode tambahan yang mengeksplorasi lapisan klien dan sumber daya](#programming-with-python-additional-code)
+ [Memahami bagaimana objek Klien dan Sumber Daya berinteraksi dengan sesi dan utas](#programming-with-python-sessions-thread-safety)
+ [Menyesuaikan objek Config](#programming-with-python-config)
+ [Penanganan kesalahan](#programming-with-python-error-handling)
+ [Pencatatan log](#programming-with-python-logging)
+ [Kait acara](#programming-with-python-event-hooks)
+ [Pagination dan Paginator](#programming-with-python-pagination)
+ [Pelayan](#programming-with-python-waiters)

## Tentang Boto
<a name="programming-with-python-about"></a>

**Anda dapat mengakses DynamoDB dari Python dengan menggunakan SDK AWS resmi untuk Python, yang biasa disebut sebagai Boto3.** Nama Boto (diucapkan boh-toh) berasal dari lumba-lumba air tawar asli Sungai Amazon. Perpustakaan Boto3 adalah versi utama ketiga perpustakaan, pertama kali dirilis pada tahun 2015. Perpustakaan Boto3 cukup besar, karena mendukung semua AWS layanan, bukan hanya DynamoDB. Orientasi ini hanya menargetkan bagian Boto3 yang relevan dengan DynamoDB.

Boto dikelola dan diterbitkan oleh AWS sebagai proyek sumber terbuka yang dihosting di. GitHub [Ini dibagi menjadi dua paket: [Botocore dan Boto3](https://github.com/boto/botocore).](https://github.com/boto/boto3)
+ **Botocore menyediakan fungsionalitas** tingkat rendah. Di Botocore Anda akan menemukan kelas klien, sesi, kredensyal, konfigurasi, dan pengecualian. 
+ **Boto3** dibangun di atas Botocore. Ini menawarkan antarmuka Pythonic tingkat yang lebih tinggi dan lebih banyak. Secara khusus, ini mengekspos tabel DynamoDB sebagai Sumber Daya dan menawarkan antarmuka yang lebih sederhana dan lebih elegan dibandingkan dengan antarmuka klien berorientasi layanan tingkat rendah.

Karena proyek ini di-host GitHub, Anda dapat melihat kode sumber, melacak masalah terbuka, atau mengirimkan masalah Anda sendiri.

## Menggunakan dokumentasi Boto
<a name="programming-with-python-documentation"></a>

Mulailah dengan dokumentasi Boto dengan sumber daya berikut:
+ Mulailah dengan [bagian Quickstart](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) yang menyediakan titik awal yang solid untuk instalasi paket. Pergi ke sana untuk petunjuk tentang menginstal Boto3 jika belum (Boto3 sering tersedia secara otomatis dalam AWS layanan seperti). AWS Lambda
+ Setelah itu, fokuslah pada panduan [DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html) dokumentasi. Ini menunjukkan cara melakukan aktivitas DynamoDB dasar: membuat dan menghapus tabel, memanipulasi item, menjalankan operasi batch, menjalankan kueri, dan melakukan pemindaian. Contohnya menggunakan antarmuka **sumber daya**. Ketika Anda melihat `boto3.resource('dynamodb')` itu menunjukkan Anda menggunakan antarmuka **sumber daya** tingkat yang lebih tinggi.
+ Setelah panduan, Anda dapat meninjau referensi [DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html). Halaman arahan ini menyediakan daftar lengkap kelas dan metode yang tersedia untuk Anda. Di bagian atas, Anda akan melihat `DynamoDB.Client` kelas. Ini memberikan akses tingkat rendah ke semua operasi bidang kontrol dan bidang data. Di bagian bawah, lihat `DynamoDB.ServiceResource` kelasnya. Ini adalah antarmuka Pythonic tingkat yang lebih tinggi. Dengan itu Anda dapat membuat tabel, melakukan operasi batch di seluruh tabel, atau mendapatkan `DynamoDB.ServiceResource.Table` instance untuk tindakan khusus tabel.

## Memahami lapisan abstraksi klien dan sumber daya
<a name="programming-with-python-client-resource"></a>

Dua antarmuka yang akan Anda gunakan adalah antarmuka **klien** dan antarmuka **sumber daya**. 
+ Antarmuka **klien** tingkat rendah menyediakan pemetaan 1-ke-1 ke API layanan yang mendasarinya. Setiap API yang ditawarkan oleh DynamoDB tersedia melalui klien. Ini berarti antarmuka klien dapat menyediakan fungsionalitas yang lengkap, tetapi seringkali lebih bertele-tele dan kompleks untuk digunakan.
+ Antarmuka **sumber daya** tingkat yang lebih tinggi tidak menyediakan pemetaan 1-ke-1 dari API layanan yang mendasarinya. Namun, ini menyediakan metode yang membuatnya lebih nyaman bagi Anda untuk mengakses layanan seperti`batch_writer`.

Berikut adalah contoh menyisipkan item menggunakan antarmuka klien. Perhatikan bagaimana semua nilai dilewatkan sebagai peta dengan kunci yang menunjukkan tipenya ('S' untuk string, 'N' untuk nomor) dan nilainya sebagai string. Ini dikenal sebagai format DynamoDB JSON.

```
import boto3

dynamodb = boto3.client('dynamodb')

dynamodb.put_item(
    TableName='YourTableName',
    Item={
        'pk': {'S': 'id#1'},
        'sk': {'S': 'cart#123'},
        'name': {'S': 'SomeName'},
        'inventory': {'N': '500'},
        # ... more attributes ...
    }
)
```

Berikut adalah `PutItem` operasi yang sama menggunakan antarmuka sumber daya. Pengetikan data tersirat:

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

table.put_item(
    Item={
        'pk': 'id#1',
        'sk': 'cart#123',
        'name': 'SomeName',
        'inventory': 500,
        # ... more attributes ...
    }
)
```

Jika diperlukan, Anda dapat mengonversi antara JSON biasa dan DynamoDB JSON menggunakan `TypeSerializer` kelas dan yang disediakan dengan boto3: `TypeDeserializer`

```
def dynamo_to_python(dynamo_object: dict) -> dict:
    deserializer = TypeDeserializer()
    return {
        k: deserializer.deserialize(v) 
        for k, v in dynamo_object.items()
    }  
  
def python_to_dynamo(python_object: dict) -> dict:
    serializer = TypeSerializer()
    return {
        k: serializer.serialize(v)
        for k, v in python_object.items()
    }
```

Berikut adalah cara melakukan query menggunakan antarmuka klien. Ini mengekspresikan query sebagai konstruksi JSON. Ini menggunakan `KeyConditionExpression` string yang membutuhkan substitusi variabel untuk menangani konflik kata kunci potensial:

```
import boto3

client = boto3.client('dynamodb')

# Construct the query
response = client.query(
    TableName='YourTableName',
    KeyConditionExpression='pk = :pk_val AND begins_with(sk, :sk_val)',
    FilterExpression='#name = :name_val',
    ExpressionAttributeValues={
        ':pk_val': {'S': 'id#1'},
        ':sk_val': {'S': 'cart#'},
        ':name_val': {'S': 'SomeName'},
    },
    ExpressionAttributeNames={
        '#name': 'name',
    }
)
```

Operasi kueri yang sama menggunakan antarmuka sumber daya dapat dipersingkat dan disederhanakan:

```
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

response = table.query(
    KeyConditionExpression=Key('pk').eq('id#1') & Key('sk').begins_with('cart#'),
    FilterExpression=Attr('name').eq('SomeName')
)
```

Sebagai contoh terakhir, bayangkan Anda ingin mendapatkan perkiraan ukuran tabel (yang merupakan metadata yang disimpan di atas meja yang diperbarui setiap 6 jam). Dengan antarmuka klien, Anda melakukan `describe_table()` operasi dan menarik jawaban dari struktur JSON yang dikembalikan:

```
import boto3

dynamodb = boto3.client('dynamodb')

response = dynamodb.describe_table(TableName='YourTableName')
size = response['Table']['TableSizeBytes']
```

Dengan antarmuka sumber daya, tabel melakukan operasi deskripsi secara implisit dan menyajikan data secara langsung sebagai atribut:

```
import boto3

dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')
size = table.table_size_bytes
```

**catatan**  
Saat mempertimbangkan apakah akan mengembangkan menggunakan antarmuka klien atau sumber daya, ketahuilah bahwa fitur baru tidak akan ditambahkan ke antarmuka sumber daya per [dokumentasi sumber daya](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html): “Tim SDK AWS Python tidak bermaksud menambahkan fitur baru ke antarmuka sumber daya di boto3. Antarmuka yang ada akan terus beroperasi selama siklus hidup boto3. Pelanggan dapat menemukan akses ke fitur layanan yang lebih baru melalui antarmuka klien.

## Menggunakan sumber daya tabel batch\$1writer
<a name="programming-with-python-batch-writer"></a>

Satu kenyamanan yang hanya tersedia dengan sumber daya tabel tingkat yang lebih tinggi adalah. `batch_writer` DynamoDB mendukung operasi batch write yang memungkinkan hingga 25 operasi put atau delete dalam satu permintaan jaringan. Batching seperti ini meningkatkan efisiensi dengan meminimalkan perjalanan pulang-pergi jaringan.

Dengan pustaka klien tingkat rendah, Anda menggunakan `client.batch_write_item()` operasi untuk menjalankan batch. Anda harus membagi pekerjaan Anda secara manual menjadi 25 batch. Setelah setiap operasi, Anda juga harus meminta untuk menerima daftar item yang belum diproses (beberapa operasi penulisan mungkin berhasil sementara yang lain bisa gagal). Anda kemudian harus meneruskan item yang belum diproses itu lagi ke `batch_write_item()` operasi selanjutnya. Ada sejumlah besar kode boilerplate.

Metode [Table.batch\$1Writer](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/batch_writer.html) menciptakan manajer konteks untuk menulis objek dalam batch. Ini menyajikan antarmuka di mana tampaknya seolah-olah Anda sedang menulis item satu per satu, tetapi secara internal itu buffering dan mengirim item dalam batch. Ini juga menangani percobaan ulang item yang belum diproses secara implisit.

```
dynamodb = boto3.resource('dynamodb')

table = dynamodb.Table('YourTableName')

movies = # long list of movies in {'pk': 'val', 'sk': 'val', etc} format
with table.batch_writer() as writer:
    for movie in movies:
        writer.put_item(Item=movie)
```

## Contoh kode tambahan yang mengeksplorasi lapisan klien dan sumber daya
<a name="programming-with-python-additional-code"></a>

Anda juga dapat merujuk ke repositori contoh kode berikut yang mengeksplorasi penggunaan berbagai fungsi, menggunakan klien dan sumber daya:
+ [Contoh kode AWS aksi tunggal resmi.](https://docs.aws.amazon.com/code-library/latest/ug/python_3_dynamodb_code_examples.html) 
+ [Contoh kode AWS berorientasi skenario resmi.](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python)
+ [Contoh kode aksi tunggal yang dikelola komunitas.](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/python)

## Memahami bagaimana objek Klien dan Sumber Daya berinteraksi dengan sesi dan utas
<a name="programming-with-python-sessions-thread-safety"></a>

Objek Resource tidak aman untuk utas dan tidak boleh dibagikan di seluruh utas atau proses. Lihat [panduan tentang Sumber Daya](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html#multithreading-or-multiprocessing-with-resources) untuk lebih jelasnya.

Objek Klien, sebaliknya, umumnya aman untuk utas, kecuali untuk fitur lanjutan tertentu. Lihat [panduan tentang Klien](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#multithreading-or-multiprocessing-with-clients) untuk lebih jelasnya. 

Objek Session tidak aman untuk utas. Jadi, setiap kali Anda membuat Klien atau Sumber Daya di lingkungan multi-utas, Anda harus membuat Sesi baru terlebih dahulu dan kemudian membuat Klien atau Sumber Daya dari Sesi. Lihat [panduan tentang Sesi](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/session.html#multithreading-or-multiprocessing-with-sessions) untuk lebih jelasnya. 

Saat Anda memanggil`boto3.resource()`, Anda secara implisit menggunakan Sesi default. Ini nyaman untuk menulis kode single-threaded. Saat menulis kode multi-utas, Anda harus terlebih dahulu membuat Sesi baru untuk setiap utas dan kemudian mengambil sumber daya dari Sesi itu:

```
# Explicitly create a new Session for this thread 
session = boto3.Session()
dynamodb = session.resource('dynamodb')
```

## Menyesuaikan objek Config
<a name="programming-with-python-config"></a>

Saat membuat objek Klien atau Sumber Daya, Anda dapat meneruskan parameter bernama opsional untuk menyesuaikan perilaku. Parameter bernama `config` membuka berbagai fungsi. Ini adalah instance dari `botocore.client.Config` dan [dokumentasi referensi untuk Config](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html) menunjukkan semua yang diekspos untuk Anda kendalikan. [Panduan untuk Konfigurasi](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) memberikan gambaran yang baik.

**catatan**  
Anda dapat memodifikasi banyak pengaturan perilaku ini di tingkat Sesi, dalam file AWS konfigurasi, atau sebagai variabel lingkungan.

**Config untuk batas waktu**

Salah satu penggunaan konfigurasi khusus adalah untuk menyesuaikan perilaku jaringan:
+ **connect\$1timeout (float atau int)** - Waktu dalam hitungan detik hingga pengecualian batas waktu dilemparkan ketika mencoba membuat koneksi. Bawaannya adalah 60 detik.
+ **read\$1timeout (float atau int)** - Waktu dalam hitungan detik hingga pengecualian batas waktu dilemparkan ketika mencoba membaca dari koneksi. Bawaannya adalah 60 detik.

Batas waktu 60 detik berlebihan untuk DynamoDB. Ini berarti kesalahan jaringan sementara akan menyebabkan penundaan satu menit untuk klien sebelum dapat mencoba lagi. Kode berikut mempersingkat batas waktu menjadi satu detik:

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

Untuk diskusi selengkapnya tentang batas waktu, lihat [Menyetel setelan permintaan HTTP SDK AWS Java untuk aplikasi DynamoDB yang sadar latensi](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/). Perhatikan bahwa Java SDK memiliki konfigurasi batas waktu lebih banyak daripada Python.

**Config untuk keep-alive**

**Jika Anda menggunakan botocore 1.27.84 atau yang lebih baru, Anda juga dapat mengontrol TCP Keep-Alive:**
+ **tcp\$1keepalive** (bool) - Mengaktifkan opsi soket TCP Keep-Alive yang digunakan saat membuat koneksi baru jika disetel ke (default ke). `True` `False` Ini hanya tersedia mulai dengan botocore 1.27.84.

Mengatur TCP Keep-Alive untuk `True` dapat mengurangi latensi rata-rata. Berikut contoh kode yang secara kondisional menetapkan TCP Keep-Alive ke true ketika Anda memiliki versi botocore yang tepat:

```
import botocore
import boto3
from botocore.config import Config
from distutils.version import LooseVersion

required_version = "1.27.84"
current_version = botocore.__version__

my_config = Config(
   connect_timeout = 0.5,
   read_timeout = 0.5
)
if LooseVersion(current_version) > LooseVersion(required_version):
    my_config = my_config.merge(Config(tcp_keepalive = True))

dynamodb = boto3.resource('dynamodb', config=my_config)
```

**catatan**  
TCP Keep-Alive berbeda dari HTTP Keep-Alive. Dengan TCP Keep-Alive, paket-paket kecil dikirim oleh sistem operasi yang mendasarinya melalui koneksi soket untuk menjaga koneksi tetap hidup dan segera mendeteksi tetesan apa pun. Dengan HTTP Keep-Alive, koneksi web yang dibangun di atas soket yang mendasarinya akan digunakan kembali. HTTP Keep-Alive selalu diaktifkan dengan boto3.

Ada batasan berapa lama koneksi idle dapat tetap hidup. Pertimbangkan untuk mengirim permintaan berkala (katakanlah setiap menit) jika Anda memiliki koneksi idle tetapi ingin permintaan berikutnya menggunakan koneksi yang sudah dibuat.

**Config untuk percobaan ulang**

Konfigurasi juga menerima kamus yang disebut **percobaan ulang di mana Anda dapat menentukan perilaku coba lagi** yang Anda inginkan. Percobaan ulang terjadi dalam SDK ketika SDK menerima kesalahan dan kesalahan adalah tipe sementara. Jika kesalahan dicoba ulang secara internal (dan percobaan ulang akhirnya menghasilkan respons yang berhasil), tidak ada kesalahan yang terlihat dari perspektif kode panggilan, hanya latensi yang sedikit meningkat. Berikut adalah nilai yang dapat Anda tentukan:
+ **max\$1attempts** — Bilangan bulat yang mewakili jumlah maksimum percobaan ulang yang akan dilakukan pada satu permintaan. Misalnya, menyetel nilai ini ke 2 akan mengakibatkan permintaan dicoba ulang paling banyak dua kali setelah permintaan awal. Menyetel nilai ini ke 0 akan menghasilkan tidak ada percobaan ulang yang pernah dicoba setelah permintaan awal. 
+ **total\$1max\$1attempts** — Bilangan bulat yang mewakili jumlah maksimum upaya total yang akan dilakukan pada satu permintaan. Ini termasuk permintaan awal, jadi nilai 1 menunjukkan bahwa tidak ada permintaan yang akan dicoba ulang. Jika `total_max_attempts` dan `max_attempts` keduanya disediakan, `total_max_attempts` diutamakan. `total_max_attempts`lebih disukai daripada `max_attempts` karena memetakan ke variabel `AWS_MAX_ATTEMPTS` lingkungan dan nilai file `max_attempts` konfigurasi.
+ **mode** — String yang mewakili jenis mode coba lagi yang harus digunakan botocore. Nilai yang valid adalah:
  + **legacy** — Mode default. Menunggu 50 ms percobaan ulang pertama, kemudian menggunakan backoff eksponensial dengan faktor dasar 2. Untuk DynamoDB, ia melakukan hingga 10 upaya maksimal total (kecuali diganti dengan yang di atas).
**catatan**  
Dengan backoff eksponensial, upaya terakhir akan menunggu hampir 13 detik.
  + **standard** — Dinamakan standar karena lebih konsisten dengan yang lain AWS SDKs. Menunggu waktu acak dari 0ms hingga 1.000 ms untuk percobaan ulang pertama. Jika percobaan lagi diperlukan, ia mengambil waktu acak lain dari 0ms menjadi 1.000 ms dan mengalikannya dengan 2. Jika percobaan ulang tambahan diperlukan, ia melakukan pengambilan acak yang sama dikalikan dengan 4, dan seterusnya. Setiap penantian dibatasi pada 20 detik. Mode ini akan melakukan percobaan ulang pada kondisi kegagalan yang lebih terdeteksi daripada `legacy` mode. Untuk DynamoDB, ia melakukan hingga 3 upaya maksimal total (kecuali diganti dengan yang di atas). 
  + **adaptif** - Mode coba lagi eksperimental yang mencakup semua fungsionalitas mode standar tetapi menambahkan pelambatan sisi klien otomatis. Dengan pembatasan tingkat adaptif, SDKs dapat memperlambat tingkat di mana permintaan dikirim untuk lebih mengakomodasi kapasitas AWS layanan. Ini adalah mode sementara yang perilakunya mungkin berubah. 

Definisi yang diperluas dari mode coba lagi ini dapat ditemukan di [panduan untuk mencoba ulang](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html) serta dalam [topik perilaku Coba lagi dalam](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) referensi SDK.

Berikut adalah contoh yang secara eksplisit menggunakan kebijakan `legacy` coba lagi dengan maksimal 3 total permintaan (2 percobaan ulang):

```
import boto3
from botocore.config import Config

my_config = Config(
   connect_timeout = 1.0,
   read_timeout = 1.0,
   retries = {
     'mode': 'legacy',
     'total_max_attempts': 3
   }
)
dynamodb = boto3.resource('dynamodb', config=my_config)
```

Karena DynamoDB adalah sistem latensi rendah yang sangat tersedia, Anda mungkin ingin lebih agresif dengan kecepatan percobaan ulang daripada yang diizinkan oleh kebijakan coba ulang bawaan. Anda dapat menerapkan kebijakan coba ulang Anda sendiri dengan menyetel upaya maksimal ke 0, menangkap pengecualian sendiri, dan mencoba lagi sebagaimana mestinya dari kode Anda sendiri alih-alih mengandalkan boto3 untuk melakukan percobaan ulang implisit.

Jika Anda mengelola kebijakan coba ulang Anda sendiri, Anda akan ingin membedakan antara throttle dan error:
+ **Throttle** (ditunjukkan oleh `ProvisionedThroughputExceededException` atau`ThrottlingException`) menunjukkan layanan sehat yang memberi tahu Anda bahwa Anda telah melebihi kapasitas baca atau tulis pada tabel atau partisi DynamoDB. Setiap milidetik yang berlalu, sedikit lebih banyak kapasitas baca atau tulis tersedia, sehingga Anda dapat mencoba lagi dengan cepat (seperti setiap 50 ms) untuk mencoba mengakses kapasitas yang baru dirilis. Dengan throttle, Anda tidak memerlukan backoff eksponensial karena throttle ringan untuk DynamoDB untuk kembali dan tidak dikenakan biaya per permintaan kepada Anda. Backoff eksponensial memberikan penundaan yang lebih lama ke utas klien yang telah menunggu paling lama, yang secara statistik memperluas p50 dan p99 ke luar.
+ **Kesalahan** (ditunjukkan oleh `InternalServerError` atau a`ServiceUnavailable`, antara lain) menunjukkan masalah sementara dengan layanan. Ini bisa untuk seluruh tabel atau mungkin hanya partisi yang Anda baca atau tulis. Dengan kesalahan, Anda dapat berhenti lebih lama sebelum mencoba ulang (seperti 250ms atau 500ms) dan menggunakan jitter untuk membuat percobaan ulang terhuyung-huyung.

**Config untuk koneksi kolam maksimal**

Terakhir, konfigurasi memungkinkan Anda mengontrol ukuran kumpulan koneksi:
+ **max\$1pool\$1connections (int)** - Jumlah maksimum koneksi untuk disimpan dalam kumpulan koneksi. Jika nilai ini tidak diatur, nilai default 10 digunakan.

Opsi ini mengontrol jumlah maksimum koneksi HTTP agar tetap dikumpulkan untuk digunakan kembali. Kolam yang berbeda disimpan per Sesi. Jika Anda mengantisipasi lebih dari 10 utas yang bertentangan dengan klien atau sumber daya yang dibangun dari Sesi yang sama, Anda harus mempertimbangkan untuk meningkatkan ini, jadi utas tidak harus menunggu utas lain menggunakan koneksi gabungan.

```
import boto3
from botocore.config import Config

my_config = Config(
   max_pool_connections = 20
)

# Setup a single session holding up to 20 pooled connections
session = boto3.Session(my_config)

# Create up to 20 resources against that session for handing to threads
# Notice the single-threaded access to the Session and each Resource
resource1 = session.resource('dynamodb')
resource2 = session.resource('dynamodb')
# etc
```

## Penanganan kesalahan
<a name="programming-with-python-error-handling"></a>

AWS pengecualian layanan tidak semuanya didefinisikan secara statis di Boto3. Ini karena kesalahan dan pengecualian dari AWS layanan sangat bervariasi dan dapat berubah. Boto3 membungkus semua pengecualian layanan sebagai a `ClientError` dan mengekspos detail sebagai JSON terstruktur. Misalnya, respons kesalahan mungkin terstruktur seperti ini:

```
{
    'Error': {
        'Code': 'SomeServiceException',
        'Message': 'Details/context around the exception or error'
    },
    'ResponseMetadata': {
        'RequestId': '1234567890ABCDEF',
        'HostId': 'host ID data will appear here as a hash',
        'HTTPStatusCode': 400,
        'HTTPHeaders': {'header metadata key/values will appear here'},
        'RetryAttempts': 0
    }
}
```

Kode berikut menangkap `ClientError` pengecualian dan melihat nilai string di `Code` dalam `Error` untuk menentukan tindakan apa yang harus diambil:

```
import botocore
import boto3

dynamodb = boto3.client('dynamodb')

try:
    response = dynamodb.put_item(...)

except botocore.exceptions.ClientError as err:
    print('Error Code: {}'.format(err.response['Error']['Code']))
    print('Error Message: {}'.format(err.response['Error']['Message']))
    print('Http Code: {}'.format(err.response['ResponseMetadata']['HTTPStatusCode']))
    print('Request ID: {}'.format(err.response['ResponseMetadata']['RequestId']))

    if err.response['Error']['Code'] in ('ProvisionedThroughputExceededException', 'ThrottlingException'):
        print("Received a throttle")
    elif err.response['Error']['Code'] == 'InternalServerError':
        print("Received a server error")
    else:
        raise err
```

Beberapa (tetapi tidak semua) kode pengecualian telah diwujudkan sebagai kelas tingkat atas. Anda dapat memilih untuk menangani ini secara langsung. Saat menggunakan antarmuka Klien, pengecualian ini diisi secara dinamis di klien Anda dan Anda menangkap pengecualian ini menggunakan instance klien Anda, seperti ini:

```
except ddb_client.exceptions.ProvisionedThroughputExceededException:
```

Saat menggunakan antarmuka Resource, Anda harus menggunakan `.meta.client` untuk melintasi dari sumber daya ke Klien yang mendasarinya untuk mengakses pengecualian, seperti ini:

```
except ddb_resource.meta.client.exceptions.ProvisionedThroughputExceededException:
```

Untuk meninjau daftar jenis pengecualian terwujud, Anda dapat membuat daftar secara dinamis:

```
ddb = boto3.client("dynamodb")
print([e for e in dir(ddb.exceptions) if e.endswith('Exception') or e.endswith('Error')])
```

Saat melakukan operasi tulis dengan ekspresi kondisi, Anda dapat meminta bahwa jika ekspresi gagal, nilai item harus dikembalikan dalam respons kesalahan.

```
try:
    response = table.put_item(
        Item=item,
        ConditionExpression='attribute_not_exists(pk)',
        ReturnValuesOnConditionCheckFailure='ALL_OLD'
    )
except table.meta.client.exceptions.ConditionalCheckFailedException as e:
    print('Item already exists:', e.response['Item'])
```

Untuk bacaan lebih lanjut tentang penanganan kesalahan dan pengecualian:
+ [Panduan boto3 tentang penanganan kesalahan](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html) memiliki informasi lebih lanjut tentang teknik penanganan kesalahan. 
+ [Bagian panduan pengembang DynamoDB tentang kesalahan pemrograman](Programming.Errors.md) mencantumkan kesalahan apa yang mungkin Anda temui. 
+ [Bagian Kesalahan Umum dalam referensi API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html).
+ Dokumentasi pada setiap operasi API mencantumkan kesalahan apa yang mungkin dihasilkan oleh panggilan (misalnya [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html)).

## Pencatatan log
<a name="programming-with-python-logging"></a>

Pustaka boto3 terintegrasi dengan modul logging bawaan Python untuk melacak apa yang terjadi selama sesi. Untuk mengontrol level logging, Anda dapat mengonfigurasi modul logging:

```
import logging

logging.basicConfig(level=logging.INFO)
```

Ini mengonfigurasi root logger untuk mencatat `INFO` dan pesan tingkat di atas. Pesan logging yang kurang parah dari level akan diabaikan. Tingkat logging termasuk`DEBUG`,`INFO`,`WARNING`,`ERROR`, dan`CRITICAL`. Nilai default-nya `WARNING`.

Logger di boto3 bersifat hierarkis. Pustaka menggunakan beberapa logger yang berbeda, masing-masing sesuai dengan bagian perpustakaan yang berbeda. Anda dapat mengontrol perilaku masing-masing secara terpisah:
+ **boto3**: Logger utama untuk modul boto3.
+ **botocore**: Logger utama untuk paket botocore.
+ **botocore.auth**: Digunakan untuk mencatat pembuatan tanda tangan untuk permintaan. AWS 
+ **botocore.credentials**: Digunakan untuk mencatat proses pengambilan dan penyegaran kredenal.
+ **botocore.endpoint**: Digunakan untuk pembuatan permintaan logging sebelum dikirim melalui jaringan.
+ **botocore.hooks**: Digunakan untuk peristiwa logging yang dipicu di perpustakaan.
+ **botocore.loaders**: Digunakan untuk logging ketika bagian-bagian dari model layanan dimuat. AWS 
+ **botocore.parsers**: Digunakan untuk mencatat respons AWS layanan sebelum diurai.
+ **botocore.retryhandler**: Digunakan untuk mencatat pemrosesan percobaan ulang permintaan layanan (mode lama). AWS 
+ **botocore.retries.standard**: Digunakan untuk mencatat pemrosesan percobaan ulang permintaan AWS layanan (mode standar atau adaptif).
+ **botocore.utils**: Digunakan untuk mencatat aktivitas lain-lain di perpustakaan.
+ **botocore.waiter**: Digunakan untuk mencatat fungsionalitas pelayan, yang melakukan polling layanan sampai keadaan tertentu AWS tercapai. 

Perpustakaan lain juga mencatat. Secara internal, boto3 menggunakan urllib3 pihak ketiga untuk penanganan koneksi HTTP. Ketika latensi penting, Anda dapat menonton lognya untuk memastikan kolam Anda dimanfaatkan dengan baik dengan melihat kapan urllib3 membuat koneksi baru atau menutup yang tidak aktif.
+ **urllib3.connectionpool:** Digunakan untuk mencatat peristiwa penanganan kumpulan koneksi.

Cuplikan kode berikut menyetel sebagian besar logging `INFO` dengan `DEBUG` logging untuk aktivitas titik akhir dan kumpulan koneksi:

```
import logging

logging.getLogger('boto3').setLevel(logging.INFO)
logging.getLogger('botocore').setLevel(logging.INFO)
logging.getLogger('botocore.endpoint').setLevel(logging.DEBUG)
logging.getLogger('urllib3.connectionpool').setLevel(logging.DEBUG)
```

## Kait acara
<a name="programming-with-python-event-hooks"></a>

Botocore memancarkan peristiwa selama berbagai bagian pelaksanaannya. Anda dapat mendaftarkan penangan untuk acara ini sehingga setiap kali suatu peristiwa dipancarkan, handler Anda akan dipanggil. Ini memungkinkan Anda memperluas perilaku botocore tanpa harus memodifikasi internal.

Misalnya, katakanlah Anda ingin melacak setiap kali `PutItem` operasi dipanggil pada setiap tabel DynamoDB dalam aplikasi Anda. Anda dapat mendaftar pada `'provide-client-params.dynamodb.PutItem'` acara untuk menangkap dan mencatat setiap kali `PutItem` operasi dipanggil pada Sesi terkait. Inilah contohnya:

```
import boto3
import botocore
import logging

def log_put_params(params, **kwargs):
    if 'TableName' in params and 'Item' in params:
        logging.info(f"PutItem on table {params['TableName']}: {params['Item']}")

logging.basicConfig(level=logging.INFO)

session = boto3.Session()
event_system = session.events

# Register our interest in hooking in when the parameters are provided to PutItem
event_system.register('provide-client-params.dynamodb.PutItem', log_put_params)

# Now, every time you use this session to put an item in DynamoDB,
# it will log the table name and item data.
dynamodb = session.resource('dynamodb')
table = dynamodb.Table('YourTableName')
table.put_item(
    Item={
        'pk': '123',
        'sk': 'cart#123',
        'item_data': 'YourItemData',
        # ... more attributes ...
    }
)
```

Di dalam handler, Anda bahkan dapat memanipulasi params secara terprogram untuk mengubah perilaku:

```
params['TableName'] = "NewTableName"
```

Untuk informasi lebih lanjut tentang acara, lihat dokumentasi [botocore tentang acara dan dokumentasi](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html) [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/events.html) tentang acara.

## Pagination dan Paginator
<a name="programming-with-python-pagination"></a>

Beberapa permintaan, seperti Query dan Scan, membatasi ukuran data yang dikembalikan pada satu permintaan dan mengharuskan Anda untuk membuat permintaan berulang untuk menarik halaman berikutnya.

Anda dapat mengontrol jumlah maksimum item yang akan dibaca untuk setiap halaman dengan `limit` parameter. Misalnya, jika Anda menginginkan 10 item terakhir, Anda dapat menggunakan `limit` untuk mengambil hanya 10 item terakhir. Perhatikan batasnya adalah berapa banyak yang harus dibaca dari tabel sebelum penyaringan apa pun diterapkan. Tidak ada cara untuk menentukan yang Anda inginkan tepat 10 setelah pemfilteran; Anda hanya dapat mengontrol jumlah yang telah difilter sebelumnya dan memeriksa sisi klien ketika Anda benar-benar mengambil 10. Terlepas dari batasnya, setiap respons selalu memiliki ukuran maksimum 1 MB.

Jika respons menyertakan a`LastEvaluatedKey`, ini menunjukkan respons berakhir karena mencapai batas hitungan atau ukuran. Kuncinya adalah kunci terakhir yang dievaluasi untuk respons. Anda dapat mengambil ini `LastEvaluatedKey` dan meneruskannya ke panggilan tindak lanjut `ExclusiveStartKey` untuk membaca potongan berikutnya dari titik awal itu. Ketika tidak ada yang `LastEvaluatedKey` dikembalikan, berarti tidak ada lagi item yang cocok dengan Kueri atau Pindai.

Berikut adalah contoh sederhana (menggunakan antarmuka Sumber Daya, tetapi antarmuka Klien memiliki pola yang sama) yang membaca paling banyak 100 item per halaman dan loop hingga semua item telah dibaca.

```
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')

query_params = {
    'KeyConditionExpression': Key('pk').eq('123') & Key('sk').gt(1000),
    'Limit': 100
}

while True:
    response = table.query(**query_params)

    # Process the items however you like
    for item in response['Items']:
        print(item)

    # No LastEvaluatedKey means no more items to retrieve
    if 'LastEvaluatedKey' not in response:
        break

    # If there are possibly more items, update the start key for the next page
    query_params['ExclusiveStartKey'] = response['LastEvaluatedKey']
```

Untuk kenyamanan, boto3 dapat melakukan ini untuk Anda dengan Paginator. Namun, ini hanya berfungsi dengan antarmuka Klien. Berikut kode yang ditulis ulang untuk menggunakan Paginator:

```
import boto3

dynamodb = boto3.client('dynamodb')

paginator = dynamodb.get_paginator('query')

query_params = {
    'TableName': 'YourTableName',
    'KeyConditionExpression': 'pk = :pk_val AND sk > :sk_val',
    'ExpressionAttributeValues': {
        ':pk_val': {'S': '123'},
        ':sk_val': {'N': '1000'},
    },
    'Limit': 100
}

page_iterator = paginator.paginate(**query_params)

for page in page_iterator:
    # Process the items however you like
    for item in page['Items']:
        print(item)
```

Untuk informasi selengkapnya, lihat [Panduan tentang Paginator dan [referensi API untuk](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/paginator/Query.html) DynamoDb.paginator.Query](https://botocore.amazonaws.com/v1/documentation/api/latest/topics/events.html).

**catatan**  
Paginator juga memiliki pengaturan konfigurasi mereka sendiri bernama`MaxItems`,`StartingToken`, dan. `PageSize` Untuk paginating dengan DynamoDB, Anda harus mengabaikan pengaturan ini.

## Pelayan
<a name="programming-with-python-waiters"></a>

Pelayan memberikan kemampuan untuk menunggu sesuatu selesai sebelum melanjutkan. Saat ini, mereka hanya mendukung menunggu tabel dibuat atau dihapus. Di latar belakang, operasi pelayan melakukan pemeriksaan untuk Anda setiap 20 detik hingga 25 kali. Anda bisa melakukannya sendiri, tetapi menggunakan pelayan itu elegan saat menulis otomatisasi.

Kode ini menunjukkan cara menunggu tabel tertentu dibuat:

```
# Create a table, wait until it exists, and print its ARN
response = client.create_table(...)
waiter = client.get_waiter('table_exists')
waiter.wait(TableName='YourTableName')
print('Table created:', response['TableDescription']['TableArn']
```

Untuk informasi lebih lanjut, lihat [Panduan untuk Pelayan dan [Referensi tentang](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#waiters) Pelayan](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#waiters).

# Pemrograman Amazon DynamoDB dengan JavaScript
<a name="programming-with-javascript"></a>

Panduan ini memberikan orientasi kepada programmer yang ingin menggunakan Amazon DynamoDB dengan. JavaScript Pelajari tentang AWS SDK untuk JavaScript, lapisan abstraksi yang tersedia, mengonfigurasi koneksi, menangani kesalahan, menentukan kebijakan coba lagi, mengelola keep-alive, dan banyak lagi.

**Topics**
+ [Tentang AWS SDK untuk JavaScript](#programming-with-javascript-about)
+ [Menggunakan AWS SDK untuk JavaScript V3](#programming-with-javascript-using-the-sdk)
+ [Mengakses dokumentasi JavaScript](#programming-with-javascript-documentation)
+ [Lapisan abstraksi](#programming-with-javascript-abstraction-layers)
+ [Menggunakan fungsi utilitas marshall](#programming-with-javascript-using-marshall-utility)
+ [Membaca item](#programming-with-javascript-reading-items)
+ [Penulisan bersyarat](#programming-with-javascript-conditional-writes)
+ [Paginasi](#programming-with-javascript-pagination)
+ [Menentukan konfigurasi](#programming-with-javascript-config)
+ [Pelayan](#programming-with-javascript-waiters)
+ [Penanganan kesalahan](#programming-with-javascript-error-handling)
+ [Pencatatan log](#programming-with-javascript-logging)
+ [Pertimbangan-pertimbangan](#programming-with-javascript-considerations)

## Tentang AWS SDK untuk JavaScript
<a name="programming-with-javascript-about"></a>

 AWS SDK untuk JavaScript Ini menyediakan akses untuk Layanan AWS menggunakan skrip browser atau Node.js. Dokumentasi ini berfokus pada versi terbaru SDK (V3). AWS SDK untuk JavaScript V3 dikelola oleh AWS sebagai [proyek sumber terbuka yang dihosting di](https://github.com/aws/aws-sdk-js-v3). GitHub Masalah dan permintaan fitur bersifat publik dan Anda dapat mengaksesnya di halaman masalah untuk GitHub repositori.

JavaScript V2 mirip dengan V3, tetapi berisi perbedaan sintaks. V3 lebih modular, membuatnya lebih mudah untuk mengirimkan dependensi yang lebih kecil, dan memiliki dukungan kelas satu. TypeScript Sebaiknya gunakan SDK versi terbaru.

## Menggunakan AWS SDK untuk JavaScript V3
<a name="programming-with-javascript-using-the-sdk"></a>

Anda dapat menambahkan SDK ke aplikasi Node.js Anda menggunakan Node Package Manager. Contoh di bawah ini menunjukkan cara menambahkan paket SDK paling umum untuk bekerja dengan DynamoDB.
+ `npm install @aws-sdk/client-dynamodb`
+ `npm install @aws-sdk/lib-dynamodb`
+ `npm install @aws-sdk/util-dynamodb`

Menginstal paket menambahkan referensi ke bagian ketergantungan file proyek package.json Anda. Anda memiliki opsi untuk menggunakan sintaks ECMAScript modul yang lebih baru. Untuk detail lebih lanjut tentang dua pendekatan ini, lihat bagian Pertimbangan.

## Mengakses dokumentasi JavaScript
<a name="programming-with-javascript-documentation"></a>

Mulailah dengan JavaScript dokumentasi dengan sumber daya berikut:
+ Akses [panduan Pengembang](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html) untuk JavaScript dokumentasi inti. Petunjuk instalasi terletak di bagian **Pengaturan**.
+ Akses dokumentasi [referensi API](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) untuk menjelajahi semua kelas dan metode yang tersedia.
+ SDK untuk JavaScript mendukung banyak Layanan AWS selain DynamoDB. Gunakan prosedur berikut untuk menemukan cakupan API tertentu untuk DynamoDB:

  1. Dari **Services**, pilih **DynamoDB dan Libraries**. Ini mendokumentasikan klien tingkat rendah.

  1. Pilih **lib-dynamodb**. Ini mendokumentasikan klien tingkat tinggi. Kedua klien mewakili dua lapisan abstraksi berbeda yang Anda memiliki pilihan untuk digunakan. Lihat bagian di bawah ini untuk informasi lebih lanjut tentang lapisan abstraksi.

## Lapisan abstraksi
<a name="programming-with-javascript-abstraction-layers"></a>

SDK untuk JavaScript V3 memiliki klien tingkat rendah (`DynamoDBClient`) dan klien tingkat tinggi (). `DynamoDBDocumentClient`

**Topics**
+ [Klien tingkat rendah () `DynamoDBClient`](#programming-with-javascript-low-level-client)
+ [Klien tingkat tinggi () `DynamoDBDocumentClient`](#programming-with-javascript-high-level-client)

### Klien tingkat rendah () `DynamoDBClient`
<a name="programming-with-javascript-low-level-client"></a>

Klien tingkat rendah tidak memberikan abstraksi tambahan atas protokol kawat yang mendasarinya. Ini memberi Anda kontrol penuh atas semua aspek komunikasi, tetapi karena tidak ada abstraksi, Anda harus melakukan hal-hal seperti memberikan definisi item menggunakan format DynamoDB JSON. 

Seperti contoh di bawah ini menunjukkan, dengan format ini tipe data harus dinyatakan secara eksplisit. *S* menunjukkan nilai string dan *N* menunjukkan nilai angka. Angka pada kawat selalu dikirim sebagai string yang ditandai sebagai jenis angka untuk memastikan tidak ada kehilangan presisi. Panggilan API tingkat rendah memiliki pola penamaan seperti `PutItemCommand` dan`GetItemCommand`.

Contoh berikut adalah menggunakan klien tingkat rendah dengan `Item` didefinisikan menggunakan DynamoDB JSON:

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      "id": { S: "Product01" },
      "description": { S: "Hiking Boots" },
      "category": { S: "footwear" },
      "sku": { S: "hiking-sku-01" },
      "size": { N: "9" }
    }
  };

  try {
    const data = await client.send(new PutItemCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

### Klien tingkat tinggi () `DynamoDBDocumentClient`
<a name="programming-with-javascript-high-level-client"></a>

Klien dokumen DynamoDB tingkat tinggi menawarkan fitur kenyamanan bawaan, seperti menghilangkan kebutuhan untuk mengumpulkan data secara manual dan memungkinkan untuk membaca dan menulis langsung menggunakan objek standar. JavaScript [Dokumentasi untuk `lib-dynamodb`](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-lib-dynamodb/) menyediakan daftar keuntungan.

Untuk membuat instance`DynamoDBDocumentClient`, buat level rendah `DynamoDBClient` dan kemudian bungkus dengan a. `DynamoDBDocumentClient` Konvensi penamaan fungsi sedikit berbeda antara kedua paket. Misalnya, penggunaan tingkat rendah `PutItemCommand` sementara penggunaan tingkat tinggi. `PutCommand` Nama yang berbeda memungkinkan kedua set fungsi untuk hidup berdampingan dalam konteks yang sama, memungkinkan Anda untuk mencampur keduanya dalam skrip yang sama.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function addProduct() {
  const params = {
    TableName: "products",
    Item: {
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    },
  };

  try {
    const data = await docClient.send(new PutCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

addProduct();
```

Pola penggunaan konsisten saat Anda membaca item menggunakan operasi API seperti`GetItem`,`Query`, atau`Scan`.

## Menggunakan fungsi utilitas marshall
<a name="programming-with-javascript-using-marshall-utility"></a>

Anda dapat menggunakan klien tingkat rendah dan marshall atau unmarshall tipe data Anda sendiri. Paket utilitas, [util-dynamodb](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-util-dynamodb/), memiliki fungsi `marshall()` utilitas yang menerima JSON dan menghasilkan DynamoDB JSON, serta fungsi, yang melakukan sebaliknya. `unmarshall()` Contoh berikut menggunakan klien tingkat rendah dengan data marshalling ditangani oleh panggilan. `marshall()`

```
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");
const { marshall } = require("@aws-sdk/util-dynamodb");

const client = new DynamoDBClient({});

async function addProduct() {
  const params = {
    TableName: "products",
    Item: marshall({
      id: "Product01",
      description: "Hiking Boots",
      category: "footwear",
      sku: "hiking-sku-01",
      size: 9,
    }),
  };

  try {
    const data = await client.send(new PutItemCommand(params));
  } catch (error) {
    console.error("Error:", error);
  }
}
addProduct();
```

## Membaca item
<a name="programming-with-javascript-reading-items"></a>

Untuk membaca satu item dari DynamoDB, Anda menggunakan `GetItem` operasi API. Mirip dengan `PutItem` perintah, Anda memiliki pilihan untuk menggunakan klien tingkat rendah atau klien Dokumen tingkat tinggi. Contoh di bawah ini menunjukkan menggunakan klien Dokumen tingkat tinggi untuk mengambil item.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, GetCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function getProduct() {
  const params = {
    TableName: "products",
    Key: {
      id: "Product01",
    },
  };

  try {
    const data = await docClient.send(new GetCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

getProduct();
```

Gunakan operasi `Query` API untuk membaca beberapa item. Anda dapat menggunakan klien tingkat rendah atau klien Dokumen. Contoh di bawah ini menggunakan klien Dokumen tingkat tinggi.

```
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
  DynamoDBDocumentClient,
  QueryCommand,
} = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({});

const docClient = DynamoDBDocumentClient.from(client);

async function productSearch() {
  const params = {
    TableName: "products",
    IndexName: "GSI1",
    KeyConditionExpression: "#category = :category and begins_with(#sku, :sku)",
    ExpressionAttributeNames: {
      "#category": "category",
      "#sku": "sku",
    },
    ExpressionAttributeValues: {
      ":category": "footwear",
      ":sku": "hiking",
    },
  };

  try {
    const data = await docClient.send(new QueryCommand(params));
    console.log('result : ' + JSON.stringify(data));
  } catch (error) {
    console.error("Error:", error);
  }
}

productSearch();
```

## Penulisan bersyarat
<a name="programming-with-javascript-conditional-writes"></a>

Operasi penulisan DynamoDB dapat menentukan ekspresi kondisi logis yang harus mengevaluasi ke true agar penulisan dapat dilanjutkan. Jika kondisi tidak mengevaluasi ke true, operasi tulis menghasilkan pengecualian. Ekspresi kondisi dapat memeriksa apakah item sudah ada atau apakah atributnya cocok dengan batasan tertentu.

`ConditionExpression = "version = :ver AND size(VideoClip) < :maxsize" `

Ketika ekspresi kondisional gagal, Anda dapat menggunakan `ReturnValuesOnConditionCheckFailure` untuk meminta agar respons kesalahan menyertakan item yang tidak memenuhi kondisi untuk menyimpulkan apa masalahnya. Untuk detail selengkapnya, lihat [Menangani kesalahan penulisan bersyarat dalam skenario konkurensi tinggi dengan Amazon DynamoDB](https://aws.amazon.com/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/).

```
try {
      const response = await client.send(new PutCommand({
          TableName: "YourTableName",
          Item: item,
          ConditionExpression: "attribute_not_exists(pk)",
          ReturnValuesOnConditionCheckFailure: "ALL_OLD"
      }));
  } catch (e) {
      if (e.name === 'ConditionalCheckFailedException') {
          console.log('Item already exists:', e.Item);
      } else {
          throw e;
      }
  }
```

[Contoh kode tambahan yang menunjukkan aspek lain dari penggunaan JavsScript SDK V3 tersedia di [Dokumentasi JavaScript SDK V3](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_dynamodb_code_examples.html) dan di bawah repositori. DynamoDB-SDK-Examples GitHub ](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/node.js)

## Paginasi
<a name="programming-with-javascript-pagination"></a>

**Topics**
+ [Menggunakan metode `paginateScan` kenyamanan](#using-the-paginatescan-convenience-method)

Permintaan baca seperti `Scan` atau kemungkinan `Query` akan mengembalikan beberapa item dalam kumpulan data. Jika Anda melakukan `Scan` atau `Query` dengan `Limit` parameter, maka setelah sistem membaca banyak item, sebagian respons akan dikirim, dan Anda harus membuat paginasi untuk mengambil item tambahan.

Sistem hanya akan membaca maksimal 1 megabyte data per permintaan. Jika Anda menyertakan `Filter` ekspresi, sistem akan tetap membaca megabyte, maksimum, data dari disk, tetapi akan mengembalikan item megabyte yang cocok dengan filter. Operasi filter dapat mengembalikan 0 item untuk halaman, tetapi masih memerlukan pagination lebih lanjut sebelum pencarian habis.

Anda harus mencari `LastEvaluatedKey` dalam respons dan menggunakannya sebagai `ExclusiveStartKey` parameter dalam permintaan berikutnya untuk melanjutkan pengambilan data. Ini berfungsi sebagai bookmark seperti yang tercantum dalam contoh berikut.

**catatan**  
Sampel melewati nol `lastEvaluatedKey` sebagai `ExclusiveStartKey` pada iterasi pertama dan ini diperbolehkan.

Contoh menggunakan`LastEvaluatedKey`:

```
const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScan() {
  let lastEvaluatedKey;
  let pageCount = 0;

  do {
    const params = {
      TableName: "products",
      ExclusiveStartKey: lastEvaluatedKey,
    };

    const response = await client.send(new ScanCommand(params));
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, response.Items);
    lastEvaluatedKey = response.LastEvaluatedKey;
  } while (lastEvaluatedKey);
}

paginatedScan().catch((err) => {
  console.error(err);
});
```

### Menggunakan metode `paginateScan` kenyamanan
<a name="using-the-paginatescan-convenience-method"></a>



SDK menyediakan metode kenyamanan yang dipanggil `paginateScan` dan `paginateQuery` yang melakukan ini bekerja untuk Anda dan membuat permintaan berulang di belakang layar. Tentukan jumlah maksimum item yang akan dibaca per permintaan menggunakan `Limit` parameter standar.

```
const { DynamoDBClient, paginateScan } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDBClient({});

async function paginatedScanUsingPaginator() {
  const params = {
    TableName: "products",
    Limit: 100
  };

  const paginator = paginateScan({client}, params);

  let pageCount = 0;

  for await (const page of paginator) {
    pageCount++;
    console.log(`Page ${pageCount}, Items:`, page.Items);
  }
}

paginatedScanUsingPaginator().catch((err) => {
  console.error(err);
});
```

**catatan**  
Melakukan pemindaian tabel penuh secara teratur bukanlah pola akses yang disarankan kecuali tabelnya kecil.

## Menentukan konfigurasi
<a name="programming-with-javascript-config"></a>

**Topics**
+ [Config untuk batas waktu](#programming-with-javascript-config-timeouts)
+ [Config untuk keep-alive](#programming-with-javascript-config-keep-alive)
+ [Config untuk percobaan ulang](#programming-with-javascript-config-retries)

Saat mengatur`DynamoDBClient`, Anda dapat menentukan berbagai penggantian konfigurasi dengan meneruskan objek konfigurasi ke konstruktor. Misalnya, Anda dapat menentukan Wilayah yang akan disambungkan jika belum diketahui konteks panggilan atau URL titik akhir yang akan digunakan. Ini berguna jika Anda ingin menargetkan instance DynamoDB Local untuk tujuan pengembangan.

```
const client = new DynamoDBClient({
  region: "eu-west-1",
  endpoint: "http://localhost:8000",
});
```

### Config untuk batas waktu
<a name="programming-with-javascript-config-timeouts"></a>

DynamoDB menggunakan HTTPS untuk komunikasi client-server. Anda dapat mengontrol beberapa aspek dari lapisan HTTP dengan menyediakan `NodeHttpHandler` objek. Misalnya, Anda dapat menyesuaikan nilai batas waktu kunci `connectionTimeout` dan`requestTimeout`. `connectionTimeout`Ini adalah durasi maksimum, dalam milidetik, bahwa klien akan menunggu sambil mencoba membuat koneksi sebelum menyerah.

Ini `requestTimeout` menentukan berapa lama klien akan menunggu respons setelah permintaan dikirim, juga dalam milidetik. Default untuk keduanya adalah nol, artinya batas waktu dinonaktifkan dan tidak ada batasan berapa lama klien akan menunggu jika respons tidak tiba. Anda harus mengatur batas waktu ke sesuatu yang masuk akal sehingga jika terjadi masalah jaringan, permintaan akan error dan permintaan baru dapat dimulai. Contoh:

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";

const requestHandler = new NodeHttpHandler({
  connectionTimeout: 2000,
  requestTimeout: 2000,
});

const client = new DynamoDBClient({
  requestHandler
});
```

**catatan**  
Contoh yang diberikan menggunakan impor [Smithy](https://smithy.io/2.0/index.html). Smithy adalah bahasa untuk mendefinisikan layanan dan SDKs, open-source dan dikelola oleh. AWS

Selain mengonfigurasi nilai batas waktu, Anda dapat mengatur jumlah soket maksimum, yang memungkinkan peningkatan jumlah koneksi bersamaan per asal. Panduan pengembang mencakup [detail tentang mengonfigurasi `maxSockets` parameter](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html).

### Config untuk keep-alive
<a name="programming-with-javascript-config-keep-alive"></a>

Saat menggunakan HTTPS, permintaan pertama selalu membutuhkan back-and-forth komunikasi untuk membuat koneksi yang aman. HTTP Keep-Alive memungkinkan permintaan berikutnya untuk menggunakan kembali koneksi yang sudah dibuat, membuat permintaan lebih efisien dan menurunkan latensi. HTTP Keep-Alive diaktifkan secara default dengan V3. JavaScript 

Ada batasan berapa lama koneksi idle dapat tetap hidup. Pertimbangkan untuk mengirim permintaan berkala, mungkin setiap menit, jika Anda memiliki koneksi idle tetapi ingin permintaan berikutnya menggunakan koneksi yang sudah dibuat.

**catatan**  
Perhatikan bahwa di V2 SDK yang lebih lama, keep-alive dimatikan secara default, yang berarti setiap koneksi akan segera ditutup setelah digunakan. Jika menggunakan V2, Anda dapat mengganti pengaturan ini.

### Config untuk percobaan ulang
<a name="programming-with-javascript-config-retries"></a>

Ketika SDK menerima respons kesalahan dan kesalahan dapat dilanjutkan seperti yang ditentukan oleh SDK, seperti pengecualian pelambatan atau pengecualian layanan sementara, SDK akan mencoba lagi. Ini terjadi tanpa terlihat bagi Anda sebagai penelepon, kecuali bahwa Anda mungkin memperhatikan permintaan membutuhkan waktu lebih lama untuk berhasil.

SDK untuk JavaScript V3 akan membuat 3 permintaan total, secara default, sebelum menyerah dan meneruskan kesalahan ke dalam konteks panggilan. Anda dapat menyesuaikan jumlah dan frekuensi percobaan ulang ini.

`DynamoDBClient`Konstruktor menerima `maxAttempts` pengaturan yang membatasi berapa banyak upaya yang akan terjadi. Contoh di bawah ini menaikkan nilai dari default 3 menjadi total 5. Jika Anda menyetelnya ke 0 atau 1, itu menunjukkan Anda tidak ingin mencoba ulang otomatis dan ingin menangani kesalahan yang dapat dilanjutkan sendiri dalam blok catch Anda.

```
const client = new DynamoDBClient({
  maxAttempts: 5,
});
```

Anda juga dapat mengontrol waktu percobaan ulang dengan strategi coba lagi khusus. Untuk melakukan ini, impor paket `util-retry` utilitas dan buat fungsi backoff khusus yang menghitung waktu tunggu antara percobaan ulang berdasarkan jumlah coba lagi saat ini.

Contoh di bawah ini mengatakan untuk melakukan maksimal 5 upaya dengan penundaan 15, 30, 90, dan 360 milidetik jika upaya pertama gagal. Fungsi backoff kustom,` calculateRetryBackoff`, menghitung penundaan dengan menerima nomor percobaan ulang (dimulai dengan 1 untuk percobaan ulang pertama) dan mengembalikan berapa milidetik untuk menunggu permintaan itu.

```
const { ConfiguredRetryStrategy } = require("@aws-sdk/util-retry");

const calculateRetryBackoff = (attempt) => {
  const backoffTimes = [15, 30, 90, 360];
  return backoffTimes[attempt - 1] || 0;
};

const client = new DynamoDBClient({
  retryStrategy: new ConfiguredRetryStrategy(
    5, // max attempts.
    calculateRetryBackoff // backoff function.
  ),
});
```

## Pelayan
<a name="programming-with-javascript-waiters"></a>

Klien DynamoDB mencakup dua fungsi [pelayan berguna](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/wait/index.html#cli-aws-dynamodb-wait) yang dapat digunakan saat membuat, memodifikasi, atau menghapus tabel saat Anda ingin kode Anda menunggu untuk melanjutkan hingga modifikasi tabel selesai. Misalnya, Anda dapat menyebarkan tabel, memanggil `waitUntilTableExists` fungsi, dan kode akan memblokir sampai tabel telah dibuat **AKTIF**. Pelayan secara internal melakukan polling layanan DynamoDB dengan setiap 20 detik. `describe-table`

```
import {waitUntilTableExists, waitUntilTableNotExists} from "@aws-sdk/client-dynamodb";

… <create table details>

const results = await waitUntilTableExists({client: client, maxWaitTime: 180}, {TableName: "products"});
if (results.state == 'SUCCESS') {
  return results.reason.Table
}
console.error(`${results.state} ${results.reason}`);
```

`waitUntilTableExists`Fitur mengembalikan kontrol hanya ketika dapat melakukan `describe-table` perintah yang menunjukkan status tabel **ACTIVE**. Ini memastikan bahwa Anda dapat menggunakan `waitUntilTableExists` untuk menunggu penyelesaian pembuatan, serta modifikasi seperti menambahkan indeks GSI, yang mungkin memerlukan beberapa waktu untuk diterapkan sebelum tabel kembali ke status **AKTIF**.

## Penanganan kesalahan
<a name="programming-with-javascript-error-handling"></a>

Dalam contoh awal di sini, kami telah menangkap semua kesalahan secara luas. Namun, dalam aplikasi praktis, penting untuk membedakan antara berbagai jenis kesalahan dan menerapkan penanganan kesalahan yang lebih tepat.

Respons kesalahan DynamoDB berisi metadata, termasuk nama kesalahan. Anda dapat menangkap kesalahan kemudian mencocokkan dengan kemungkinan nama string dari kondisi kesalahan untuk menentukan cara melanjutkan. Untuk kesalahan sisi server, Anda dapat memanfaatkan `instanceof` operator dengan jenis kesalahan yang diekspor oleh `@aws-sdk/client-dynamodb` paket untuk mengelola penanganan kesalahan secara efisien.

Penting untuk dicatat bahwa kesalahan ini hanya terwujud setelah semua percobaan ulang telah habis. Jika kesalahan dicoba lagi dan akhirnya diikuti oleh panggilan yang berhasil, dari perspektif kode, tidak ada kesalahan hanya latensi yang sedikit meningkat. Percobaan ulang akan muncul di CloudWatch bagan Amazon sebagai permintaan yang tidak berhasil, seperti permintaan throttle atau error. Jika klien mencapai jumlah percobaan ulang maksimum, itu akan menyerah dan menghasilkan pengecualian. Ini adalah cara klien mengatakan itu tidak akan mencoba lagi.

Di bawah ini adalah cuplikan untuk menangkap kesalahan dan mengambil tindakan berdasarkan jenis kesalahan yang dikembalikan.

```
import {
  ResourceNotFoundException
  ProvisionedThroughputExceededException,
  DynamoDBServiceException,
} from "@aws-sdk/client-dynamodb";

try {
  await client.send(someCommand);
} catch (e) {
    if (e instanceof ResourceNotFoundException) {
      // Handle ResourceNotFoundException
    } else if (e instanceof ProvisionedThroughputExceededException) {
      // Handle ProvisionedThroughputExceededException
    } else if (e instanceof DynamoDBServiceException) {
      // Handle DynamoDBServiceException
    } else {
      // Other errors such as those from the SDK
      if (e.name === "TimeoutError") {
        // Handle SDK TimeoutError.
      } else {
        // Handle other errors.
      }
    }
}
```

Lihat [Penanganan kesalahan dengan DynamoDB](Programming.Errors.md) string kesalahan umum di *DynamoDB* Developer Guide. Kesalahan persis yang mungkin terjadi dengan panggilan API tertentu dapat ditemukan dalam dokumentasi untuk panggilan API tersebut, seperti [dokumen Query API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html).

Metadata kesalahan mencakup properti tambahan, tergantung pada kesalahannya. Untuk a` TimeoutError`, metadata mencakup jumlah upaya yang dilakukan dan`totalRetryDelay`, seperti yang ditunjukkan di bawah ini.

```
{
  "name": "TimeoutError",
  "$metadata": {
    "attempts": 3,
    "totalRetryDelay": 199
  }
}
```

Jika Anda mengelola kebijakan coba ulang Anda sendiri, Anda akan ingin membedakan antara throttle dan error:
+ **Throttle** (ditunjukkan oleh ` ProvisionedThroughputExceededException` atau`ThrottlingException`) menunjukkan layanan sehat yang memberi tahu Anda bahwa Anda telah melebihi kapasitas baca atau tulis pada tabel atau partisi DynamoDB. Setiap milidetik yang berlalu, sedikit lebih banyak kapasitas baca atau tulis tersedia, sehingga Anda dapat mencoba lagi dengan cepat, seperti setiap 50 ms, untuk mencoba mengakses kapasitas yang baru dirilis.

   Dengan throttle Anda tidak terlalu membutuhkan backoff eksponensial karena throttle ringan untuk DynamoDB untuk kembali dan tidak dikenakan biaya per permintaan kepada Anda. Backoff eksponensial memberikan penundaan yang lebih lama ke utas klien yang telah menunggu paling lama, yang secara statistik memperluas p50 dan p99 ke luar.
+ **Kesalahan** (ditunjukkan oleh ` InternalServerError` atau a`ServiceUnavailable`, antara lain) menunjukkan masalah sementara dengan layanan, mungkin seluruh tabel atau hanya partisi yang Anda baca atau tulis. Dengan kesalahan, Anda dapat berhenti lebih lama sebelum mencoba ulang, seperti 250ms atau 500ms, dan menggunakan jitter untuk membuat percobaan ulang terhuyung-huyung.

## Pencatatan log
<a name="programming-with-javascript-logging"></a>

Aktifkan logging untuk mendapatkan detail lebih lanjut tentang apa yang dilakukan SDK. Anda dapat mengatur parameter pada `DynamoDBClient` seperti yang ditunjukkan pada contoh di bawah ini. Informasi log lainnya akan muncul di konsol dan menyertakan metadata seperti kode status dan kapasitas yang dikonsumsi. Jika Anda menjalankan kode secara lokal di jendela terminal, log akan muncul di sana. Jika Anda menjalankan kode di AWS Lambda, dan Anda memiliki CloudWatch log Amazon yang disiapkan, maka output konsol akan ditulis di sana.

```
const client = new DynamoDBClient({
  logger: console
});
```

Anda juga dapat menghubungkan ke aktivitas SDK internal dan melakukan pencatatan khusus saat peristiwa tertentu terjadi. Contoh di bawah ini menggunakan klien `middlewareStack` untuk mencegat setiap permintaan saat dikirim dari SDK dan mencatatnya saat terjadi.

```
const client = new DynamoDBClient({});

client.middlewareStack.add(
  (next) => async (args) => {
    console.log("Sending request from AWS SDK", { request: args.request });
    return next(args);
  },
  {
    step: "build",
    name: "log-ddb-calls",
  }
);
```

`MiddlewareStack`Ini menyediakan pengait yang kuat untuk mengamati dan mengendalikan perilaku SDK. Lihat blog [Memperkenalkan Middleware Stack in Modular AWS SDK untuk JavaScript](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/), untuk informasi lebih lanjut.

## Pertimbangan-pertimbangan
<a name="programming-with-javascript-considerations"></a>

Saat menerapkan AWS SDK untuk JavaScript dalam proyek Anda, berikut adalah beberapa faktor lebih lanjut yang perlu dipertimbangkan.

**Sistem modul**  
SDK mendukung dua sistem modul, CommonJS dan ES ()ECMAScript. CommonJS menggunakan `require` fungsi, sedangkan ES menggunakan `import` kata kunci.  

1. **JS umum** - `const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb");`

1. **ES (ECMAScript**— `import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";`
Jenis proyek menentukan sistem modul yang akan digunakan dan ditentukan di bagian tipe file package.json Anda. Defaultnya adalah CommonJS. Gunakan `"type": "module"` untuk menunjukkan proyek ES. Jika Anda memiliki proyek Node.JS yang sudah ada yang menggunakan format paket CommonJS, Anda masih dapat menambahkan fungsi dengan sintaks Impor SDK V3 yang lebih modern dengan menamai file fungsi Anda dengan ekstensi.mjs. Ini akan memungkinkan file kode diperlakukan sebagai ES (ECMAScript).

**Operasi asinkron**  
Anda akan melihat banyak contoh kode menggunakan callback dan janji untuk menangani hasil operasi DynamoDB. Dengan modern, kompleksitas JavaScript ini tidak lagi diperlukan dan pengembang dapat memanfaatkan async/await sintaks yang lebih ringkas dan mudah dibaca untuk operasi asinkron.

**Waktu proses peramban web**  
Pengembang web dan seluler yang membangun dengan React atau React Native dapat menggunakan SDK untuk JavaScript proyek mereka. Dengan V2 SDK sebelumnya, pengembang web harus memuat SDK lengkap ke browser, merujuk gambar SDK yang dihosting di. https://sdk.amazonaws.com/js/   
Dengan V3, dimungkinkan untuk menggabungkan hanya modul klien V3 yang diperlukan dan semua JavaScript fungsi yang diperlukan ke dalam satu JavaScript file menggunakan Webpack, dan menambahkannya dalam tag skrip di halaman HTML Anda, seperti yang dijelaskan di bagian [Memulai di skrip browser](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/getting-started-browser.html) dari dokumentasi SDK. `<head>`

**Operasi pesawat data DAX**  
Operasi bidang data Amazon DynamoDB Streams Accelerator (DAX) didukung oleh SDK untuk V3. JavaScript 

# Pemrograman DynamoDB dengan AWS SDK for Java 2.x
<a name="ProgrammingWithJava"></a>

Panduan pemrograman ini memberikan orientasi bagi programmer yang ingin menggunakan Amazon DynamoDB dengan Java. Panduan ini mencakup konsep yang berbeda termasuk lapisan abstraksi, manajemen konfigurasi, penanganan kesalahan, pengendalian kebijakan coba lagi, dan pengelolaan keep-alive.

**Topics**
+ [Tentang AWS SDK for Java 2.x](#AboutProgrammingWithJavaSDK)
+ [Memulai](#GetStartedProgrammingWithJavaSDK)
+ [Dokumentasi SDK for Java 2.x](#ProgrammingWithJavaUseDoc)
+ [Antarmuka yang didukung](#JavaInterfaces)
+ [Contoh kode tambahan](#AdditionalCodeEx)
+ [Sinkronisasi dan pemrograman async](#SyncAsyncProgramming)
+ [Klien HTTP](#HttpClients)
+ [Config](#ConfigHttpClient)
+ [Penanganan kesalahan](#JavaErrorHandling)
+ [AWS ID permintaan](#JavaRequestID)
+ [Pencatatan log](#JavaLogging)
+ [Paginasi](#JavaPagination)
+ [Anotasi kelas data](#JavaDataClassAnnotation)

## Tentang AWS SDK for Java 2.x
<a name="AboutProgrammingWithJavaSDK"></a>

Anda dapat mengakses DynamoDB dari Java menggunakan resmi. AWS SDK untuk Java SDK for Java memiliki dua versi: 1.x dan 2.x. end-of-supportUntuk 1.x [diumumkan](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) pada 12 Januari 2024. Ini akan memasuki mode pemeliharaan pada 31 Juli 2024 dan akan jatuh tempo pada 31 Desember 2025. end-of-support Untuk pengembangan baru, kami sangat menyarankan Anda menggunakan 2.x, yang pertama kali dirilis pada tahun 2018. Panduan ini secara eksklusif menargetkan 2.x dan hanya berfokus pada bagian SDK yang relevan dengan DynamoDB.

Untuk informasi tentang pemeliharaan dan dukungan AWS SDKs, lihat [Kebijakan pemeliharaan AWS SDK dan Tools serta](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) [matriks dukungan versi Tools](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) di *Panduan Referensi Alat AWS SDKs dan*.AWS SDKs 

 AWS SDK for Java 2.x Ini adalah penulisan ulang utama dari basis kode 1.x. SDK for Java 2.x mendukung fitur Java modern, seperti I/O non-blocking yang diperkenalkan di Java 8. SDK for Java 2.x juga menambahkan dukungan untuk implementasi klien HTTP pluggable untuk memberikan lebih banyak fleksibilitas koneksi jaringan dan opsi konfigurasi.

Perubahan nyata antara SDK for Java 1.x dan SDK for Java 2.x adalah penggunaan nama paket baru. Java 1.x SDK menggunakan nama `com.amazonaws` paket, sedangkan Java 2.x SDK menggunakan. `software.amazon.awssdk` Demikian pula, artefak Maven untuk Java 1.x SDK menggunakan `com.amazonaws``groupId`, sedangkan artefak Java 2.x SDK menggunakan file. `software.amazon.awssdk` `groupId`

**penting**  
 AWS SDK untuk Java 1.x memiliki paket DynamoDB bernama. `com.amazonaws.dynamodbv2` “v2" dalam nama paket tidak menunjukkan bahwa itu untuk Java 2 (J2SE). Sebaliknya, “v2" menunjukkan bahwa paket mendukung [versi kedua](CurrentAPI.md) API tingkat rendah DynamoDB alih-alih versi [asli](Appendix.APIv20111205.md) API tingkat rendah.

### Support untuk versi Java
<a name="SupportedJavaVersions"></a>

 AWS SDK for Java 2.x Ini memberikan dukungan penuh untuk [rilis Java](https://github.com/aws/aws-sdk-java-v2?tab=readme-ov-file#maintenance-and-support-for-java-versions) dukungan jangka panjang (LTS).

## Memulai dengan AWS SDK for Java 2.x
<a name="GetStartedProgrammingWithJavaSDK"></a>

Tutorial berikut menunjukkan cara menggunakan [Apache Maven](https://maven.apache.org/) untuk mendefinisikan dependensi untuk SDK for Java 2.x. Tutorial ini juga menunjukkan cara menulis kode yang menghubungkan ke DynamoDB untuk daftar tabel DynamoDB yang tersedia. Tutorial dalam panduan ini didasarkan pada tutorial [Memulai dengan AWS SDK for Java 2.x di](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html) *Panduan AWS SDK for Java 2.x Pengembang*. Kami telah mengedit tutorial ini untuk melakukan panggilan ke DynamoDB alih-alih Amazon S3.

**Topics**
+ [Langkah 1: Siapkan untuk tutorial ini](#GetStartedJavaSetup)
+ [Langkah 2: Buat proyek](#GetStartedJavaProjectSetup)
+ [Langkah 3: Tulis kodenya](#GetStartedJavaCode)
+ [Langkah 4: Bangun dan jalankan aplikasi](#GetStartedRunJava)

### Langkah 1: Siapkan untuk tutorial ini
<a name="GetStartedJavaSetup"></a>

Sebelum Anda memulai tutorial ini, Anda memerlukan yang berikut:
+ Izin untuk mengakses DynamoDB.
+ Lingkungan pengembangan Java yang dikonfigurasi dengan akses masuk tunggal untuk Layanan AWS menggunakan file. Portal akses AWS

Untuk mengatur tutorial ini, ikuti petunjuk di [Ikhtisar pengaturan](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-overview) di *Panduan AWS SDK for Java 2.x Pengembang*. Setelah [Anda mengkonfigurasi lingkungan pengembangan Anda dengan akses masuk tunggal](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials) untuk Java SDK dan Anda memiliki [sesi portal AWS akses aktif](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso), kemudian lanjutkan ke [Langkah 2](#GetStartedJavaProjectSetup) dari tutorial ini.

### Langkah 2: Buat proyek
<a name="GetStartedJavaProjectSetup"></a>

Untuk membuat proyek untuk tutorial ini, Anda menjalankan perintah Maven yang meminta Anda untuk masukan tentang cara mengkonfigurasi proyek. Setelah semua input dimasukkan dan dikonfirmasi, Maven selesai membangun proyek dengan membuat `pom.xml` file dan membuat file Java rintisan.

1. Buka terminal atau jendela prompt perintah dan arahkan ke direktori pilihan Anda, misalnya, `Home` folder Anda `Desktop` atau.

1. Masukkan perintah berikut di terminal, lalu tekan **Enter**.

   ```
   mvn archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-app-quickstart \
      -DarchetypeVersion=2.22.0
   ```

1. Untuk setiap prompt, masukkan nilai yang tercantum di kolom kedua.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazondynamodb/latest/developerguide/ProgrammingWithJava.html)

1. Setelah Anda memasukkan nilai terakhir, Maven mencantumkan pilihan yang Anda buat. Untuk mengonfirmasi, masukkan **Y**. Atau, masukkan **N**, lalu masukkan kembali pilihan Anda.

Maven membuat folder proyek bernama `getstarted` berdasarkan `artifactId` nilai yang Anda masukkan. Di dalam `getstarted` folder, temukan file bernama `README.md` yang dapat Anda tinjau, `pom.xml` file, dan `src` direktori.

Maven membangun pohon direktori berikut.

```
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
```

Berikut ini menunjukkan isi dari file `pom.xml` proyek.

#### `pom.xml`
<a name="ProjectSetupCollapse2"></a>

`dependencyManagement`Bagian ini berisi ketergantungan ke AWS SDK for Java 2.x, dan `dependencies` bagian memiliki ketergantungan untuk DynamoDB. Menentukan dependensi ini memaksa Maven untuk menyertakan `.jar` file yang relevan di jalur kelas Java Anda. Secara default, AWS SDK tidak menyertakan semua kelas untuk semua Layanan AWS. Untuk DynamoDB, jika Anda menggunakan antarmuka tingkat rendah, maka Anda harus memiliki ketergantungan pada artefak. `dynamodb` Atau, jika Anda menggunakan antarmuka tingkat tinggi, pada `dynamodb-enhanced` artefak. Jika Anda tidak menyertakan dependensi yang relevan, maka kode Anda tidak dapat dikompilasi. Proyek ini menggunakan Java 1.8 karena `1.8` nilai dalam `maven.compiler.source` dan `maven.compiler.target` properti.

```
<?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>
```

### Langkah 3: Tulis kodenya
<a name="GetStartedJavaCode"></a>

Kode berikut menunjukkan `App` kelas yang dibuat Maven. `main`Metode ini adalah titik masuk ke dalam aplikasi, yang menciptakan sebuah instance dari `Handler` kelas dan kemudian memanggil `sendRequest` metodenya.

#### `App` kelas
<a name="projectsetup-collapse2"></a>

```
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");
     }
 }
```

`DependencyFactory`Kelas yang dibuat Maven berisi metode `dynamoDbClient` pabrik yang membangun dan mengembalikan sebuah instance. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html) `DynamoDbClient`Instance menggunakan instance dari klien HTTP berbasis Apache. Ini karena Anda menentukan `apache-client` kapan Maven meminta Anda untuk klien HTTP mana yang akan digunakan.

Kode berikut menunjukkan `DependencyFactory` kelas.

#### DependencyFactory kelas
<a name="code-collapse2"></a>

```
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`Kelas berisi logika utama program Anda. Ketika sebuah instance `Handler` dibuat di `App` kelas, `DependencyFactory` melengkapi klien `DynamoDbClient` layanan. Kode Anda menggunakan `DynamoDbClient` instance untuk memanggil DynamoDB.

Maven menghasilkan `Handler` kelas berikut dengan komentar. `TODO` Langkah selanjutnya dalam tutorial menggantikan *`TODO`*komentar dengan kode.

#### `Handler`kelas, yang dihasilkan oleh Maven
<a name="code-collapsible3"></a>

```
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.
     }
 }
```

Untuk mengisi logika, ganti seluruh isi `Handler` kelas dengan kode berikut. `sendRequest`Metode diisi dan impor yang diperlukan ditambahkan.

#### `Handler`kelas, diimplementasikan
<a name="code-collapse4"></a>

Kode berikut menggunakan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)contoh untuk mengambil daftar tabel yang ada. Jika tabel ada untuk akun tertentu dan Wilayah AWS, maka kode menggunakan `Logger` instance untuk mencatat nama-nama tabel ini.

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

### Langkah 4: Bangun dan jalankan aplikasi
<a name="GetStartedRunJava"></a>

Setelah Anda membuat proyek dan berisi `Handler` kelas lengkap, membangun dan menjalankan aplikasi.

1. Pastikan Anda memiliki AWS IAM Identity Center sesi aktif. Untuk mengonfirmasi, jalankan perintah AWS Command Line Interface (AWS CLI) `aws sts get-caller-identity` dan periksa responsnya. Jika Anda tidak memiliki sesi aktif, lihat [Masuk menggunakan AWS CLI](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso) petunjuk.

1. Buka terminal atau jendela prompt perintah dan arahkan ke direktori proyek Anda`getstarted`.

1. Untuk membangun proyek Anda, jalankan perintah berikut:

   ```
   mvn clean package
   ```

1. Untuk menjalankan aplikasi, jalankan perintah berikut:

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

Setelah Anda melihat file, hapus objek, dan kemudian hapus ember.

#### Berhasil
<a name="GetStartedSuccessJava"></a>

Jika proyek Maven Anda dibangun dan berjalan tanpa kesalahan, maka selamat\$1 Anda telah berhasil membangun aplikasi Java pertama Anda menggunakan SDK for Java 2.x.

#### Pembersihan
<a name="GetStartedCleanupJava"></a>

Untuk membersihkan sumber daya yang Anda buat selama tutorial ini, hapus folder proyek`getstarted`.

## Meninjau dokumentasi AWS SDK for Java 2.x
<a name="ProgrammingWithJavaUseDoc"></a>

[Panduan AWS SDK for Java 2.x Pengembang](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) mencakup semua aspek SDK di semua Layanan AWS aspek. Kami menyarankan Anda meninjau topik-topik berikut:
+ [Migrasi dari versi 1.x ke 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) - Termasuk penjelasan rinci tentang perbedaan antara 1.x dan 2.x. Topik ini juga berisi petunjuk tentang cara menggunakan kedua versi utama side-by-side.
+ [Panduan DynamoDB untuk Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb.html) SDK - Menunjukkan cara melakukan operasi DynamoDB dasar: membuat tabel, memanipulasi item, dan mengambil item. Contoh-contoh ini menggunakan antarmuka tingkat rendah. Java memiliki beberapa antarmuka, seperti yang dijelaskan di bagian berikut: [Antarmuka yang didukung](#JavaInterfaces)

**Tip**  
Setelah Anda meninjau topik ini, tandai [Referensi AWS SDK for Java 2.x API](https://sdk.amazonaws.com/java/api/latest/). Ini mencakup semua Layanan AWS, dan kami menyarankan Anda menggunakannya sebagai referensi API utama Anda.

## Antarmuka yang didukung
<a name="JavaInterfaces"></a>

 AWS SDK for Java 2.x Mendukung antarmuka berikut, tergantung pada tingkat abstraksi yang Anda inginkan.

**Topics**
+ [Antarmuka tingkat rendah](#LowLevelInterface)
+ [Antarmuka tingkat tinggi](#HighLevelInterface)
+ [Antarmuka dokumen](#DocumentInterface)
+ [Membandingkan antarmuka dengan contoh `Query`](#CompareJavaInterfacesQueryEx)

### Antarmuka tingkat rendah
<a name="LowLevelInterface"></a>

Antarmuka tingkat rendah menyediakan one-to-one pemetaan ke API layanan yang mendasarinya. Setiap DynamoDB API tersedia melalui antarmuka ini. Ini berarti bahwa antarmuka tingkat rendah dapat menyediakan fungsionalitas yang lengkap, tetapi seringkali lebih bertele-tele dan kompleks untuk digunakan. Misalnya, Anda harus menggunakan `.s()` fungsi untuk menahan string dan `.n()` fungsi untuk menahan angka. Contoh berikut [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)menyisipkan item menggunakan antarmuka tingkat rendah.

```
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)");
    }
}
```

### Antarmuka tingkat tinggi
<a name="HighLevelInterface"></a>

Antarmuka tingkat tinggi di dalam disebut DynamoDB Enhanced Client. AWS SDK for Java 2.x Antarmuka ini memberikan pengalaman penulisan kode yang lebih idiomatis.

Klien yang disempurnakan menawarkan cara untuk memetakan antara kelas data sisi klien dan tabel DynamoDB yang dirancang untuk menyimpan data tersebut. Anda menentukan hubungan antara tabel dan kelas model yang sesuai dalam kode Anda. Kemudian, Anda dapat mengandalkan SDK untuk mengelola manipulasi tipe data. *Untuk informasi selengkapnya tentang klien yang disempurnakan, lihat [DynamoDB API klien yang disempurnakan](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) di AWS SDK for Java 2.x Panduan Pengembang.*

Contoh berikut [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)menggunakan antarmuka tingkat tinggi. Dalam contoh ini, yang `DynamoDbBean` bernama `YourItem` menciptakan a `TableSchema` yang memungkinkan penggunaan langsungnya sebagai input untuk `putItem()` panggilan.

```
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 untuk Java 1.x memiliki antarmuka tingkat tinggi sendiri, yang sering disebut oleh kelas utamanya. `DynamoDBMapper` AWS SDK for Java 2.x Ini diterbitkan dalam paket terpisah (dan artefak Maven) bernama. `software.amazon.awssdk.enhanced.dynamodb` Java 2.x SDK sering disebut oleh kelas utamanya. `DynamoDbEnhancedClient`

#### Antarmuka tingkat tinggi menggunakan kelas data yang tidak dapat diubah
<a name="HighLevelInterfaceImmutableDataClasses"></a>

Fitur pemetaan API klien yang disempurnakan DynamoDB juga berfungsi dengan kelas data yang tidak dapat diubah. Kelas yang tidak dapat diubah hanya memiliki getter dan memerlukan kelas pembangun yang digunakan SDK untuk membuat instance kelas. Kekekalan di Jawa adalah gaya yang umum digunakan yang dapat digunakan pengembang untuk membuat kelas yang tidak memiliki efek samping. Kelas-kelas ini lebih dapat diprediksi dalam perilaku mereka dalam aplikasi multi-threaded yang kompleks. Alih-alih menggunakan `@DynamoDbBean` anotasi seperti yang ditunjukkan dalam[High-level interface example](#highleveleg), kelas yang tidak dapat diubah menggunakan `@DynamoDbImmutable` anotasi, yang mengambil kelas pembangun sebagai inputnya.

Contoh berikut mengambil kelas builder `DynamoDbEnhancedClientImmutablePutItem` sebagai masukan untuk membuat skema tabel. Contoh kemudian memberikan skema sebagai input untuk panggilan [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)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 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)");
    }
}
```

Contoh berikut menunjukkan kelas data yang tidak dapat diubah.

```
@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); }
    }
}
```

#### Antarmuka tingkat tinggi menggunakan kelas data yang tidak dapat diubah dan pustaka generasi boilerplate pihak ketiga
<a name="ImmutableDataClassesThirdPartyBoilerplateGenLib"></a>

Kelas data yang tidak dapat diubah (ditunjukkan pada contoh sebelumnya) memerlukan beberapa kode boilerplate. Misalnya, logika getter dan setter pada kelas data, selain kelas. `Builder` Perpustakaan pihak ketiga, seperti [Project Lombok](https://projectlombok.org/), dapat membantu Anda menghasilkan jenis kode boilerplate tersebut. Mengurangi sebagian besar kode boilerplate membantu Anda membatasi jumlah kode yang diperlukan untuk bekerja dengan kelas data yang tidak dapat diubah dan SDK. AWS Ini selanjutnya menghasilkan peningkatan produktivitas dan keterbacaan kode Anda. Untuk informasi selengkapnya, lihat [Menggunakan pustaka pihak ketiga, seperti Lombok](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-use-immut.html#ddb-en-client-use-immut-lombok) di Panduan *AWS SDK for Java 2.x Pengembang*.

Contoh berikut menunjukkan bagaimana Project Lombok menyederhanakan kode yang diperlukan untuk menggunakan DynamoDB ditingkatkan client 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)");
    }
}
```

Contoh berikut menunjukkan objek data yang tidak berubah dari kelas data yang tidak dapat diubah.

```
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`Kelas menggunakan anotasi berikut yang Project Lombok dan AWS SDK menyediakan:
+ [@Builder](https://projectlombok.org/features/Builder) — Menghasilkan pembangun kompleks APIs untuk kelas data yang disediakan Project Lombok.
+ [@ DynamoDbImmutable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/DynamoDbImmutable.html) — Mengidentifikasi `DynamoDbImmutable` kelas sebagai anotasi entitas DynamoDB yang dapat dipetakan yang disediakan SDK. AWS 
+ [@Value](https://projectlombok.org/features/Value) — Varian yang tidak dapat diubah dari. `@Data` Secara default, semua bidang dibuat pribadi dan final, dan setter tidak dibuat. Proyek Lombok memberikan anotasi ini.

### Antarmuka dokumen
<a name="DocumentInterface"></a>

Antarmuka AWS SDK for Java 2.x Dokumen menghindari kebutuhan untuk menentukan deskriptor tipe data. Jenis data yang tersirat oleh semantik data itu sendiri. Antarmuka Dokumen ini mirip dengan antarmuka AWS SDK untuk Java 1.x, Dokumen, tetapi dengan antarmuka yang didesain ulang.

Berikut ini [Document interface example](#DocInterfaceEg) menunjukkan `PutItem` panggilan yang dinyatakan menggunakan antarmuka Dokumen. Contoh ini juga menggunakan EnhancedDocument. Untuk menjalankan perintah terhadap tabel DynamoDB menggunakan API dokumen yang disempurnakan, Anda harus terlebih dahulu mengaitkan tabel dengan skema tabel dokumen Anda untuk membuat objek sumber daya. `DynamoDBTable` Pembuat skema tabel Dokumen memerlukan kunci indeks utama dan penyedia konverter atribut.

Anda dapat menggunakan `AttributeConverterProvider.defaultProvider()` untuk mengonversi atribut dokumen dari tipe default. Anda dapat mengubah keseluruhan perilaku default dengan `AttributeConverterProvider` implementasi kustom. Anda juga dapat mengubah konverter untuk satu atribut. [Panduan Referensi AWS SDKs and Tools](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) memberikan rincian dan contoh lebih lanjut tentang cara menggunakan konverter khusus. Penggunaan utamanya adalah untuk atribut kelas domain Anda yang tidak memiliki konverter default yang tersedia. Menggunakan konverter khusus, Anda dapat memberikan SDK dengan informasi yang diperlukan untuk menulis atau membaca ke 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)");
    }

}
```

Untuk mengonversi dokumen JSON ke dan dari tipe data Amazon DynamoDB asli, Anda dapat menggunakan metode utilitas berikut:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String))— Membuat EnhancedDocument instance baru dari string JSON.
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson())— Membuat representasi string JSON dari dokumen yang dapat Anda gunakan dalam aplikasi Anda seperti objek JSON lainnya.

### Membandingkan antarmuka dengan contoh `Query`
<a name="CompareJavaInterfacesQueryEx"></a>

Bagian ini menunjukkan [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)panggilan yang sama yang diekspresikan menggunakan berbagai antarmuka. Untuk menyempurnakan hasil kueri ini, perhatikan hal berikut:
+ DynamoDB menargetkan satu nilai kunci partisi tertentu, jadi Anda harus menentukan kunci partisi sepenuhnya.
+ Untuk memiliki item keranjang target kueri saja, kunci pengurutan memiliki ekspresi kondisi kunci yang menggunakan`begins_with`.
+ Kami gunakan `limit()` untuk membatasi kueri hingga maksimum 100 item yang dikembalikan.
+ Kami mengatur `scanIndexForward` ke false. Hasilnya dikembalikan dalam urutan UTF-8 byte, yang biasanya berarti item keranjang dengan jumlah terendah dikembalikan terlebih dahulu. Dengan menyetel `scanIndexForward` ke false, kami membalikkan pesanan dan item keranjang dengan angka tertinggi dikembalikan terlebih dahulu.
+ Kami menerapkan filter untuk menghapus hasil apa pun yang tidak sesuai dengan kriteria. Data yang difilter menghabiskan kapasitas baca apakah item tersebut cocok dengan filter.

**Example `Query`menggunakan antarmuka tingkat rendah**  
Contoh berikut query tabel bernama `YourTableName` menggunakan. `keyConditionExpression` Ini membatasi kueri ke nilai kunci partisi tertentu dan mengurutkan nilai kunci yang dimulai dengan nilai awalan tertentu. Kondisi utama ini membatasi jumlah data yang dibaca dari DynamoDB. Akhirnya, kueri menerapkan filter pada data yang diambil dari DynamoDB menggunakan file. `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"));
    }
}
```

**Example `Query`menggunakan antarmuka Dokumen**  
Contoh berikut query tabel bernama `YourTableName` menggunakan antarmuka Dokumen.  

```
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"));

    }
}
```

**Example `Query`menggunakan antarmuka tingkat tinggi**  
Contoh berikut menanyakan tabel bernama `YourTableName` menggunakan DynamoDB API klien yang disempurnakan.  

```
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;
        }
    }
}
```
**Antarmuka tingkat tinggi menggunakan kelas data yang tidak dapat diubah**  
Saat Anda melakukan a `Query` dengan kelas data abadi tingkat tinggi, kodenya sama dengan contoh antarmuka tingkat tinggi kecuali untuk konstruksi kelas entitas atau. `YourItem` `YourImmutableItem` Untuk informasi lebih lanjut, lihat [PutItem](#HighLevelImmutableDataClassEg)contoh.
**Antarmuka tingkat tinggi menggunakan kelas data yang tidak dapat diubah dan pustaka generasi boilerplate pihak ketiga**  
Saat Anda melakukan a `Query` dengan kelas data abadi tingkat tinggi, kodenya sama dengan contoh antarmuka tingkat tinggi kecuali untuk konstruksi kelas entitas atau. `YourItem` `YourImmutableLombokItem` Untuk informasi lebih lanjut, lihat [PutItem](#HighLevelImmutableDataClassEg)contoh.

## Contoh kode tambahan
<a name="AdditionalCodeEx"></a>

Untuk contoh tambahan tentang cara menggunakan DynamoDB dengan SDK for Java 2.x, lihat repositori contoh kode berikut:
+ [Contoh kode AWS aksi tunggal resmi](https://docs.aws.amazon.com/code-library/latest/ug/java_2_dynamodb_code_examples.html)
+ [Contoh kode aksi tunggal yang dikelola komunitas](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)
+ [Contoh kode AWS berorientasi skenario resmi](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)

## Pemrograman sinkron dan asinkron
<a name="SyncAsyncProgramming"></a>

 AWS SDK for Java 2.x Ini menyediakan klien *sinkron* dan *asinkron* untuk, Layanan AWS seperti DynamoDB.

`DynamoDbEnhancedClient`Kelas `DynamoDbClient` dan menyediakan metode sinkron yang memblokir eksekusi thread Anda hingga klien menerima respons dari layanan. Klien ini adalah cara paling mudah untuk berinteraksi dengan DynamoDB jika Anda tidak memerlukan operasi asinkron.

`DynamoDbEnhancedAsyncClient`Kelas `DynamoDbAsyncClient` and menyediakan metode asinkron yang segera kembali, dan memberikan kontrol kembali ke utas panggilan tanpa menunggu respons. Klien non-pemblokiran memiliki keuntungan yang digunakannya untuk konkurensi tinggi di beberapa utas, yang menyediakan penanganan permintaan I/O yang efisien dengan sumber daya komputasi minimal. Ini meningkatkan throughput dan daya tanggap.

 AWS SDK for Java 2.x Menggunakan dukungan asli untuk non-blocking I/O. AWS SDK untuk Java 1.x harus mensimulasikan non-blocking I/O.

Metode sinkron kembali sebelum respons tersedia, jadi Anda memerlukan cara untuk mendapatkan respons saat sudah siap. Metode asinkron dalam AWS SDK untuk Java mengembalikan [https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)objek yang berisi hasil operasi asinkron di masa depan. Ketika Anda memanggil `get()` atau `join()` pada `CompletableFuture` objek-objek ini, kode Anda memblokir sampai hasilnya tersedia. Jika Anda memanggil ini pada saat yang sama saat Anda membuat permintaan, maka perilakunya mirip dengan panggilan sinkron biasa.

*Untuk informasi selengkapnya tentang pemrograman asinkron, lihat [Menggunakan pemrograman asinkron](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html) di Panduan Pengembang.AWS SDK for Java 2.x *

## Klien HTTP
<a name="HttpClients"></a>

Untuk mendukung setiap klien, ada klien HTTP yang menangani komunikasi dengan klien Layanan AWS. Anda dapat mencolokkan klien HTTP alternatif, memilih salah satu yang memiliki karakteristik yang paling sesuai dengan aplikasi Anda. Beberapa lebih ringan; beberapa memiliki lebih banyak opsi konfigurasi.

Beberapa klien HTTP hanya mendukung penggunaan sinkron, sementara yang lain hanya mendukung penggunaan asinkron. Untuk diagram alur yang dapat membantu Anda memilih klien HTTP optimal untuk beban kerja Anda, lihat [rekomendasi klien HTTP di Panduan AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html#http-clients-recommend) *Pengembang*.

Daftar berikut menyajikan beberapa kemungkinan klien HTTP:

**Topics**
+ [Klien HTTP berbasis Apache](#ApacheHttpClient)
+ [`URLConnection`berbasis HTTP klien](#URLConnHttpClient)
+ [Klien HTTP berbasis Netty](#NettyHttpClient)
+ [AWS Klien HTTP berbasis CRT](#AWSCRTHttpClient)

### Klien HTTP berbasis Apache
<a name="ApacheHttpClient"></a>

[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html)Kelas mendukung klien layanan sinkron. Ini adalah klien HTTP default untuk penggunaan sinkron. *Untuk informasi tentang mengonfigurasi `ApacheHttpClient` kelas, lihat [Mengkonfigurasi klien HTTP berbasis Apache](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-apache.html) di Panduan Pengembang.AWS SDK for Java 2.x *

### `URLConnection`berbasis HTTP klien
<a name="URLConnHttpClient"></a>

[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html)Kelas adalah pilihan lain untuk klien sinkron. Ini memuat lebih cepat daripada klien HTTP berbasis Apache, tetapi memiliki lebih sedikit fitur. Untuk informasi tentang mengonfigurasi `UrlConnectionHttpClient` kelas, lihat [Mengkonfigurasi klien HTTP URLConnection berbasis](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-url.html) di *Panduan AWS SDK for Java 2.x Pengembang*.

### Klien HTTP berbasis Netty
<a name="NettyHttpClient"></a>

`NettyNioAsyncHttpClient`Kelas mendukung klien async. Ini adalah pilihan default untuk penggunaan async. *Untuk informasi tentang mengonfigurasi `NettyNioAsyncHttpClient` kelas, lihat [Mengkonfigurasi klien HTTP berbasis Netty](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-netty.html) di Panduan Pengembang.AWS SDK for Java 2.x *

### AWS Klien HTTP berbasis CRT
<a name="AWSCRTHttpClient"></a>

Yang lebih baru `AwsCrtHttpClient` dan `AwsCrtAsyncHttpClient` kelas dari pustaka AWS Common Runtime (CRT) adalah lebih banyak opsi yang mendukung klien sinkron dan asinkron. Dibandingkan dengan klien HTTP lainnya, AWS CRT menawarkan:
+ Waktu startup SDK lebih cepat
+ Jejak memori yang lebih kecil
+ Mengurangi waktu latensi
+ Manajemen kesehatan koneksi
+ Penyeimbangan beban DNS

*Untuk informasi tentang mengonfigurasi `AwsCrtHttpClient` dan `AwsCrtAsyncHttpClient` kelas, lihat [Mengkonfigurasi klien HTTP AWS berbasis CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html) di Panduan Pengembang AWS SDK for Java 2.x .*

Klien HTTP AWS berbasis CRT bukan default karena itu akan merusak kompatibilitas mundur untuk aplikasi yang ada. Namun, untuk DynamoDB kami menyarankan Anda menggunakan klien HTTP berbasis CRT untuk penggunaan AWS sinkronisasi dan asinkron.

*Untuk pengenalan klien HTTP AWS berbasis CRT, lihat [Mengumumkan ketersediaan AWS CRT HTTP Client di Blog Alat Pengembang AWS SDK for Java 2.x](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/).AWS *

## Mengkonfigurasi klien HTTP
<a name="ConfigHttpClient"></a>

Saat mengonfigurasi klien, Anda dapat memberikan berbagai opsi konfigurasi, termasuk:
+ Menyetel batas waktu untuk berbagai aspek panggilan API.
+ Mengaktifkan TCP Keep-Alive.
+ Mengontrol kebijakan coba lagi saat mengalami kesalahan.
+ Menentukan atribut [eksekusi yang dapat dimodifikasi oleh instance pencegat](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/interceptors.html) Eksekusi. Pencegat eksekusi dapat menulis kode yang mencegat eksekusi permintaan dan tanggapan API Anda. Ini memungkinkan Anda untuk melakukan tugas-tugas seperti menerbitkan metrik dan memodifikasi permintaan dalam penerbangan.
+ Menambahkan atau memanipulasi header HTTP.
+ Mengaktifkan pelacakan metrik [kinerja sisi klien](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html). Menggunakan fitur ini membantu Anda mengumpulkan metrik tentang klien layanan di aplikasi Anda dan menganalisis output di Amazon CloudWatch.
+ Menentukan layanan pelaksana alternatif yang akan digunakan untuk menjadwalkan tugas, seperti percobaan ulang async dan tugas batas waktu.

Anda mengontrol konfigurasi dengan menyediakan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html)objek ke `Builder` kelas klien layanan. Anda akan melihat ini di beberapa contoh kode di bagian berikut.

`ClientOverrideConfiguration`Ini menyediakan pilihan konfigurasi standar. Klien HTTP pluggable yang berbeda memiliki kemungkinan konfigurasi khusus implementasi juga.

**Topics**
+ [Konfigurasi waktu habis](#TimeoutConfig)
+ [RetryMode](#RetryMode)
+ [DefaultsMode](#DefaultsMode)
+ [Konfigurasi Keep-Alive](#KeepAliveConfig)

### Konfigurasi waktu habis
<a name="TimeoutConfig"></a>

Anda dapat menyesuaikan konfigurasi klien untuk mengontrol berbagai batas waktu yang terkait dengan panggilan layanan. DynamoDB memberikan latensi yang lebih rendah dibandingkan dengan yang lain. Layanan AWS Oleh karena itu, Anda mungkin ingin menyesuaikan properti ini untuk menurunkan nilai batas waktu sehingga Anda dapat gagal dengan cepat jika ada masalah jaringan.

Anda dapat menyesuaikan perilaku terkait latensi menggunakan `ClientOverrideConfiguration` pada klien DynamoDB atau dengan mengubah opsi konfigurasi terperinci pada implementasi klien HTTP yang mendasarinya.

Anda dapat mengonfigurasi properti berdampak berikut menggunakan: `ClientOverrideConfiguration`
+ `apiCallAttemptTimeout`— Jumlah waktu untuk menunggu satu upaya untuk menyelesaikan permintaan HTTP sebelum menyerah dan waktu habis.
+ `apiCallTimeout`— Jumlah waktu yang dimiliki klien untuk sepenuhnya menjalankan panggilan API. Ini termasuk eksekusi penangan permintaan yang terdiri dari semua permintaan HTTP, termasuk percobaan ulang.

 AWS SDK for Java 2.x Ini memberikan [nilai default](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) untuk beberapa opsi batas waktu, seperti batas waktu koneksi dan batas waktu soket. SDK tidak memberikan nilai default untuk batas waktu panggilan API atau batas waktu percobaan panggilan API individual. Jika batas waktu ini tidak disetel dalam`ClientOverrideConfiguration`, maka SDK menggunakan nilai batas waktu soket sebagai gantinya untuk batas waktu panggilan API secara keseluruhan. Batas waktu soket memiliki nilai default 30 detik.

### RetryMode
<a name="RetryMode"></a>

Konfigurasi lain yang terkait dengan konfigurasi batas waktu yang harus Anda pertimbangkan adalah objek `RetryMode` konfigurasi. Objek konfigurasi ini berisi kumpulan perilaku coba lagi.

SDK for Java 2.x mendukung mode coba lagi berikut:
+ `legacy`— Mode coba lagi default jika Anda tidak mengubahnya secara eksplisit. Mode coba lagi ini khusus untuk Java SDK. Ini ditandai dengan hingga tiga percobaan ulang, atau lebih untuk layanan seperti DynamoDB, yang memiliki hingga delapan percobaan ulang.
+ `standard`— Dinamakan “standar” karena lebih konsisten dengan yang lain AWS SDKs. Mode ini menunggu jumlah waktu acak mulai dari 0ms hingga 1.000 ms untuk percobaan ulang pertama. Jika percobaan lagi diperlukan, maka mode ini mengambil waktu acak lain dari 0ms menjadi 1.000 ms dan mengalikannya dengan dua. Jika percobaan ulang tambahan diperlukan, maka ia melakukan pengambilan acak yang sama dikalikan empat, dan seterusnya. Setiap penantian dibatasi pada 20 detik. Mode ini melakukan percobaan ulang pada kondisi kegagalan yang lebih terdeteksi daripada `legacy` mode. Untuk DynamoDB, ia melakukan hingga tiga upaya maksimal total kecuali Anda mengganti dengan. [numRetries](#numRetries)
+ `adaptive`— Dibangun pada `standard` mode dan secara dinamis membatasi tingkat AWS permintaan untuk memaksimalkan tingkat keberhasilan. Ini dapat terjadi dengan mengorbankan latensi permintaan. Kami tidak merekomendasikan mode coba lagi adaptif ketika latensi yang dapat diprediksi penting.

Anda dapat menemukan definisi yang diperluas dari mode coba lagi ini dalam topik [perilaku Coba lagi](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) di Panduan *Referensi Alat AWS SDKs dan Alat*.

#### Coba lagi kebijakan
<a name="RetryPolicies"></a>

Semua `RetryMode` konfigurasi memiliki [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html), yang dibangun berdasarkan satu atau lebih [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html)konfigurasi. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html)Ini sangat penting untuk perilaku coba lagi implementasi klien DynamoDB SDK. Kondisi ini membatasi jumlah percobaan ulang yang dibuat SDK menggunakan algoritma token bucket. Bergantung pada mode coba lagi yang dipilih, pengecualian pembatasan mungkin atau mungkin tidak mengurangi token dari. `TokenBucket`

Ketika klien menemukan kesalahan yang dapat dicoba ulang, seperti pengecualian pembatasan atau kesalahan server sementara, SDK secara otomatis mencoba ulang permintaan tersebut. Anda dapat mengontrol berapa kali dan seberapa cepat percobaan ulang ini terjadi.

Saat mengkonfigurasi klien, Anda dapat memberikan `RetryPolicy` yang mendukung parameter berikut:
+ `numRetries`— Jumlah maksimum percobaan ulang yang harus diterapkan sebelum permintaan dianggap gagal. Nilai defaultnya adalah 8 terlepas dari mode coba lagi yang Anda gunakan.
**Awas**  
Pastikan bahwa Anda mengubah nilai default ini setelah pertimbangan.
+ `backoffStrategy`— [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html)Untuk diterapkan pada percobaan ulang, dengan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html)menjadi strategi default. Strategi ini melakukan penundaan eksponensial antara percobaan ulang tambahan berdasarkan jumlah saat ini atau percobaan ulang, penundaan dasar, dan waktu backoff maksimum. Kemudian menambahkan jitter untuk memberikan sedikit keacakan. Penundaan dasar yang digunakan dalam penundaan eksponensial adalah 25 ms terlepas dari mode coba lagi.
+ `retryCondition`— [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html)Menentukan apakah akan mencoba kembali permintaan sama sekali. Secara default, ia mencoba ulang satu set kode status HTTP tertentu dan pengecualian yang diyakini dapat dicoba ulang. Untuk sebagian besar situasi, konfigurasi default harus cukup.

Kode berikut menyediakan kebijakan coba lagi alternatif. Ini menentukan total lima percobaan ulang (enam permintaan total). Percobaan ulang pertama harus dilakukan setelah penundaan sekitar 100 ms, dengan setiap percobaan lagi tambahan menggandakan waktu itu secara eksponensial, hingga penundaan maksimum satu detik.

```
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
<a name="DefaultsMode"></a>

Properti batas waktu yang `ClientOverrideConfiguration` dan `RetryMode` tidak dikelola biasanya dikonfigurasi secara implisit dengan menentukan. `DefaultsMode`

 AWS SDK for Java 2.x (versi 2.17.102 atau yang lebih baru) memperkenalkan dukungan untuk. `DefaultsMode` Fitur ini menyediakan serangkaian nilai default untuk pengaturan umum yang dapat dikonfigurasi, seperti pengaturan komunikasi HTTP, perilaku coba lagi, pengaturan titik akhir Regional layanan, dan kemungkinan konfigurasi terkait SDK apa pun. Saat Anda menggunakan fitur ini, Anda bisa mendapatkan default konfigurasi baru yang disesuaikan dengan skenario penggunaan umum.

Mode default distandarisasi di semua. AWS SDKs SDK for Java 2.x mendukung mode default berikut:
+ `legacy`— Menyediakan pengaturan default yang bervariasi menurut AWS SDK dan yang ada sebelum `DefaultsMode` dibuat.
+ `standard`— Menyediakan pengaturan default yang tidak dioptimalkan untuk sebagian besar skenario.
+ `in-region`— Dibangun pada mode standar dan termasuk pengaturan yang disesuaikan untuk aplikasi yang memanggil Layanan AWS dari dalam yang sama. Wilayah AWS
+ `cross-region`— Dibangun pada mode standar dan termasuk pengaturan dengan batas waktu tinggi untuk aplikasi yang memanggil Layanan AWS di Wilayah yang berbeda.
+ `mobile`— Dibangun pada mode standar dan mencakup pengaturan dengan batas waktu tinggi yang disesuaikan untuk aplikasi seluler dengan latensi lebih tinggi.
+ `auto`— Dibangun pada mode standar dan termasuk fitur eksperimental. SDK mencoba menemukan lingkungan runtime untuk menentukan pengaturan yang sesuai secara otomatis. Deteksi otomatis berbasis heuristik dan tidak memberikan akurasi 100%. Jika lingkungan runtime tidak dapat ditentukan, maka mode standar digunakan. Deteksi otomatis mungkin menanyakan [metadata Instance dan data pengguna](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html), yang mungkin memperkenalkan latensi. Jika latensi startup sangat penting untuk aplikasi Anda, sebaiknya pilih yang eksplisit`DefaultsMode`.

Anda dapat mengonfigurasi mode default dengan cara berikut:
+ Langsung pada klien, melalui`AwsClientBuilder.Builder#defaultsMode(DefaultsMode)`.
+ Pada profil konfigurasi, melalui properti file `defaults_mode` profil.
+ Secara global, melalui properti `aws.defaultsMode` sistem.
+ Secara global, melalui variabel `AWS_DEFAULTS_MODE` lingkungan.

**catatan**  
Untuk mode apa pun selain`legacy`, nilai default yang dijual dapat berubah seiring berkembangnya praktik terbaik. Oleh karena itu, jika Anda menggunakan mode selain`legacy`, maka kami mendorong Anda untuk melakukan pengujian saat memutakhirkan SDK.

[Konfigurasi Smart default](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) di *AWS SDKs and Tools Reference Guide* menyediakan daftar properti konfigurasi dan nilai defaultnya dalam mode default yang berbeda.

Anda memilih nilai mode default berdasarkan karakteristik aplikasi Anda dan interaksi dengan Layanan AWS aplikasi.

Nilai-nilai ini dikonfigurasi dengan berbagai pilihan Layanan AWS dalam pikiran. Untuk penerapan DynamoDB tipikal di mana tabel dan aplikasi DynamoDB Anda digunakan dalam satu Wilayah, mode default `in-region` paling relevan di antara mode default. `standard`

**Example Konfigurasi klien DynamoDB SDK disetel untuk panggilan latensi rendah**  
Contoh berikut menyesuaikan batas waktu ke nilai yang lebih rendah untuk panggilan DynamoDB latensi rendah yang diharapkan.  

```
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder()
    .defaultsMode(DefaultsMode.IN_REGION)
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder())
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallTimeout(Duration.ofSeconds(3))
        .apiCallAttemptTimeout(Duration.ofMillis(500))
        .build())
    .build();
```
Implementasi klien HTTP individual dapat memberi Anda kontrol yang lebih terperinci atas batas waktu dan perilaku penggunaan koneksi. Misalnya, untuk klien AWS berbasis CRT, Anda dapat mengaktifkan`ConnectionHealthConfiguration`, yang memungkinkan klien untuk secara aktif memantau kesehatan koneksi yang digunakan. Untuk informasi selengkapnya, lihat [Konfigurasi lanjutan klien HTTP AWS berbasis CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html#configuring-the-crt-based-http-client) di Panduan *AWS SDK for Java 2.x Pengembang*.

### Konfigurasi Keep-Alive
<a name="KeepAliveConfig"></a>

Mengaktifkan keep-alive dapat mengurangi latensi dengan menggunakan kembali koneksi. Ada dua jenis keep-alive: HTTP Keep-Alive dan TCP Keep-Alive.
+ HTTP Keep-Alive mencoba mempertahankan koneksi HTTPS antara klien dan server sehingga permintaan selanjutnya dapat menggunakan kembali koneksi tersebut. Ini melewatkan otentikasi HTTPS kelas berat pada permintaan selanjutnya. HTTP Keep-Alive diaktifkan secara default pada semua klien.
+ TCP Keep-Alive meminta agar sistem operasi yang mendasarinya mengirimkan paket kecil melalui koneksi soket untuk memberikan jaminan ekstra bahwa soket tetap hidup dan segera mendeteksi tetesan apa pun. Ini memastikan bahwa permintaan selanjutnya tidak akan menghabiskan waktu mencoba menggunakan soket yang terjatuh. Secara default, TCP Keep-Alive dinonaktifkan pada semua klien. Contoh kode berikut menunjukkan cara mengaktifkannya pada setiap klien HTTP. Ketika diaktifkan untuk semua klien HTTP berbasis non-CRT, mekanisme Keep-Alive yang sebenarnya bergantung pada sistem operasi. Oleh karena itu, Anda harus mengonfigurasi nilai TCP Keep-Alive tambahan, seperti batas waktu dan jumlah paket, melalui sistem operasi. Anda dapat melakukan ini menggunakan `sysctl` di Linux atau macOS, atau menggunakan nilai registri di Windows.

**Example untuk mengaktifkan TCP Keep-Alive pada klien HTTP berbasis Apache**  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**`URLConnection`berbasis HTTP klien**  
Setiap klien sinkron yang menggunakan klien HTTP `URLConnection` berbasis [https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html)tidak memiliki [mekanisme](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html) untuk mengaktifkan keep-alive.

**Example untuk mengaktifkan TCP Keep-Alive pada klien HTTP berbasis Netty**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Example untuk mengaktifkan TCP Keep-Alive pada klien HTTP berbasis CRT AWS**  
Dengan klien HTTP AWS berbasis CRT, Anda dapat mengaktifkan TCP keep-alive dan mengontrol durasinya.  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(AwsCrtHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```
Saat menggunakan klien DynamoDB asinkron, Anda dapat mengaktifkan TCP Keep-Alive seperti yang ditunjukkan pada kode berikut.  

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

## Penanganan kesalahan
<a name="JavaErrorHandling"></a>

Ketika datang ke penanganan pengecualian, AWS SDK for Java 2.x menggunakan pengecualian runtime (tidak dicentang).

Pengecualian dasar, yang mencakup semua pengecualian SDK, adalah [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html), yang meluas dari Java tidak dicentang. `RuntimeException` Jika Anda menangkap ini, Anda akan menangkap semua pengecualian yang dilemparkan SDK.

`SdkServiceException`memiliki subclass yang disebut [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html). Subkelas ini menunjukkan masalah apa pun dalam komunikasi dengan. Layanan AWS Ini memiliki subclass yang disebut [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html), yang menunjukkan masalah dalam komunikasi dengan DynamoDB. Jika Anda menangkap ini, Anda akan menangkap semua pengecualian yang terkait dengan DynamoDB, tetapi tidak ada pengecualian SDK lainnya.

Ada [jenis pengecualian](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html) yang lebih spesifik di bawah`DynamoDbException`. Beberapa jenis pengecualian ini berlaku untuk operasi bidang kontrol seperti. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html) Lainnya berlaku untuk operasi data-plane. Berikut ini adalah contoh pengecualian bidang data umum:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html)— Anda menentukan kondisi dalam permintaan yang dievaluasi menjadi false. Misalnya, Anda mungkin telah mencoba melakukan pembaruan bersyarat pada suatu item, tetapi nilai atribut sebenarnya tidak cocok dengan nilai yang diharapkan dalam kondisi yang dihadapi. Permintaan yang gagal dengan cara ini tidak dicoba lagi.

Situasi lain tidak memiliki pengecualian khusus yang ditentukan. Misalnya, ketika permintaan Anda dibatasi, spesifik `ProvisionedThroughputExceededException` mungkin dilemparkan, sementara dalam kasus lain permintaan yang lebih umum `DynamoDbException` dilemparkan. Dalam kedua kasus tersebut, Anda dapat menentukan apakah pelambatan menyebabkan pengecualian dengan memeriksa apakah `isThrottlingException()` pengembalian. `true`

Tergantung pada kebutuhan aplikasi Anda, Anda dapat menangkap semua `AwsServiceException` atau `DynamoDbException` instance. Namun, Anda sering membutuhkan perilaku yang berbeda dalam situasi yang berbeda. Logika untuk menangani kegagalan pemeriksaan kondisi berbeda dari itu untuk menangani pelambatan. Tentukan jalur luar biasa mana yang ingin Anda tangani dan pastikan untuk menguji jalur alternatif. Ini membantu Anda memastikan bahwa Anda dapat menangani semua skenario yang relevan.

Untuk daftar kesalahan umum yang mungkin Anda temui, lihat[Penanganan kesalahan dengan DynamoDB](Programming.Errors.md). Lihat juga [Kesalahan Umum di Referensi](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html) *Amazon DynamoDB* API. Referensi API juga menyediakan kesalahan yang tepat untuk setiap operasi API, seperti untuk [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)operasi. Untuk informasi tentang menangani pengecualian, lihat [Penanganan pengecualian untuk](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/handling-exceptions.html) *Panduan AWS SDK for Java 2.x Pengembang*. AWS SDK for Java 2.x

## AWS ID permintaan
<a name="JavaRequestID"></a>

Setiap permintaan menyertakan ID permintaan, yang dapat berguna untuk ditarik jika Anda bekerja dengan AWS Dukungan untuk mendiagnosis masalah. Setiap pengecualian yang berasal dari `SdkServiceException` memiliki [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId())metode yang tersedia untuk mengambil ID permintaan.

## Pencatatan log
<a name="JavaLogging"></a>

Menggunakan logging asalkan SDK menyediakan dapat berguna baik untuk menangkap pesan penting dari pustaka klien dan untuk tujuan debugging yang lebih mendalam. Logger bersifat hierarkis dan SDK digunakan `software.amazon.awssdk` sebagai root logger-nya. Anda dapat mengkonfigurasi level dengan salah satu dari`TRACE`,`DEBUG`,`INFO`,`WARN`,`ERROR`,`ALL`, atau`OFF`. Level yang dikonfigurasi berlaku untuk logger itu dan turun ke hierarki logger.

Untuk logging nya, AWS SDK for Java 2.x menggunakan Simple Logging Façade untuk Java (SLF4J). Ini bertindak sebagai lapisan abstraksi di sekitar logger lain, dan Anda dapat menggunakannya untuk mencolokkan logger yang Anda inginkan. Untuk petunjuk tentang memasukkan logger, lihat manual [pengguna SLF4 J](https://www.slf4j.org/manual.html).

Setiap logger memiliki perilaku tertentu. Secara default, logger Log4j 2.x membuat`ConsoleAppender`, yang menambahkan peristiwa log ke `System.out` dan default ke tingkat log. `ERROR`

 SimpleLogger Logger yang disertakan dalam output SLF4 J secara default ke `System.err` dan default ke tingkat log. `INFO`

Sebaiknya Anda mengatur level `WARN` untuk setiap penerapan produksi `software.amazon.awssdk` untuk menangkap pesan penting apa pun dari pustaka klien SDK sambil membatasi kuantitas keluaran.

[Jika SLF4 J tidak dapat menemukan logger yang didukung di jalur kelas (tidak ada pengikatan SLF4 J), maka defaultnya adalah implementasi tanpa operasi.](https://www.slf4j.org/codes.html#noProviders) Implementasi ini menghasilkan logging pesan untuk `System.err` menjelaskan bahwa SLF4 J tidak dapat menemukan implementasi logger di classpath. Untuk mencegah situasi ini, Anda harus menambahkan implementasi logger. Untuk melakukan ini, Anda dapat menambahkan ketergantungan di Apache Maven Anda `pom.xml` pada artefak, seperti atau. `org.slf4j.slf4j-simple` `org.apache.logging.log4j.log4j-slf4j2-imp`

*Untuk informasi tentang cara mengonfigurasi logging di SDK, termasuk menambahkan dependensi logging ke konfigurasi aplikasi Anda, lihat [Logging dengan SDK for Java 2.x di](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/logging-slf4j.html) Panduan Pengembang.AWS SDK untuk Java *

Konfigurasi berikut dalam `Log4j2.xml` file menunjukkan cara menyesuaikan perilaku logging jika Anda menggunakan logger Apache Log4j 2. Konfigurasi ini menetapkan level root logger ke`WARN`. Semua logger dalam hierarki mewarisi level log ini, termasuk logger. `software.amazon.awssdk`

Secara default, output masuk ke`System.out`. Dalam contoh berikut, kita masih mengganti appender Log4j keluaran default untuk menerapkan log4j yang disesuaikan. `PatternLayout`

**Contoh file `Log4j2.xml` konfigurasi**  
Konfigurasi berikut mencatat pesan ke konsol di `WARN` tingkat `ERROR` dan untuk semua hierarki logger.

```
<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 minta pencatatan ID
<a name="JavaReqIDLogging"></a>

Ketika terjadi kesalahan, Anda dapat menemukan permintaan IDs dalam pengecualian. Namun, jika Anda menginginkan permintaan IDs untuk permintaan yang tidak menghasilkan pengecualian, Anda dapat menggunakan logging.

Permintaan keluaran `software.amazon.awssdk.request` logger IDs di tingkat tersebut. `DEBUG` Contoh berikut memperluas sebelumnya [configuration example](#Log4j2ConfigEg) untuk menjaga level root logger pada`ERROR`, level at`WARN`, dan level at. `software.amazon.awssdk` `software.amazon.awssdk.request` `DEBUG` Menyetel level ini membantu menangkap permintaan IDs dan detail terkait permintaan lainnya, seperti titik akhir dan kode status.

```
<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>
```

Berikut adalah contoh output log:

```
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
```

## Paginasi
<a name="JavaPagination"></a>

Beberapa permintaan, seperti [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)dan [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html), membatasi ukuran data yang dikembalikan pada satu permintaan dan mengharuskan Anda membuat permintaan berulang untuk menarik halaman berikutnya.

Anda dapat mengontrol jumlah maksimum item untuk dibaca untuk setiap halaman dengan `Limit` parameter. Misalnya, Anda dapat menggunakan `Limit` parameter untuk mengambil hanya 10 item terakhir. Batas ini menentukan berapa banyak item untuk membaca dari tabel sebelum penyaringan diterapkan. Jika Anda menginginkan tepat 10 item setelah pemfilteran, tidak ada cara untuk menentukannya. Anda hanya dapat mengontrol jumlah yang telah difilter sebelumnya dan memeriksa sisi klien saat Anda benar-benar mengambil 10 item. Terlepas dari batasnya, respons selalu memiliki ukuran maksimum 1 MB.

A `LastEvaluatedKey` mungkin disertakan dalam respons API. Ini menunjukkan bahwa respons berakhir karena mencapai batas hitungan atau batas ukuran. Kunci ini adalah kunci terakhir yang dievaluasi untuk respons itu. Dengan berinteraksi langsung dengan API, Anda dapat mengambil ini `LastEvaluatedKey` dan meneruskannya ke panggilan tindak lanjut `ExclusiveStartKey` untuk membaca potongan berikutnya dari titik awal itu. Jika no `LastEvaluatedKey` dikembalikan, itu berarti tidak ada lagi item yang cocok dengan panggilan `Scan` API `Query` atau.

Contoh berikut menggunakan antarmuka tingkat rendah untuk membatasi item hingga 100 berdasarkan `keyConditionExpression` parameter.

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

Ini AWS SDK for Java 2.x dapat menyederhanakan interaksi ini dengan DynamoDB dengan menyediakan metode pagination otomatis yang membuat beberapa panggilan layanan untuk secara otomatis mendapatkan halaman hasil berikutnya untuk Anda. Ini menyederhanakan kode Anda, tetapi menghilangkan beberapa kontrol penggunaan sumber daya yang akan Anda simpan dengan membaca halaman secara manual.

Dengan menggunakan `Iterable` metode yang tersedia di klien DynamoDB, [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest))seperti [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest))dan, SDK menangani pagination. Jenis pengembalian metode ini adalah iterable khusus yang dapat Anda gunakan untuk mengulangi semua halaman. SDK secara internal menangani panggilan layanan untuk Anda. Menggunakan Java Stream API, Anda dapat menangani hasil `QueryPaginator` seperti yang ditunjukkan pada contoh berikut.

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

## Anotasi kelas data
<a name="JavaDataClassAnnotation"></a>

Java SDK menyediakan beberapa anotasi yang dapat Anda masukkan pada atribut kelas data Anda. Anotasi ini memengaruhi cara SDK berinteraksi dengan atribut. Dengan menambahkan anotasi, Anda dapat memiliki atribut yang berperilaku sebagai penghitung atom implisit, mempertahankan nilai stempel waktu yang dibuat secara otomatis, atau melacak nomor versi item. Untuk informasi selengkapnya, lihat [Anotasi kelas data](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html).

# Penanganan kesalahan dengan DynamoDB
<a name="Programming.Errors"></a>

 Bagian ini menjelaskan kesalahan runtime dan cara menanganinya. Kode dan pesan kesalahan yang khusus untuk Amazon DynamoDB juga dijelaskan dalam bagian ini. Untuk daftar kesalahan umum yang berlaku untuk semua AWS layanan, lihat [Manajemen Akses](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html)

**Topics**
+ [Komponen kesalahan](#Programming.Errors.Components)
+ [Kesalahan transaksional](#Programming.Errors.TransactionalErrors)
+ [Pesan dan kode kesalahan](#Programming.Errors.MessagesAndCodes)
+ [Penanganan kesalahan dalam aplikasi Anda](#Programming.Errors.Handling)
+ [Percobaan ulang kesalahan dan penundaan eksponensial](#Programming.Errors.RetryAndBackoff)
+ [Operasi batch dan penanganan kesalahan](#Programming.Errors.BatchOperations)

## Komponen kesalahan
<a name="Programming.Errors.Components"></a>

Ketika program Anda mengirimkan permintaan, DynamoDB mencoba untuk memprosesnya. Jika permintaan berhasil, DynamoDB akan menghasilkan kode status sukses HTTP (`200 OK`), bersama dengan hasil dari operasi yang diminta.

Jika permintaan tidak berhasil, DynamoDB menampilkan kesalahan. Setiap kesalahan memiliki tiga komponen: 
+ Kode status HTTP (seperti `400`).
+ Nama pengecualian (seperti `ResourceNotFoundException`).
+ Pesan kesalahan (seperti `Requested resource not found: Table: tablename not found`).

 AWS SDKs Jaga penyebaran kesalahan ke aplikasi Anda sehingga Anda dapat mengambil tindakan yang tepat. Misalnya, dalam program Java, Anda bisa menulis logika `try-catch` untuk menangani `ResourceNotFoundException`.

Jika Anda tidak menggunakan AWS SDK, Anda perlu mengurai konten respons tingkat rendah dari DynamoDB. Berikut ini adalah contoh respons tersebut.

```
HTTP/1.1 400 Bad Request
x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG
Content-Type: application/x-amz-json-1.0
Content-Length: 240
Date: Thu, 15 Mar 2012 23:56:23 GMT

{"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
"message":"Requested resource not found: Table: tablename not found"}
```

## Kesalahan transaksional
<a name="Programming.Errors.TransactionalErrors"></a>

Untuk informasi tentang kesalahan transaksional, lihat [Penanganan konflik transaksi di DynamoDB](transaction-apis.md#transaction-conflict-handling)

## Pesan dan kode kesalahan
<a name="Programming.Errors.MessagesAndCodes"></a>

Berikut ini adalah daftar pengecualian yang dikembalikan oleh DynamoDB, dikelompokkan berdasarkan kode status HTTP. Jika *Boleh diulang?* adalah *Ya*, Anda dapat mengirimkan permintaan yang sama lagi. Jika *Boleh diulang?* adalah *Tidak*, Anda harus memperbaiki masalah di sisi klien sebelum mengirimkan permintaan baru.

### Kode status HTTP 400
<a name="Programming.Errors.MessagesAndCodes.http400"></a>

Kode status `400` HTTP menunjukkan adanya masalah dengan permintaan Anda, seperti kegagalan autentikasi, parameter yang diperlukan tidak ada, atau melebihi throughput yang disediakan tabel. Anda harus memperbaiki masalah di aplikasi Anda sebelum mengirimkan permintaan lagi.

**AccessDeniedException **  
Pesan: *Akses ditolak.*  
Klien salah menandatangani permintaan. Jika Anda menggunakan AWS SDK, permintaan ditandatangani untuk Anda secara otomatis; jika tidak, buka [Proses penandatanganan Tanda Tangan versi 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) di *Referensi Umum AWS*.  
Boleh diulang? Tidak

**ConditionalCheckFailedException**  
Pesan: *Permintaan bersyarat gagal.*  
Anda menentukan syarat yang dievaluasi ke false. Misalnya, Anda mungkin telah mencoba melakukan pembaruan bersyarat pada suatu item, tetapi nilai atribut sebenarnya tidak cocok dengan nilai yang diharapkan dalam kondisi yang dihadapi.  
Boleh diulang? Tidak

**IncompleteSignatureException**  
Pesan: *Tanda tangan permintaan tidak sesuai dengan standar AWS .*  
Tanda tangan permintaan tidak menyertakan semua komponen yang diperlukan. Jika Anda menggunakan AWS SDK, permintaan ditandatangani untuk Anda secara otomatis; jika tidak, buka [proses penandatanganan Versi Tanda Tangan 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) di *Referensi Umum AWS*.  
Ingin mengulang? Tidak

**ItemCollectionSizeLimitExceededException**  
Pesan: *Ukuran koleksi terlampaui.*  
Untuk tabel dengan indeks sekunder lokal, sekelompok item dengan nilai kunci partisi yang sama telah melampaui batas ukuran maksimum 10 GB. Untuk informasi selengkapnya tentang kumpulan item, lihat [Kumpulan item dalam Indeks Sekunder Lokal](LSI.md#LSI.ItemCollections).  
Boleh diulang? Ya

**LimitExceededException**  
Pesan: *Terlalu banyak operasi untuk pelanggan tertentu.*  
Terlalu banyak operasi bidang kontrol secara bersamaan. Jumlah kumulatif tabel dan indeks dalam `CREATING`, `DELETING`, atau keadaan `UPDATING` tidak boleh melebihi 500.  
Boleh diulang? Ya

**MissingAuthenticationTokenException**  
Pesan: *Permintaan harus berisi ID Kunci Akses AWS yang valid (terdaftar).*  
Permintaan tidak menyertakan header otorisasi yang diperlukan, atau formatnya salah. Lihat [API tingkat rendah DynamoDB](Programming.LowLevelAPI.md).  
Boleh diulang? Tidak

**ProvisionedThroughputExceededException**  
Pesan: *Anda melampaui throughput maksimum yang diizinkan untuk sebuah tabel atau untuk satu atau beberapa indeks sekunder global. [Untuk melihat metrik kinerja untuk throughput yang disediakan vs. throughput yang dikonsumsi, buka konsol Amazon. CloudWatch](https://console.aws.amazon.com/cloudwatch/home)*  
Kesalahan mencakup daftar `ThrottlingReason` bidang yang menyediakan konteks spesifik tentang mengapa pelambatan terjadi, mengikuti format `ResourceType+OperationType+LimitType` (misalnya,`TableReadProvisionedThroughputExceeded`) dan ARN sumber daya yang terpengaruh. Ini membantu Anda mengidentifikasi sumber daya mana yang sedang dibatasi (tabel atau indeks), jenis operasi apa yang memicu pelambatan (baca atau tulis), dan batas spesifik yang terlampaui (dalam hal ini: kapasitas yang disediakan). Untuk informasi selengkapnya tentang mendiagnosis dan menyelesaikan masalah pelambatan, lihat. [Mendiagnosis pelambatan](throttling-diagnosing-workflow.md)  
Contoh: Tingkat permintaan Anda terlalu tinggi. AWS SDKs Untuk DynamoDB secara otomatis mencoba kembali permintaan yang menerima pengecualian ini. Permintaan Anda akhirnya berhasil, kecuali antrean percobaan ulang Anda terlalu besar untuk diselesaikan. Kurangi frekuensi permintaan menggunakan [Percobaan ulang kesalahan dan penundaan eksponensial](#Programming.Errors.RetryAndBackoff).   
Boleh diulang? Ya

**ReplicatedWriteConflictException**  
Pesan: *Satu atau beberapa item dalam permintaan ini sedang dimodifikasi oleh permintaan di Wilayah lain.*  
Contoh: Operasi tulis diminta untuk item dalam tabel global Multi-region yang sangat konsisten (MRSC) yang saat ini sedang dimodifikasi oleh permintaan di Wilayah lain.   
Boleh diulang? Ya

**RequestLimitExceeded**  
Pesan: *Throughput melebihi batas throughput saat ini untuk akun Anda. Untuk meminta peningkatan batas, hubungi AWS Support di [https://aws.amazon.com/support](https://aws.amazon.com/support)*.  
Kesalahan mencakup daftar `ThrottlingReason` bidang yang menyediakan konteks spesifik tentang mengapa pelambatan terjadi, mengikuti format `ResourceType+OperationType+LimitType` (misalnya, `TableWriteAccountLimitExceeded` atau`IndexReadAccountLimitExceeded`) dan ARN sumber daya yang terpengaruh. Ini membantu Anda mengidentifikasi sumber daya mana yang sedang dibatasi (tabel atau indeks), jenis operasi apa yang memicu pelambatan (baca atau tulis), dan bahwa Anda telah melampaui kuota layanan tingkat akun. Untuk informasi selengkapnya tentang mendiagnosis dan menyelesaikan masalah pelambatan, lihat. [Mendiagnosis pelambatan](throttling-diagnosing-workflow.md)   
Contoh: Tingkat permintaan sesuai permintaan melebihi throughput akun yang diizinkan dan tabel tidak dapat diskalakan lebih lanjut.  
Boleh diulang? Ya

**ResourceInUseException**  
Pesan: *Sumber daya yang Anda coba ubah sedang digunakan.*  
Contoh: Anda mencoba untuk membuat ulang tabel yang sudah ada, atau menghapus tabel yang saat ini dalam status `CREATING`.   
Boleh diulang? Tidak

**ResourceNotFoundException **  
Pesan: *Sumber daya yang diminta tidak ditemukan.*  
Contoh: Tabel yang diminta tidak ada, atau terlalu dini dalam status `CREATING`.  
Boleh diulang? Tidak

**ThrottlingException**  
Pesan: *Tingkat permintaan melebihi throughput yang diizinkan.*  
Pengecualian ini dikembalikan sebagai AmazonServiceException respons dengan kode status THROTTLING\$1EXCEPTION. Pengecualian ini mungkin dikembalikan jika Anda melakukan operasi API [bidang kontrol](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.ControlPlane) terlalu cepat.  
Untuk tabel yang menggunakan mode sesuai permintaan, pengecualian ini mungkin dikembalikan untuk setiap operasi API [bidang data](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.DataPlane) jika tingkat permintaan Anda terlalu tinggi. Untuk mempelajari lebih lanjut tentang penskalaan sesuai permintaan, lihat. [Throughput awal dan properti penskalaan](on-demand-capacity-mode.md#on-demand-capacity-mode-initial)   
Kesalahan mencakup daftar `ThrottlingReason` bidang yang menyediakan konteks spesifik tentang mengapa pelambatan terjadi, mengikuti format `ResourceType+OperationType+LimitType` (misalnya, `TableReadKeyRangeThroughputExceeded` atau`IndexWriteMaxOnDemandThroughputExceeded`) dan ARN sumber daya yang terpengaruh. Informasi ini membantu Anda mengidentifikasi sumber daya mana yang sedang dibatasi (tabel atau indeks), jenis operasi apa yang memicu pelambatan (baca atau tulis), dan batas spesifik yang terlampaui (batas partisi atau throughput maksimum sesuai permintaan). Untuk informasi selengkapnya tentang mendiagnosis dan menyelesaikan masalah pelambatan, lihat. [Mendiagnosis pelambatan](throttling-diagnosing-workflow.md)  
Boleh diulang? Ya

**UnrecognizedClientException**  
Pesan: *ID Kunci Akses atau token keamanan tidak valid.*  
Tanda tangan permintaan tidak benar. Penyebab yang paling mungkin adalah ID kunci AWS akses atau kunci rahasia yang tidak valid.  
Boleh diulang? Ya

**ValidationException**  
Pesan: Bervariasi, tergantung pada kesalahan tertentu yang dialami  
Kesalahan ini dapat terjadi karena beberapa alasan, seperti parameter yang diperlukan tidak ada, nilai di luar rentang, atau jenis data tidak cocok. kesalahan berisi detail tentang bagian tertentu dari permintaan yang menyebabkan kesalahan.  
Boleh diulang? Tidak

### Kode status HTTP 5xx
<a name="Programming.Errors.MessagesAndCodes.http5xx"></a>

Kode status `5xx` HTTP menunjukkan masalah yang harus diselesaikan oleh AWS. Kemungkinan ini adalah kesalahan sementara, sehingga Anda dapat mencoba lagi permintaan Anda hingga berhasil. Jika tidak, masuk ke [Service Health Dashboard AWS](https://status.aws.amazon.com/) untuk melihat apakah ada masalah operasional dengan layanan ini.

Untuk informasi selengkapnya, lihat [Bagaimana cara mengatasi kesalahan HTTP 5xx di Amazon DynamoDB?](https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-http-5xx-errors/)

**InternalServerError (HTTP 500)**  
DynamoDB tidak dapat memproses permintaan Anda.  
Boleh diulang? Ya  
Anda mungkin mengalami kesalahan server internal saat menggunakan item. Ini diduga terjadi selama masa aktif tabel. Setiap permintaan yang gagal dapat segera dicoba kembali.  
Ketika Anda menerima kode status 500 pada operasi tulis, operasi tersebut mungkin berhasil atau gagal. Jika operasi tulis adalah permintaan `TransactWriteItem`, maka boleh saja mencoba ulang operasi tersebut. Jika operasi tulis adalah permintaan penulisan item tunggal seperti`PutItem`,, atau `UpdateItem``DeleteItem`, maka aplikasi Anda harus membaca status item sebelum mencoba kembali operasi, and/or gunakan [Contoh CLI ekspresi kondisi DynamoDB](Expressions.ConditionExpressions.md) untuk memastikan bahwa item tetap dalam keadaan yang benar setelah mencoba kembali terlepas dari apakah operasi sebelumnya berhasil atau gagal. Jika idempotensi adalah persyaratan untuk operasi tulis, gunakan [`TransactWriteItem`](transaction-apis.md#transaction-apis-txwriteitems), yang mendukung permintaan idempoten dengan menentukan `ClientRequestToken` secara otomatis untuk membedakan beberapa upaya untuk melakukan tindakan yang sama.

**ServiceUnavailable (HTTP 503)**  
DynamoDB saat ini tidak tersedia. (Ini harus merupakan status sementara.)  
Boleh diulang? Ya

## Penanganan kesalahan dalam aplikasi Anda
<a name="Programming.Errors.Handling"></a>

Agar aplikasi Anda berjalan lancar, Anda perlu menambahkan logika untuk menangkap dan merespons kesalahan. Pendekatan umum termasuk menggunakan blok `try-catch` atau pernyataan `if-then`.

 AWS SDKs Melakukan percobaan ulang dan pengecekan kesalahan mereka sendiri. Jika Anda menemukan kesalahan saat menggunakan salah satu AWS SDKs, kode kesalahan dan deskripsi dapat membantu Anda memecahkan masalah itu.

Anda juga akan melihat `Request ID` dalam respons. Ini `Request ID` dapat membantu jika Anda perlu bekerja dengan AWS Support untuk mendiagnosis suatu masalah.

## Percobaan ulang kesalahan dan penundaan eksponensial
<a name="Programming.Errors.RetryAndBackoff"></a>

Banyak komponen di jaringan, seperti server DNS, sakelar, penyeimbang beban, dan lainnya, dapat menghasilkan kesalahan di mana pun selama permintaan tertentu. Teknik biasa untuk menangani respons kesalahan ini dalam lingkungan jaringan adalah dengan menerapkan percobaan ulang dalam aplikasi klien. Teknik ini meningkatkan keandalan aplikasi.

Setiap AWS SDK mengimplementasikan logika coba ulang secara otomatis. Anda dapat mengubah parameter percobaan ulang sesuai kebutuhan Anda. Misalnya, pertimbangkan aplikasi Java yang memerlukan strategi gagal cepat (fail fast), dengan tidak memperbolehkan percobaan ulang jika terjadi kesalahan. Dengan AWS SDK untuk Java, Anda dapat menggunakan `ClientConfiguration` kelas dan memberikan `maxErrorRetry` nilai `0` untuk mematikan percobaan ulang. Untuk informasi selengkapnya, lihat dokumentasi AWS SDK untuk bahasa pemrograman Anda.

Jika Anda tidak menggunakan AWS SDK, Anda harus mencoba kembali permintaan asli yang menerima kesalahan server (5xx). Namun, kesalahan klien (4xx, selain `ThrottlingException` atau `ProvisionedThroughputExceededException`) menunjukkan bahwa Anda perlu merevisi permintaan itu sendiri untuk memperbaiki masalah sebelum melakukan percobaan ulang. [Untuk rekomendasi terperinci untuk mengatasi skenario pelambatan tertentu, lihat bagian pemecahan masalah pelambatan DynamoDB.](TroubleshootingThrottling.md)

Selain percobaan ulang sederhana, setiap AWS SDK mengimplementasikan algoritma backoff eksponensial untuk kontrol aliran yang lebih baik. Konsep di balik penundaan eksponensial adalah menggunakan waktu tunggu yang lebih lama di antara percobaan ulang untuk respon kesalahan berturut-turut. Sebagai contoh, hinga 50 milidetik sebelum percobaan ulang pertama, hingga 100 milidetik sebelum percobaan ulang kedua, hingga 200 milidetik sebelum percobaan ulang ketiga, dan seterusnya. Namun, setelah satu menit, jika permintaan tidak berhasil, masalahnya mungkin pada ukuran permintaan yang melebihi throughput yang disediakan, dan bukan pada tingkat permintaan. Tetapkan jumlah maksimum percobaan ulang untuk berhenti sekitar satu menit. Jika permintaan tidak berhasil, selidiki opsi throughput yang disediakan. 

**catatan**  
 AWS SDKs Mengimplementasikan logika coba ulang otomatis dan backoff eksponensial.

Kebanyakan algoritma penundaan eksponensial menggunakan jitter (penundaan acak) untuk mencegah tabrakan berturut-turut. Karena Anda tidak berusaha menghindari tabrakan seperti itu dalam kasus ini, Anda tidak perlu menggunakan nomor acak ini. Namun, jika Anda menggunakan klien secara bersamaan, jitter dapat membantu permintaan Anda berhasil lebih cepat. Untuk informasi selengkapnya, lihat postingan blog tentang [Penundaan eksponensial dan jitter](http://www.awsarchitectureblog.com/2015/03/backoff.html).

## Operasi batch dan penanganan kesalahan
<a name="Programming.Errors.BatchOperations"></a>

API tingkat rendah DynamoDB mendukung operasi batch untuk baca dan tulis. `BatchGetItem` membaca item dari satu atau beberapa tabel, dan `BatchWriteItem` memasukkan atau menghapus item dalam satu atau beberapa tabel. Operasi batch ini diimplementasikan sebagai pembungkus di sekitar operasi DynamoDB non-batch lainnya. Dengan kata lain, `BatchGetItem` menginvokasi `GetItem` sekali untuk setiap item dalam batch. Demikian pula, `BatchWriteItem` menginvokasi `DeleteItem` atau `PutItem`, jika sesuai, untuk setiap item dalam batch.

Operasi batch dapat menoleransi kegagalan permintaan individual dalam batch. Misalnya, pertimbangkan `BatchGetItem` untuk membaca lima item. Meskipun beberapa permintaan `GetItem` yang mendasarinya gagal, ini tidak menyebabkan seluruh operasi `BatchGetItem` gagal. Namun, jika kelima operasi baca gagal, maka seluruh `BatchGetItem` akan gagal pula.

Operasi batch mengembalikan informasi tentang masing-masing permintaan yang gagal sehingga Anda dapat mendiagnosis masalah dan mencoba kembali operasi tersebut. Untuk `BatchGetItem`, tabel dan kunci primer yang dimaksud dikembalikan dalam nilai `UnprocessedKeys` respons. Untuk `BatchWriteItem`, informasi serupa dikembalikan dalam `UnprocessedItems`. 

Kemungkinan besar penyebab gagalnya baca atau tulis adalah *throttling*. Untuk `BatchGetItem`, satu atau beberapa tabel dalam permintaan batch tidak memiliki kapasitas baca yang memadai untuk mendukung operasi. Untuk `BatchWriteItem`, satu atau beberapa tabel tidak memiliki kapasitas tulis yang memadai.

Jika DynamoDB mengembalikan item yang belum diproses, Anda harus mencoba ulang operasi batch pada item tersebut. Namun, *kami sangat merekomendasikan agar Anda menggunakan algoritma penundaan eksponensial*. Jika Anda segera mencoba ulang operasi batch, permintaan baca atau tulis yang mendasarinya masih bisa gagal karena throttling pada masing-masing tabel. Jika Anda menunda operasi batch menggunakan penundaan eksponensial, masing-masing permintaan dalam batch kemungkinan besar akan berhasil.

**catatan**  
Beberapa AWS SDKs menyediakan klien tingkat tinggi yang menangani percobaan ulang item yang belum diproses secara otomatis, jadi Anda tidak perlu menerapkan logika coba lagi ini sendiri. Contoh:  
**Java** [— [DynamoDB Enhanced](DynamoDBEnhanced.md) Client di AWS SDK untuk Java v2 dan DBMapper Dynamo in v1 keduanya secara otomatis mencoba kembali item yang belum diproses saat melakukan operasi batch.](DynamoDBMapper.md)
**Python** - Sumber daya Tabel boto3 `batch_writer` menangani percobaan ulang item yang belum diproses secara implisit untuk operasi penulisan batch. Untuk informasi selengkapnya, lihat [Menggunakan sumber daya tabel batch\$1writer](programming-with-python.md#programming-with-python-batch-writer).
Jika Anda menggunakan klien tingkat rendah atau SDK yang tidak memberikan perilaku ini, Anda harus menerapkan logika coba lagi sendiri seperti yang dijelaskan di atas.

# Menggunakan DynamoDB dengan SDK AWS
<a name="sdk-general-information-section"></a>

AWS kit pengembangan perangkat lunak (SDKs) tersedia untuk banyak bahasa pemrograman populer. Setiap SDK menyediakan API, contoh kode, dan dokumentasi yang memudahkan developer untuk membangun aplikasi dalam bahasa pilihan mereka.


| Dokumentasi SDK | Contoh kode | 
| --- | --- | 
| [AWS SDK untuk C\$1\$1](https://docs.aws.amazon.com/sdk-for-cpp) | [AWS SDK untuk C\$1\$1 contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp) | 
| [AWS CLI](https://docs.aws.amazon.com/cli) | [AWS CLI contoh kode](https://docs.aws.amazon.com/code-library/latest/ug/cli_2_code_examples.html) | 
| [AWS SDK untuk Go](https://docs.aws.amazon.com/sdk-for-go) | [AWS SDK untuk Go contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2) | 
| [AWS SDK untuk Java](https://docs.aws.amazon.com/sdk-for-java) | [AWS SDK untuk Java contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2) | 
| [AWS SDK untuk JavaScript](https://docs.aws.amazon.com/sdk-for-javascript) | [AWS SDK untuk JavaScript contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3) | 
| [AWS SDK untuk Kotlin](https://docs.aws.amazon.com/sdk-for-kotlin) | [AWS SDK untuk Kotlin contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin) | 
| [AWS SDK untuk .NET](https://docs.aws.amazon.com/sdk-for-net) | [AWS SDK untuk .NET contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3) | 
| [AWS SDK untuk PHP](https://docs.aws.amazon.com/sdk-for-php) | [AWS SDK untuk PHP contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php) | 
| [Alat AWS untuk PowerShell](https://docs.aws.amazon.com/powershell) | [Alat AWS untuk PowerShell contoh kode](https://docs.aws.amazon.com/code-library/latest/ug/powershell_5_code_examples.html) | 
| [AWS SDK untuk Python (Boto3)](https://docs.aws.amazon.com/pythonsdk) | [AWS SDK untuk Python (Boto3) contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python) | 
| [AWS SDK untuk Ruby](https://docs.aws.amazon.com/sdk-for-ruby) | [AWS SDK untuk Ruby contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/ruby) | 
| [AWS SDK for Rust](https://docs.aws.amazon.com/sdk-for-rust) | [AWS SDK for Rust contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1) | 
| [AWS SDK for SAP ABAP](https://docs.aws.amazon.com/sdk-for-sapabap) | [AWS SDK for SAP ABAP contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap) | 
| [AWS SDK for Swift](https://docs.aws.amazon.com/sdk-for-swift) | [AWS SDK for Swift contoh kode](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift) | 

Untuk contoh khusus DynamoDB, lihat [Contoh kode untuk DynamoDB menggunakan AWS SDKs](service_code_examples.md).

**Ketersediaan contoh**  
Tidak dapat menemukan apa yang Anda butuhkan? Minta contoh kode menggunakan tautan **Berikan umpan balik** di bagian bawah halaman ini.