

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

# DynamoDB memetakan perbedaan API antara versi 1 dan versi 2 AWS SDK untuk Java
<a name="ddb-mapping"></a>

 APIs Pemetaan DynamoDB berubah secara signifikan antara versi 1 dan versi 2. AWS SDK untuk Java Di versi 1, Anda menggunakan `DynamoDBMapper` untuk bekerja dengan Java POJOs. Di versi 2, Anda menggunakan nama metode `DynamoDbEnhancedClient` yang diperbarui, opsi definisi skema yang disempurnakan, dan keamanan tipe yang ditingkatkan.

Perbedaan utama meliputi:
+ Nama metode baru (seperti `getItem` bukan`load`)
+ Pembuatan skema tabel eksplisit
+ Dukungan bawaan untuk operasi sinkron dan asinkron
+ Perubahan cara string dan konfigurasi kosong ditangani

Bagian ini mencakup perubahan API pemetaan, perbedaan anotasi, pembaruan konfigurasi, dan panduan migrasi untuk membantu Anda bertransisi dari v1 `DynamoDBMapper` ke v2. `DynamoDbEnhancedClient`

**Contents**
+ [Perubahan tingkat tinggi dalam pemetaan pustaka dari versi 1 ke versi 2 SDK for Java](dynamodb-mapping-high-level.md)
  + [Perbedaan ketergantungan impor](dynamodb-mapping-high-level.md#dynamodb-mapping-deps)
+ [Perubahan dalam APIs pemetaan DynamoDB antara versi 1 dan versi 2 dari SDK for Java](dynamodb-mapping-api-changes.md)
  + [Buat klien](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-client)
  + [Menetapkan pemetaan ke tabel/indeks DynamoDB](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-mapping)
  + [Operasi tabel](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-tobleops)
  + [Kelas peta dan properti](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas)
    + [Anotasi kacang](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos)
    + [V2 anotasi tambahan](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos-v2-addnl)
  + [Konfigurasi](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration)
    + [Konfigurasi per operasi](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration-per-op)
  + [Kondisional](dynamodb-mapping-api-changes.md#dynamodb-mapping-conditionals)
  + [Jenis konversi](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv)
    + [Konverter default](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-defaults)
    + [Menetapkan konverter kustom untuk atribut](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-anno)
    + [Tambahkan pabrik atau penyedia konverter tipe](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-factory)
+ [String menangani perbedaan antara versi 1 dan versi 2 dari SDK for Java](dynamodb-migration-string-handling.md)
+ [Perbedaan penguncian optimis antara versi 1 dan versi 2 dari SDK for Java](dynamodb-migrate-optimstic-locking.md)
+ [Perbedaan setter yang lancar antara versi 1 dan versi 2 dari SDK for Java](dynamodb-migrate-fluent-setters.md)

# Perubahan tingkat tinggi dalam pemetaan pustaka dari versi 1 ke versi 2 SDK for Java
<a name="dynamodb-mapping-high-level"></a>

Nama-nama klien pemetaan di setiap pustaka berbeda di V1 dan V2:
+ V1 - Dinamo DBMapper
+ V2 - Klien yang Ditingkatkan DynamoDB

Anda berinteraksi dengan dua pustaka dengan cara yang hampir sama: Anda membuat instance mapper/client dan kemudian memasok POJO Java untuk membaca dan menulis item ini ke APIs tabel DynamoDB. Kedua pustaka juga menawarkan anotasi untuk kelas POJO untuk mengarahkan bagaimana klien menangani POJO. 

Perbedaan penting saat Anda pindah ke V2 meliputi:
+ V2 dan V1 menggunakan nama metode yang berbeda untuk operasi DynamoDB tingkat rendah. Contoh:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/dynamodb-mapping-high-level.html)
+ V2 menawarkan beberapa cara untuk menentukan skema tabel dan memetakan POJOs ke tabel. Anda dapat memilih dari penggunaan anotasi atau skema yang dihasilkan dari kode menggunakan pembangun. V2 juga menawarkan versi skema yang dapat berubah dan tidak dapat diubah.
+ Dengan V2, Anda secara khusus membuat skema tabel sebagai salah satu langkah pertama, sedangkan di V1, skema tabel disimpulkan dari kelas beranotasi sesuai kebutuhan.
+ V2 menyertakan [klien Document API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html) dalam API klien yang disempurnakan, sedangkan V1 menggunakan [API terpisah](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/DynamoDB.html).
+ Semua APIs tersedia dalam versi sinkron dan asinkron di V2.

Lihat bagian [pemetaan DynamoDB](dynamodb-enhanced-client.md) dalam panduan ini untuk informasi lebih rinci tentang klien yang disempurnakan V2.

## Perbedaan ketergantungan impor
<a name="dynamodb-mapping-deps"></a>


| V1 | V2 | 
| --- | --- | 
|  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>com.amazonaws</groupId><br />      <artifactId>aws-java-sdk-bom</artifactId><br />      <version>1.X.X</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>com.amazonaws</groupId><br />    <artifactId>aws-java-sdk-dynamodb</artifactId><br />  </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>software.amazon.awssdk</groupId><br />      <artifactId>bom</artifactId><br />      <version>2.X.X*</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>software.amazon.awssdk</groupId><br />    <artifactId>dynamodb-enhanced</artifactId><br />  </dependency><br /></dependencies></pre>  | 

\$1 [Versi terbaru](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

Di V1, dependensi tunggal mencakup API DynamoDB tingkat rendah dan mapping/document API, sedangkan di V2, Anda menggunakan `dynamodb-enhanced` dependensi artefak untuk mengakses API. mapping/document `dynamodb-enhanced`Modul ini berisi ketergantungan transitif pada modul tingkat rendah`dynamodb`. 

# Perubahan dalam APIs pemetaan DynamoDB antara versi 1 dan versi 2 dari SDK for Java
<a name="dynamodb-mapping-api-changes"></a>

## Buat klien
<a name="dynamodb-mapping-api-changes-client"></a>


****  

| Kasus penggunaan | V1 | V2 | 
| --- | --- | --- | 
|   Instantiasi normal  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard()<br />    .withCredentials(credentialsProvider)<br />    .withRegion(Regions.US_EAST_1)<br />    .build();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbClient standardClient = DynamoDbClient.builder()<br />    .credentialsProvider(ProfileCredentialsProvider.create())<br />    .region(Region.US_EAST_1)<br />    .build();<br />DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .build();</pre>  | 
|   Instantiasi minimal  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();</pre>  | 
|   Dengan trafo atribut\$1  |  <pre>DynamoDBMapper mapper = new DynamoDBMapper(standardClient, <br />                        attributeTransformerInstance);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .extensions(extensionAInstance, extensionBInstance)<br />    .build();</pre>  | 

\$1 Ekstensi di V2 kira-kira sesuai dengan atribut transformer di V1. [Gunakan ekstensi untuk menyesuaikan operasi DynamoDB Enhanced Client](ddb-en-client-extensions.md)Bagian ini berisi informasi lebih lanjut tentang ekstensi di V2. 

## Menetapkan pemetaan ke tabel/indeks DynamoDB
<a name="dynamodb-mapping-api-changes-mapping"></a>

Di V1, Anda menentukan nama tabel DynamoDB melalui anotasi kacang. Dalam V2, metode pabrik,`table()`, menghasilkan instance `DynamoDbTable` yang mewakili tabel DynamoDB jarak jauh. Parameter pertama dari `table()` metode ini adalah nama tabel DynamoDB.


****  

| Kasus penggunaan | V1 | V2 | 
| --- | --- | --- | 
|   Memetakan kelas Java POJO ke tabel DynamoDB  |  <pre>@DynamoDBTable(tableName ="Customer")<br />public class Customer {<br />  ...<br />}</pre>  |  <pre>DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer",<br />    TableSchema.fromBean(Customer.class));</pre>  | 
|   Peta ke indeks sekunder DynamoDB  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) Bagian dalam DynamoDB Developer Guide yang [membahas metode `query` V1 menunjukkan contoh](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.query) lengkap.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) [Gunakan indeks sekunder](ddb-en-client-use-secindex.md)Bagian dalam panduan ini memberikan informasi lebih lanjut.  | 

## Operasi tabel
<a name="dynamodb-mapping-api-changes-tobleops"></a>

Bagian ini menjelaskan operasi APIs yang berbeda antara V1 dan V2 untuk sebagian besar kasus penggunaan standar. 

Di V2, semua operasi yang melibatkan satu tabel dipanggil pada `DynamoDbTable` instance, bukan pada klien yang disempurnakan. Klien yang disempurnakan berisi metode yang dapat menargetkan beberapa tabel. 

Dalam tabel bernama *operasi Tabel* di bawah ini, contoh POJO disebut sebagai `item` atau sebagai tipe tertentu seperti`customer1`. Untuk contoh V2 instance bernama, `table` adalah hasil dari pemanggilan sebelumnya `enhancedClient.table()` yang mengembalikan referensi ke `DynamoDbTable` instance.

Perhatikan bahwa sebagian besar operasi V2 dapat dipanggil dengan pola konsumen yang lancar bahkan ketika tidak ditampilkan. Misalnya, 

```
Customer customer = table.getItem(r → r.key(key));
  or
Customer customer = table.getItem(r → r.key(k -> k.partitionValue("id").sortValue("email")))
```

Untuk operasi V1, *operasi Tabel* (di bawah) berisi beberapa formulir yang umum digunakan dan tidak semua formulir yang kelebihan beban. Misalnya, `load()` metode ini memiliki kelebihan beban berikut:

```
mapper.load(Customer.class, hashKey)
mapper.load(Customer.class, hashKey, rangeKey)
mapper.load(Customer.class, hashKey, config)
mapper.load(Customer.class, hashKey, rangeKey, config)
mapper.load(item)
mapper.load(item, config)
```

*Operasi tabel* (di bawah) menunjukkan bentuk yang umum digunakan:

```
mapper.load(item)
mapper.load(item, config)
```


**Operasi tabel**  

| Kasus penggunaan | V1 | V2 | 
| --- | --- | --- | 
|  Tulis POJO Java ke tabel DynamoDB **Operasi DynamoDB**:, `PutItem` `UpdateItem`  |  <pre>mapper.save(item)<br />mapper.save(item, config)<br />mapper.save(item, saveExpression, config)</pre> Dalam V1, `DynamoDBMapperConfig.SaveBehavior` dan anotasi menentukan metode DynamoDB tingkat rendah mana yang akan dipanggil. Secara umum, `UpdateItem` disebut kecuali saat menggunakan `SaveBehavior.CLOBBER` dan`SaveBehavior.PUT`. Kunci yang dihasilkan secara otomatis adalah kasus penggunaan khusus, dan kadang-kadang keduanya `PutItem` dan `UpdateItem` digunakan.  |  <pre>table.putItem(putItemRequest)<br />table.putItem(item)<br />table.putItemWithResponse(item) //Returns metadata.<br /><br />updateItem(updateItemRequest)<br />table.updateItem(item)<br />table.updateItemWithResponse(item) //Returns metadata.</pre>  | 
|  Membaca item dari tabel DynamoDB ke POJO Java **Operasi DynamoDB:** `GetItem`  |  <pre>mapper.load(item)<br />mapper.load(item, config)</pre>  |  <pre>table.getItem(getItemRequest)<br />table.getItem(item)<br />table.getItem(key)<br />table.getItemWithResponse(key) //Returns POJO with metadata.</pre>  | 
|  Menghapus item dari tabel DynamoDB **Operasi DynamoDB:** `DeleteItem`  |  <pre>mapper.delete(item, deleteExpression, config)</pre>  |  <pre>table.deleteItem(deleteItemRequest)<br />table.deleteItem(item)<br />table.deleteItem(key)</pre>  | 
|  Kueri tabel DynamoDB atau indeks sekunder dan kembalikan daftar paginasi **Operasi DynamoDB:** `Query`  |  <pre>mapper.query(Customer.class, queryExpression)<br />mapper.query(Customer.class, queryExpression, <br />                             mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> Gunakan yang dikembalikan `PageIterable.stream()` (pemuatan lambat) untuk respons sinkronisasi dan `PagePublisher.subscribe()` untuk respons asinkron  | 
|  Kueri tabel DynamoDB atau indeks sekunder dan kembalikan daftar **Operasi DynamoDB:** `Query`  |  <pre>mapper.queryPage(Customer.class, queryExpression)<br />mapper.queryPage(Customer.class, queryExpression, <br />                                 mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> Gunakan yang dikembalikan `PageIterable.items()` (pemuatan lambat) untuk respons sinkronisasi dan `PagePublisher.items.subscribe()` untuk respons asinkron  | 
|  Memindai tabel DynamoDB atau indeks sekunder dan mengembalikan daftar paginasi **Operasi DynamoDB:** `Scan`  |  <pre>mapper.scan(Customer.class, scanExpression)<br />mapper.scan(Customer.class, scanExpression, <br />                            mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> Gunakan yang dikembalikan `PageIterable.stream()` (pemuatan lambat) untuk respons sinkronisasi dan `PagePublisher.subscribe()` untuk respons asinkron  | 
|  Pindai tabel DynamoDB atau indeks sekunder dan kembalikan daftar **Operasi DynamoDB:** `Scan`  |  <pre>mapper.scanPage(Customer.class, scanExpression)<br />mapper.scanPage(Customer.class, scanExpression, <br />                                mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> Gunakan yang dikembalikan `PageIterable.items()` (pemuatan lambat) untuk respons sinkronisasi dan `PagePublisher.items.subscribe()` untuk respons asinkron  | 
|  Baca beberapa item dari beberapa tabel dalam satu batch **Operasi DynamoDB:** `BatchGetItem`  |  <pre>mapper.batchLoad(Arrays.asList(customer1, <br />                               customer2, <br />                               book1))<br />mapper.batchLoad(itemsToGet) <br />           // itemsToGet: Map<Class<?>, List<KeyPair>></pre>  |  <pre>enhancedClient.batchGetItem(batchGetItemRequest)<br /><br />enhancedClient.batchGetItem(r -> r.readBatches(<br />    ReadBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build(),<br />    ReadBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build()))<br /><br />// Iterate over pages with lazy loading or over all items <br />   from the same table.</pre>  | 
|  Tulis beberapa item ke beberapa tabel dalam satu batch **Operasi DynamoDB:** `BatchWriteItem`  |  <pre>mapper.batchSave(Arrays.asList(customer1, <br />                               customer2, <br />                               book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(batchWriteItemRequest)<br /><br />enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addPutItem(item2)<br />             .build()))</pre>  | 
|  Hapus beberapa item dari beberapa tabel dalam satu batch **Operasi DynamoDB:** `BatchWriteItem`  |  <pre>mapper.batchDelete(Arrays.asList(customer1, <br />                                 customer2, <br />                                 book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addDeleteItem(item1key)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  Tulis/hapus beberapa item dalam satu batch **Operasi DynamoDB:** `BatchWriteItem`  |  <pre>mapper.batchWrite(Arrays.asList(customer1, book1), <br />                  Arrays.asList(customer2)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  Lakukan penulisan transaksional **Operasi DynamoDB:** `TransactWriteItems`  |  <pre>mapper.transactionWrite(transactionWriteRequest)</pre>  |  <pre>enhancedClient.transactWriteItems(transasctWriteItemsRequest)</pre>  | 
|  Lakukan pembacaan transaksional **Operasi DynamoDB:** `TransactGetItems`  |  <pre>mapper.transactionLoad(transactionLoadRequest)</pre>  |  <pre>enhancedClient.transactGetItems(transactGetItemsRequest) </pre>  | 
|  Dapatkan hitungan item yang cocok dari kueri **Operasi DynamoDB**: dengan `Query` `Select.COUNT`  |  <pre>mapper.count(Customer.class, queryExpression)</pre>  |  <pre>// Get the count from query results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.query(QueryEnhancedRequest.builder()<br />        .queryConditional(queryConditional)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.query(QueryEnhancedRequest.builder()<br />                .queryConditional(queryConditional)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  Dapatkan hitungan item yang cocok dari pemindaian **Operasi DynamoDB**: dengan `Scan` `Select.COUNT`  |  <pre>mapper.count(Customer.class, scanExpression)</pre>  |  <pre>// Get the count from scan results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.scan(ScanEnhancedRequest.builder()<br />        .filterExpression(filterExpression)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.scan(ScanEnhancedRequest.builder()<br />                .filterExpression(filterExpression)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  Buat tabel di DynamoDB sesuai dengan kelas POJO **Operasi DynamoDB:** `CreateTable`  |  <pre>mapper.generateCreateTableRequest(Customer.class)</pre> Pernyataan sebelumnya menghasilkan permintaan tabel buat tingkat rendah; pengguna harus memanggil klien `createTable` DynamoDB.  |  <pre>table.createTable(createTableRequest)<br /><br />table.createTable(r -> r.provisionedThroughput(defaultThroughput())<br />    .globalSecondaryIndices(<br />        EnhancedGlobalSecondaryIndex.builder()<br />            .indexName("gsi_1")<br />            .projection(p -> p.projectionType(ProjectionType.ALL))<br />            .provisionedThroughput(defaultThroughput())<br />            .build()));</pre>  | 
|  Lakukan pemindaian paralel di DynamoDB **Operasi `Scan` DynamoDB**: dengan dan parameter `Segment` `TotalSegments`  |  <pre>mapper.parallelScan(Customer.class, <br />                    scanExpression, <br />                    numTotalSegments)</pre>  |  Pengguna diminta untuk menangani thread pekerja dan memanggil `scan` untuk setiap segmen: <pre>table.scan(r -> r.segment(0).totalSegments(5))</pre>  | 
|  Integrasikan Amazon S3 dengan DynamoDB untuk menyimpan tautan S3 cerdas  |  <pre>mapper.createS3Link(bucket, key)<br />mapper.getS3ClientCache()</pre>  |  Tidak didukung karena memasangkan Amazon S3 dan DynamoDB.  | 

## Kelas peta dan properti
<a name="dynamodb-mapping-schemas"></a>

Di V1 dan V2, Anda memetakan kelas ke tabel menggunakan anotasi gaya kacang. V2 juga menawarkan [cara lain untuk mendefinisikan skema](ddb-en-client-adv-features.md#ddb-en-client-adv-features-schm-overview) untuk kasus penggunaan tertentu, seperti bekerja dengan kelas yang tidak dapat diubah.

### Anotasi kacang
<a name="dynamodb-mapping-schemas-annos"></a>

Tabel berikut menunjukkan anotasi kacang setara untuk kasus penggunaan tertentu yang digunakan dalam V1 dan V2. Skenario `Customer` kelas digunakan untuk mengilustrasikan parameter.

Anotasi — serta kelas dan pencacahan — di V2 ikuti konvensi kasus unta dan gunakan '', bukan 'DynamoDB'. DynamoDb


| Kasus penggunaan | V1 | V2 | 
| --- | --- | --- | 
| Petakan kelas ke tabel |  <pre>@DynamoDBTable (tableName ="CustomerTable")</pre>  | <pre>@DynamoDbBean<br />@DynamoDbBean(converterProviders = {...})</pre>Nama tabel didefinisikan saat memanggil DynamoDbEnhancedClient\$1table() metode. | 
| Menunjuk anggota kelas sebagai atribut tabel  |  <pre>@DynamoDBAttribute(attributeName = "customerName")</pre>  |  <pre>@DynamoDbAttribute("customerName") </pre>  | 
| Menunjuk anggota kelas adalah kunci hash/partition  |  <pre>@DynamoDBHashKey </pre>  |  <pre>@DynamoDbPartitionKey</pre>  | 
| Menunjuk anggota kelas adalah kunci range/sort  |  <pre>@DynamoDBRangeKey </pre>  |  <pre>@DynamoDbSortKey </pre>  | 
| Menunjuk anggota kelas adalah kunci hash/partisi indeks sekunder |  <pre>@DynamoDBIndexHashKey </pre>  |  <pre>@DynamoDbSecondaryPartitionKey </pre>  | 
| Menunjuk anggota kelas adalah kunci rentang/sortir indeks sekunder |  <pre>@DynamoDBIndexRangeKey </pre>  |  <pre>@DynamoDbSecondarySortKey </pre>  | 
| Abaikan anggota kelas ini saat memetakan ke tabel |  <pre>@DynamoDBIgnore </pre>  |  <pre>@DynamoDbIgnore</pre>  | 
| Tentukan anggota kelas sebagai atribut kunci UUID yang dibuat secara otomatis |  <pre>@DynamoDBAutoGeneratedKey</pre>  |  <pre>@DynamoDbAutoGeneratedUuid </pre> Ekstensi yang menyediakan ini tidak dimuat secara default; Anda harus menambahkan ekstensi ke pembuat klien.  | 
| Tentukan anggota kelas sebagai atribut stempel waktu yang dibuat secara otomatis |  <pre>@DynamoDBAutoGeneratedTimestamp</pre>  |  <pre>@DynamoDbAutoGeneratedTimestampAttribute</pre> Ekstensi yang menyediakan ini tidak dimuat secara default; Anda harus menambahkan ekstensi ke pembuat klien.  | 
| Menunjuk anggota kelas sebagai atribut versi auto-incremented |  <pre>@DynamoDBVersionAttribute</pre>  |  <pre>@DynamoDbVersionAttribute</pre> Ekstensi yang menyediakan ini dimuat secara otomatis.  | 
| Menunjuk anggota kelas sebagai membutuhkan konversi kustom |  <pre>@DynamoDBTypeConverted</pre>  |  <pre>@DynamoDbConvertedBy</pre>  | 
| Menunjuk anggota kelas untuk disimpan sebagai jenis atribut yang berbeda |  <pre>@DynamoDBTyped(<DynamoDBAttributeType>)</pre>  |  Gunakan `AttributeConverter` implementasi. V2 menyediakan banyak konverter bawaan untuk tipe Java umum. Anda juga dapat menerapkan kebiasaan Anda sendiri `AttributeConverter` atau`AttributeConverterProvider`. Lihat [Konversi atribut kontrol](ddb-en-client-adv-features-conversion.md) di panduan ini.  | 
| Tentukan kelas yang dapat diserialisasikan ke dokumen DynamoDB (dokumen gaya JSON) atau sub-dokumen  |  <pre>@DynamoDBDocument</pre>  | Gunakan API Dokumen yang Ditingkatkan. Lihat sumber daya berikut:[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) | 

### V2 anotasi tambahan
<a name="dynamodb-mapping-schemas-annos-v2-addnl"></a>


| Kasus penggunaan | V1 | V2 | 
| --- | --- | --- | 
| Menunjuk anggota kelas untuk tidak disimpan sebagai atribut NULL jika nilai Java adalah null | N/A |  <pre>@DynamoDbIgnoreNulls</pre>  | 
| Menunjuk anggota kelas untuk menjadi objek kosong jika semua atribut adalah null | N/A |  <pre>@DynamoDbPreserveEmptyObject</pre>  | 
| Tentukan tindakan pembaruan khusus untuk anggota kelas | N/A |  <pre>@DynamoDbUpdateBehavior</pre>  | 
| Tentukan kelas yang tidak dapat diubah | N/A |  <pre>@DynamoDbImmutable</pre>  | 
| Menunjuk anggota kelas sebagai atribut counter auto-incremented | N/A |  <pre>@DynamoDbAtomicCounter</pre> Ekstensi yang menyediakan fungsi ini dimuat secara otomatis.  | 

## Konfigurasi
<a name="dynamodb-mapping-configuration"></a>

Di V1, Anda biasanya mengontrol perilaku tertentu dengan menggunakan instance dari. `DynamoDBMapperConfig` Anda dapat menyediakan objek konfigurasi baik ketika Anda membuat mapper atau ketika Anda membuat permintaan. Dalam V2, konfigurasi khusus untuk objek permintaan untuk operasi.


| Kasus penggunaan | V1 | Default di V1 | V2 | 
| --- | --- | --- | --- | 
|  |  <pre>DynamoDBMapperConfig.builder()</pre>  |  |  | 
| Strategi load/write coba lagi Batch |  <pre>  .withBatchLoadRetryStrategy(loadRetryStrategy)</pre> <pre>  .withBatchWriteRetryStrategy(writeRetryStrategy)</pre>  | coba lagi item yang gagal | Konfigurasikan strategi coba lagi pada yang mendasarinyaDynamoDBClient. Lihat [Konfigurasikan perilaku coba lagi di AWS SDK for Java 2.x](retry-strategy.md) di panduan ini. | 
| Bacaan yang konsisten |  <pre>  .withConsistentReads(CONSISTENT)</pre>  | EVENTUAL | Secara default, pembacaan konsisten salah untuk operasi baca. Ganti dengan .consistentRead(true) objek permintaan. | 
| Skema konversi dengan set marshallers/unmarshallers |  <pre>  .withConversionSchema(conversionSchema)</pre> Implementasi statis memberikan kompatibilitas mundur dengan versi yang lebih lama.  | V2\$1COMPATIBLE | Tidak berlaku. Ini adalah fitur lama yang mengacu pada bagaimana versi awal DynamoDB (V1) menyimpan tipe data, dan perilaku ini tidak akan dipertahankan di klien yang disempurnakan. Contoh perilaku di DynamoDB V1 adalah menyimpan boolean sebagai Number, bukan sebagai Boolean. | 
| Nama tabel |  <pre>  .withObjectTableNameResolver()<br />  .withTableNameOverride() <br />  .withTableNameResolver()</pre> Implementasi statis memberikan kompatibilitas mundur dengan versi yang lebih lama  | gunakan anotasi atau tebakan dari kelas |  Nama tabel didefinisikan saat memanggil `DynamoDbEnhancedClient#table()` metode.  | 
| Strategi beban pagination |  <pre>  .withPaginationLoadingStrategy(strategy)</pre>  Pilihannya adalah: LAZY\$1`LOADING`,, `EAGER_LOADING` atau `ITERATION_ONLY`  | LAZY\$1LOADING |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html)  | 
| Minta pengumpulan metrik |  <pre>  .withRequestMetricCollector(collector)</pre>  | null | Gunakan metricPublisher() ClientOverrideConfiguration saat membangun klien DynamoDB standar.  | 
| Simpan perilaku |  <pre>  .withSaveBehavior(SaveBehavior.CLOBBER) </pre> Pilihannya adalah `UPDATE``CLOBBER`,,`PUT`,`APPEND_SET`, atau`UPDATE_SKIP_NULL_ATTRIBUTES`.  | UPDATE |  Di V2, Anda menelepon `putItem()` atau `updateItem()` secara eksplisit. `CLOBBER or PUT`: Tindakan yang sesuai di v 2 memanggil`putItem()`. Tidak ada `CLOBBER` konfigurasi khusus. `UPDATE`: Sesuai dengan `updateItem()` `UPDATE_SKIP_NULL_ATTRIBUTES`: Sesuai dengan`updateItem()`. Kontrol perilaku pembaruan dengan setelan permintaan `ignoreNulls` dan anotasi/tag`DynamoDbUpdateBehavior`. `APPEND_SET`: Tidak didukung  | 
| Jenis konverter pabrik |  <pre>  .withTypeConverterFactory(typeConverterFactory) </pre>  | konverter tipe standar |  Atur kacang dengan menggunakan <pre>@DynamoDbBean(converterProviders = {ConverterProvider.class, <br />        DefaultAttributeConverterProvider.class})</pre>  | 

### Konfigurasi per operasi
<a name="dynamodb-mapping-configuration-per-op"></a>

Di V1, beberapa operasi, seperti`query()`, sangat dapat dikonfigurasi melalui objek “ekspresi” yang dikirimkan ke operasi. Contoh:

```
DynamoDBQueryExpression<Customer> emailBwQueryExpr = new DynamoDBQueryExpression<Customer>()
    .withRangeKeyCondition("Email",
        new Condition()
            .withComparisonOperator(ComparisonOperator.BEGINS_WITH)
            .withAttributeValueList(
                new AttributeValue().withS("my")));

mapper.query(Customer.class, emailBwQueryExpr);
```

Di V2, alih-alih menggunakan objek konfigurasi, Anda menetapkan parameter pada objek permintaan dengan menggunakan pembuat. Contoh:

```
QueryEnhancedRequest emailBw = QueryEnhancedRequest.builder()
    .queryConditional(QueryConditional
        .sortBeginsWith(kb -> kb
            .sortValue("my"))).build();

customerTable.query(emailBw);
```

## Kondisional
<a name="dynamodb-mapping-conditionals"></a>

Dalam V2, ekspresi kondisional dan penyaringan diekspresikan menggunakan `Expression` objek, yang merangkum kondisi dan pemetaan nama dan filter. 


| Kasus penggunaan | Operasi | V1 | V2 | 
| --- | --- | --- | --- | 
| Kondisi atribut yang diharapkan | save (), delete (), query (), scan () |  <pre>new DynamoDBSaveExpression()<br />  .withExpected(Collections.singletonMap(<br />      "otherAttribute", new ExpectedAttributeValue(false)))<br />  .withConditionalOperator(ConditionalOperator.AND);</pre>  | Usang; gunakan sebagai gantinya. ConditionExpression | 
| Ekspresi kondisi | hapus () |  <pre>deleteExpression.setConditionExpression("zipcode = :zipcode")<br />deleteExpression.setExpressionAttributeValues(...)<br /></pre>  |  <pre>Expression conditionExpression =<br />    Expression.builder()<br />        .expression("#key = :value OR #key1 = :value1")<br />        .putExpressionName("#key", "attribute")<br />        .putExpressionName("#key1", "attribute3")<br />        .putExpressionValue(":value", AttributeValues.stringValue("wrong"))<br />        .putExpressionValue(":value1", AttributeValues.stringValue("three"))<br />        .build();<br /><br />DeleteItemEnhancedRequest request = DeleteItemEnhancedRequest.builder()<br />         .conditionExpression(conditionExpression).build();</pre>  | 
| Ekspresi filter | query (), scan () |  <pre>scanExpression<br />  .withFilterExpression("#statename = :state")<br />  .withExpressionAttributeValues(attributeValueMapBuilder.build())<br />  .withExpressionAttributeNames(attributeNameMapBuilder.build())<br /></pre>  |  <pre>Map<String, AttributeValue> values = singletonMap(":key", stringValue("value"));<br />Expression filterExpression =<br />    Expression.builder()<br />        .expression("name = :key")<br />        .expressionValues(values)<br />        .build();<br />QueryEnhancedRequest request = QueryEnhancedRequest.builder()<br />    .filterExpression(filterExpression).build();<br /></pre>  | 
| Ekspresi kondisi untuk kueri | kueri () |  <pre>queryExpression.withKeyConditionExpression()</pre>  |  <pre>QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b<br />                .partitionValue("movie01"));<br /><br />QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()<br />                .queryConditional(keyEqual)<br />                .build();</pre>  | 

## Jenis konversi
<a name="dynamodb-mapping-type-conv"></a>

### Konverter default
<a name="dynamodb-mapping-type-conv-defaults"></a>

Di V2, SDK menyediakan satu set konverter default untuk semua tipe umum. Anda dapat mengubah konverter tipe baik di tingkat penyedia keseluruhan maupun untuk satu atribut. Anda dapat menemukan daftar konverter yang tersedia di referensi [AttributeConverter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html)API.

### Menetapkan konverter kustom untuk atribut
<a name="dynamodb-mapping-type-conv-anno"></a>

Di V1, Anda dapat membuat anotasi metode pengambil dengan `@DynamoDBTypeConverted` untuk menentukan kelas yang mengkonversi antara tipe atribut Java dan tipe atribut DynamoDB. Misalnya, `CurrencyFormatConverter` yang mengkonversi antara `Currency` tipe Java dan DynamoDB String dapat diterapkan seperti yang ditunjukkan pada cuplikan berikut.

```
@DynamoDBTypeConverted(converter = CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

Setara V2 dari cuplikan sebelumnya ditunjukkan di bawah ini.

```
@DynamoDbConvertedBy(CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

**catatan**  
Di V1, Anda dapat menerapkan anotasi ke atribut itu sendiri, tipe atau anotasi yang ditentukan pengguna, V2 mendukung penerapan anotasi hanya ke pengambil.

### Tambahkan pabrik atau penyedia konverter tipe
<a name="dynamodb-mapping-type-conv-factory"></a>

Di V1, Anda dapat menyediakan set konverter tipe Anda sendiri, atau mengganti tipe yang Anda pedulikan dengan menambahkan pabrik konverter tipe ke konfigurasi. Pabrik konverter tipe meluas`DynamoDBTypeConverterFactory`, dan penggantian dilakukan dengan mendapatkan referensi ke set default dan memperluasnya. Cuplikan berikut menunjukkan cara melakukan ini.

```
DynamoDBTypeConverterFactory typeConverterFactory =
    DynamoDBTypeConverterFactory.standard().override()
        .with(String.class, CustomBoolean.class, new DynamoDBTypeConverter<String, CustomBoolean>() {
            @Override
            public String convert(CustomBoolean bool) {
                return String.valueOf(bool.getValue());
            }
            @Override
            public CustomBoolean unconvert(String string) {
                return new CustomBoolean(Boolean.valueOf(string));
            }}).build();
DynamoDBMapperConfig config =
    DynamoDBMapperConfig.builder()
        .withTypeConverterFactory(typeConverterFactory)
        .build();
DynamoDBMapper mapperWithTypeConverterFactory = new DynamoDBMapper(dynamo, config);
```

V2 menyediakan fungsionalitas serupa melalui `@DynamoDbBean` anotasi. Anda dapat memberikan satu `AttributeConverterProvider` atau satu rantai pesanan `AttributeConverterProvider` s. Perhatikan bahwa jika Anda menyediakan rantai penyedia konverter atribut Anda sendiri, Anda akan mengganti penyedia konverter default dan harus memasukkannya ke dalam rantai untuk menggunakan konverter atributnya. 

```
@DynamoDbBean(converterProviders = {
   ConverterProvider1.class, 
   ConverterProvider2.class,
   DefaultAttributeConverterProvider.class})
public class Customer {
  ...
}
```

Bagian tentang [konversi atribut](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example) dalam panduan ini berisi contoh lengkap untuk V2.

# String menangani perbedaan antara versi 1 dan versi 2 dari SDK for Java
<a name="dynamodb-migration-string-handling"></a>

V1 dan V2 menangani string kosong secara berbeda saat mengirim data ke DynamoDB:
+ **V1**: Mengkonversi string kosong ke nilai null sebelum mengirim ke DynamoDB (menghasilkan tidak ada atribut)
+ **V2**: Mengirim string kosong sebagai nilai string kosong aktual ke DynamoDB

**penting**  
Setelah bermigrasi ke V2, jika Anda tidak ingin string kosong disimpan di DynamoDB, Anda harus menerapkan konverter khusus. Tanpa konverter khusus, V2 menyimpan string kosong sebagai atribut string kosong yang sebenarnya di item DynamoDB Anda, yang berbeda dari perilaku V1 menghilangkan atribut ini sepenuhnya.

**Example konverter khusus untuk V2 yang mengubah atribut string kosong menjadi null**  

```
/**
 * Custom converter that maintains V1 behavior by converting empty strings to null values
 * when writing to DynamoDB, ensuring compatibility with existing data. No attribute will be saved to DynamoDB.
 */
public class NullifyEmptyStringConverter implements AttributeConverter<String> {
    @Override
    public AttributeValue transformFrom(String value) {
        if (value == null || value.isEmpty()) {
            return AttributeValue.builder().nul(true).build();
        }
        return AttributeValue.builder().s(value).build();
    }

    @Override
    public String transformTo(AttributeValue attributeValue) {
        if (attributeValue.nul()) {
            return null;
        }
        return attributeValue.s();
    }

    @Override
    public EnhancedType<String> type() {
        return EnhancedType.of(String.class);
    }

    @Override
    public AttributeValueType attributeValueType() {
        return AttributeValueType.S;
    }
}

// V2 usage:
@DynamoDbBean
public class Customer {
    private String name;

    @DynamoDbConvertedBy(NullifyEmptyStringConverter.class)
    public String getName() {
        return name;
    }
}
```



# Perbedaan penguncian optimis antara versi 1 dan versi 2 dari SDK for Java
<a name="dynamodb-migrate-optimstic-locking"></a>

Baik V1 dan V2 menerapkan penguncian optimis dengan anotasi atribut yang menandai satu properti di kelas kacang Anda untuk menyimpan nomor versi.


**Perbedaan perilaku penguncian yang optimis**  

|  | V1 | V2 | 
| --- | --- | --- | 
| Anotasi kelas kacang | @DynamoDBVersionAttribute | @DynamoDbVersionAttribute(perhatikan bahwa V2 menggunakan huruf kecil “b”) | 
| Simpan awal | Atribut nomor versi disetel ke 1. |  Nilai awal untuk atribut versi ditetapkan dengan`@DynamoDbVersionAttribute(startAt = X)`. Nilai default-nya adalah 0.  | 
| Perbarui | Atribut nomor versi bertambah 1 jika pemeriksaan bersyarat memverifikasi bahwa nomor versi objek yang diperbarui cocok dengan nomor dalam database. |  Atribut nomor versi bertambah jika pemeriksaan bersyarat memverifikasi bahwa nomor versi objek yang diperbarui cocok dengan nomor dalam database. Atribut nomor versi ditambah dengan `incrementBy` opsi yang ditetapkan dengan`@DynamoDbVersionAttribute(incrementBy = X)`. Nilai default adalah 1.  | 
| Delete | DynamoDBMappermenambahkan pemeriksaan bersyarat bahwa nomor versi objek yang dihapus cocok dengan nomor versi dalam database. |  V2 tidak tidak secara otomatis menambahkan kondisi untuk operasi penghapusan. Anda harus menambahkan ekspresi kondisi secara manual jika Anda ingin mengontrol perilaku hapus. Dalam contoh berikut `recordVersion` adalah atribut versi kacang. <pre>// 1. Read the item and get its current version.<br />Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build());<br />AttributeValue currentVersion = item.getRecordVersion();<br /><br />// 2. Create conditional delete with the `currentVersion` value.<br />DeleteItemEnhancedRequest deleteItemRequest =<br />    DeleteItemEnhancedRequest.builder()<br />       .key(KEY)<br />       .conditionExpression(Expression.builder()<br />           .expression("recordVersion = :current_version_value")<br />           .putExpressionValue(":current_version_value", currentVersion)<br />           .build()).build();<br /><br />customerTable.deleteItem(deleteItemRequest);</pre>  | 
| Tulis Transaksional dengan Pemeriksaan Kondisi | Anda tidak dapat menggunakan kelas kacang yang dianotasi dengan @DynamoDBVersionAttribute metode. addConditionCheck | Anda dapat menggunakan kelas kacang dengan @DynamoDbVersionAttribute anotasi dalam metode addConditionCheck pembangun untuk transactWriteItems permintaan. | 
| Nonaktifkan | Nonaktifkan penguncian optimis dengan mengubah nilai  DynamoDBMapperConfig.SaveBehavior enumerasi dari ke. UPDATE CLOBBER |  Jangan gunakan `@DynamoDbVersionAttribute` anotasi.  | 

# Perbedaan setter yang lancar antara versi 1 dan versi 2 dari SDK for Java
<a name="dynamodb-migrate-fluent-setters"></a>

Anda dapat menggunakan POJOs dengan penyetel yang lancar di API pemetaan DynamoDB untuk V1 dan dengan V2 sejak versi 2.30.29. 

Misalnya, POJO berikut mengembalikan `Customer` instance dari `setName` metode:

```
// V1

@DynamoDBTable(tableName ="Customer")
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){
     this.name = name;
     return this;
  }
}
```

Namun, jika Anda menggunakan versi V2 sebelum 2.30.29, `setName` mengembalikan `Customer` instance dengan `name` nilai. `null`

```
// V2 prior to version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Bug: returns this instance with a `name` value of `null`.
  }
}
```

```
// Available in V2 since version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Returns this instance for method chaining with the `name` value set.
  }
}
```