

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

# Bekerja dengan dokumen JSON dengan Enhanced Document API untuk DynamoDB
<a name="ddb-en-client-doc-api"></a>

[Enhanced Document API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/package-summary.html) for AWS SDK for Java 2.x dirancang untuk bekerja dengan data berorientasi dokumen yang tidak memiliki skema tetap. Namun, ini juga memungkinkan Anda menggunakan kelas khusus untuk memetakan atribut individual.

 Enhanced Document API adalah penerus [Document API](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/DynamoDB.html) dari AWS SDK untuk Java v1.x.

**Contents**
+ [Mulai menggunakan Enhanced Document API](ddb-en-client-doc-api-steps.md)
  + [Buat `DocumentTableSchema` dan a `DynamoDbTable`](ddb-en-client-doc-api-steps.md#ddb-en-client-doc-api-steps-createschema)
+ [Membangun dokumen yang disempurnakan](ddb-en-client-doc-api-steps-create-ed.md)
  + [Membangun dari string JSON](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromJson)
  + [Membangun dari elemen individu](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromparts)
+ [Lakukan operasi CRUD](ddb-en-client-doc-api-steps-use.md)
+ [Akses atribut dokumen yang disempurnakan sebagai objek khusus](ddb-en-client-doc-api-convert.md)
+ [Gunakan `EnhancedDocument` tanpa DynamoDB](ddb-en-client-doc-api-standalone.md)

# Mulai menggunakan Enhanced Document API
<a name="ddb-en-client-doc-api-steps"></a>

Enhanced Document API memerlukan [dependensi](ddb-en-client-getting-started.md#ddb-en-client-gs-dep) yang sama yang diperlukan untuk DynamoDB Enhanced Client API. Ini juga membutuhkan [`DynamoDbEnhancedClient`contoh](ddb-en-client-getting-started-dynamodbTable.md#ddb-en-client-getting-started-dynamodbTable-eclient) seperti yang ditunjukkan di awal topik ini.

Karena API Dokumen yang Ditingkatkan dirilis dengan versi 2.20.3 AWS SDK for Java 2.x, Anda memerlukan versi itu atau lebih tinggi.

## Buat `DocumentTableSchema` dan a `DynamoDbTable`
<a name="ddb-en-client-doc-api-steps-createschema"></a>

Untuk menjalankan perintah terhadap tabel DynamoDB menggunakan Enhanced Document API, kaitkan tabel dengan objek resource < > sisi [DynamoDbTableklien EnhancedDocument](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html). 

`table()`Metode klien yang disempurnakan membuat `DynamoDbTable<EnhancedDocument>` instance dan membutuhkan parameter untuk nama tabel DynamoDB dan a. `DocumentTableSchema` 

Pembangun untuk a [DocumentTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/DocumentTableSchema.html)memerlukan kunci indeks utama dan satu atau lebih penyedia konverter atribut. `AttributeConverterProvider.defaultProvider()`Metode ini menyediakan konverter untuk [tipe default](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/package-summary.html). Itu harus ditentukan bahkan jika Anda menyediakan penyedia konverter atribut khusus. Anda dapat menambahkan kunci indeks sekunder opsional ke pembangun.

Cuplikan kode berikut menunjukkan kode yang menghasilkan representasi sisi klien dari tabel DynamoDB yang menyimpan objek tanpa skema. `person` `EnhancedDocument`

```
DynamoDbTable<EnhancedDocument> documentDynamoDbTable = 
                enhancedClient.table("person",
                        TableSchema.documentSchemaBuilder()
                            // Specify the primary key attributes.
                            .addIndexPartitionKey(TableMetadata.primaryIndexName(),"id", AttributeValueType.S)
                            .addIndexSortKey(TableMetadata.primaryIndexName(), "lastName", AttributeValueType.S)
                            // Specify attribute converter providers. Minimally add the default one.
                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                            .build());
                                                         
// Call documentTable.createTable() if "person" does not exist in DynamoDB.
// createTable() should be called only one time.
```

Berikut ini menunjukkan representasi JSON dari `person` objek yang digunakan di seluruh bagian ini.

### Objek JSON `person`
<a name="ddb-en-client-doc-api-steps-createschema-obj"></a>

```
{
  "id": 1,
  "firstName": "Richard",
  "lastName": "Roe",
  "age": 25,
  "addresses":
    {
      "home": {
        "zipCode": "00000",
        "city": "Any Town",
        "state": "FL",
        "street": "123 Any Street"
      },
      "work": {
        "zipCode": "00001",
        "city": "Anywhere",
        "state": "FL",
        "street": "100 Main Street"
      }
    },
  "hobbies": [
    "Hobby 1",
    "Hobby 2"
  ],
  "phoneNumbers": [
    {
      "type": "Home",
      "number": "555-0100"
    },
    {
      "type": "Work",
      "number": "555-0119"
    }
  ]
}
```

# Membangun dokumen yang disempurnakan
<a name="ddb-en-client-doc-api-steps-create-ed"></a>

An `[EnhancedDocument](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html)` merupakan objek tipe dokumen yang memiliki struktur kompleks dengan atribut bersarang. Sebuah `EnhancedDocument` membutuhkan atribut tingkat atas yang cocok dengan atribut kunci utama yang ditentukan untuk atribut. `DocumentTableSchema` Konten yang tersisa bersifat arbitrer dan dapat terdiri dari atribut tingkat atas dan juga atribut yang sangat bersarang.

Anda membuat `EnhancedDocument` instance dengan menggunakan builder yang menyediakan beberapa cara untuk menambahkan elemen.

## Membangun dari string JSON
<a name="ddb-en-client-doc-api-steps-create-ed-fromJson"></a>

Dengan string JSON, Anda dapat membangun panggilan `EnhancedDocument` dalam satu metode. Cuplikan berikut membuat `EnhancedDocument` dari string JSON dikembalikan oleh metode helper. `jsonPerson()` `jsonPerson()`Metode mengembalikan versi string JSON dari [objek orang](ddb-en-client-doc-api-steps.md#ddb-en-client-doc-api-steps-createschema-obj) yang ditunjukkan sebelumnya.

```
EnhancedDocument document = 
        EnhancedDocument.builder()
                        .json( jsonPerson() )
                        .build());
```

## Membangun dari elemen individu
<a name="ddb-en-client-doc-api-steps-create-ed-fromparts"></a>

Atau, Anda dapat membangun sebuah `EnhancedDocument` instance dari komponen individual menggunakan metode type-safe dari builder.

Contoh berikut membangun dokumen yang `person` disempurnakan mirip dengan dokumen yang disempurnakan yang dibangun dari string JSON pada contoh sebelumnya.

```
        /* Define the shape of an address map whose JSON representation looks like the following.
           Use 'addressMapEnhancedType' in the following EnhancedDocument.builder() to simplify the code.
           "home": {
             "zipCode": "00000",
             "city": "Any Town",
             "state": "FL",
             "street": "123 Any Street"
           }*/
        EnhancedType<Map<String, String>> addressMapEnhancedType =
                EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(String.class));


        //  Use the builder's typesafe methods to add elements to the enhanced document.
        EnhancedDocument personDocument = EnhancedDocument.builder()
                .putNumber("id", 50)
                .putString("firstName", "Shirley")
                .putString("lastName", "Rodriguez")
                .putNumber("age", 53)
                .putNull("nullAttribute")
                .putJson("phoneNumbers", phoneNumbersJSONString())
                /* Add the map of addresses whose JSON representation looks like the following.
                        {
                          "home": {
                            "zipCode": "00000",
                            "city": "Any Town",
                            "state": "FL",
                            "street": "123 Any Street"
                          }
                        } */
                .putMap("addresses", getAddresses(), EnhancedType.of(String.class), addressMapEnhancedType)
                .putList("hobbies", List.of("Theater", "Golf"), EnhancedType.of(String.class))
                .build();
```

### Metode pembantu
<a name="ddb-en-client-doc-api-steps-use-fromparts-helpers"></a>

```
    private static String phoneNumbersJSONString() {
        return "  [" +
                "    {" +
                "      \"type\": \"Home\"," +
                "      \"number\": \"555-0140\"" +
                "    }," +
                "    {" +
                "      \"type\": \"Work\"," +
                "      \"number\": \"555-0155\"" +
                "    }" +
                "  ]";
    }

    private static Map<String, Map<String, String>> getAddresses() {
        return Map.of(
                "home", Map.of(
                        "zipCode", "00002",
                        "city", "Any Town",
                        "state", "ME",
                        "street", "123 Any Street"));

    }
```

# Lakukan operasi CRUD
<a name="ddb-en-client-doc-api-steps-use"></a>

Setelah Anda mendefinisikan sebuah `EnhancedDocument` instance, Anda dapat menyimpannya ke tabel DynamoDB. Cuplikan kode berikut menggunakan [personDocument](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromparts) yang dibuat dari elemen individual.

```
documentDynamoDbTable.putItem(personDocument);
```

Setelah Anda membaca instance dokumen yang disempurnakan dari DynamoDB, Anda dapat mengekstrak nilai atribut individual menggunakan getter seperti yang ditunjukkan dalam cuplikan kode berikut yang mengakses data yang disimpan dari. `personDocument` Atau, Anda dapat mengekstrak konten lengkap ke string JSON seperti yang ditunjukkan pada bagian terakhir dari kode contoh.

```
        // Read the item.
        EnhancedDocument personDocFromDb = documentDynamoDbTable.getItem(Key.builder().partitionValue(50).build());

        // Access top-level attributes.
        logger.info("Name: {} {}", personDocFromDb.getString("firstName"), personDocFromDb.getString("lastName"));
        // Name: Shirley Rodriguez

        // Typesafe access of a deeply nested attribute. The addressMapEnhancedType shown previously defines the shape of an addresses map.
        Map<String, Map<String, String>> addresses = personDocFromDb.getMap("addresses", EnhancedType.of(String.class), addressMapEnhancedType);
        addresses.keySet().forEach(k -> logger.info(addresses.get(k).toString()));
        // {zipCode=00002, city=Any Town, street=123 Any Street, state=ME}

        // Alternatively, work with AttributeValue types checking along the way for deeply nested attributes.
        Map<String, AttributeValue> addressesMap = personDocFromDb.getMapOfUnknownType("addresses");
        addressesMap.keySet().forEach((String k) -> {
            logger.info("Looking at data for [{}] address", k);
            // Looking at data for [home] address
            AttributeValue value = addressesMap.get(k);
            AttributeValue cityValue = value.m().get("city");
            if (cityValue != null) {
                logger.info(cityValue.s());
                // Any Town
            }
        });

        List<AttributeValue> phoneNumbers = personDocFromDb.getListOfUnknownType("phoneNumbers");
        phoneNumbers.forEach((AttributeValue av) -> {
            if (av.hasM()) {
                AttributeValue type = av.m().get("type");
                if (type.s() != null) {
                    logger.info("Type of phone: {}", type.s());
                    // Type of phone: Home
                    // Type of phone: Work
                }
            }
        });

        String jsonPerson = personDocFromDb.toJson();
        logger.info(jsonPerson);
        // {"firstName":"Shirley","lastName":"Rodriguez","addresses":{"home":{"zipCode":"00002","city":"Any Town","street":"123 Any Street","state":"ME"}},"hobbies":["Theater","Golf"],
        //     "id":50,"nullAttribute":null,"age":53,"phoneNumbers":[{"number":"555-0140","type":"Home"},{"number":"555-0155","type":"Work"}]}
```

`EnhancedDocument`instance dapat digunakan dengan metode apa pun dari `[DynamoDbTable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)` atau [DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html)di tempat kelas data yang dipetakan.

# Akses atribut dokumen yang disempurnakan sebagai objek khusus
<a name="ddb-en-client-doc-api-convert"></a>

Selain menyediakan API untuk membaca dan menulis atribut dengan struktur tanpa skema, API Dokumen yang Ditingkatkan memungkinkan Anda mengonversi atribut ke dan dari instance kelas khusus.

Enhanced Document API menggunakan `AttributeConverterProvider` s dan `AttributeConverter` s yang ditampilkan di bagian [konversi atribut kontrol](ddb-en-client-adv-features-conversion.md) sebagai bagian dari DynamoDB Enhanced Client API.

Dalam contoh berikut, kita menggunakan a `CustomAttributeConverterProvider` dengan `AddressConverter` kelas bersarang untuk mengkonversi `Address` objek. 

Contoh ini menunjukkan bahwa Anda dapat mencampur data dari kelas dan juga data dari struktur yang dibangun sesuai kebutuhan. Contoh ini juga menunjukkan bahwa kelas kustom dapat digunakan pada setiap tingkat struktur bersarang. `Address`Objek dalam contoh ini adalah nilai yang digunakan dalam peta.

```
    public static void attributeToAddressClassMappingExample(DynamoDbEnhancedClient enhancedClient, DynamoDbClient standardClient) {
        String tableName = "customer";

        // Define the DynamoDbTable for an enhanced document.
        // The schema builder provides methods for attribute converter providers and keys.
        DynamoDbTable<EnhancedDocument> documentDynamoDbTable = enhancedClient.table(tableName,
                DocumentTableSchema.builder()
                        // Add the CustomAttributeConverterProvider along with the default when you build the table schema.
                        .attributeConverterProviders(
                                List.of(
                                        new CustomAttributeConverterProvider(),
                                        AttributeConverterProvider.defaultProvider()))
                        .addIndexPartitionKey(TableMetadata.primaryIndexName(), "id", AttributeValueType.N)
                        .addIndexSortKey(TableMetadata.primaryIndexName(), "lastName", AttributeValueType.S)
                        .build());
        // Create the DynamoDB table if needed.
        documentDynamoDbTable.createTable();
        waitForTableCreation(tableName, standardClient);


        // The getAddressesForCustomMappingExample() helper method that provides 'addresses' shows the use of a custom Address class
        // rather than using a Map<String, Map<String, String> to hold the address data.
        Map<String, Address> addresses = getAddressesForCustomMappingExample();

        // Build an EnhancedDocument instance to save an item with a mix of structures defined as needed and static classes.
        EnhancedDocument personDocument = EnhancedDocument.builder()
                .putNumber("id", 50)
                .putString("firstName", "Shirley")
                .putString("lastName", "Rodriguez")
                .putNumber("age", 53)
                .putNull("nullAttribute")
                .putJson("phoneNumbers", phoneNumbersJSONString())
                // Note the use of 'EnhancedType.of(Address.class)' instead of the more generic
                // 'EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(String.class))' that was used in a previous example.
                .putMap("addresses", addresses, EnhancedType.of(String.class), EnhancedType.of(Address.class))
                .putList("hobbies", List.of("Hobby 1", "Hobby 2"), EnhancedType.of(String.class))
                .build();
        // Save the item to DynamoDB.
        documentDynamoDbTable.putItem(personDocument);

        // Retrieve the item just saved.
        EnhancedDocument srPerson = documentDynamoDbTable.getItem(Key.builder().partitionValue(50).sortValue("Rodriguez").build());

        // Access the addresses attribute.
        Map<String, Address> srAddresses = srPerson.get("addresses",
                EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(Address.class)));

        srAddresses.keySet().forEach(k -> logger.info(addresses.get(k).toString()));

        documentDynamoDbTable.deleteTable();

// The content logged to the console shows that the saved maps were converted to Address instances.
Address{street='123 Main Street', city='Any Town', state='NC', zipCode='00000'}
Address{street='100 Any Street', city='Any Town', state='NC', zipCode='00000'}
```

## `CustomAttributeConverterProvider`kode
<a name="ddb-en-client-doc-api-convert-provider"></a>

```
public class CustomAttributeConverterProvider implements AttributeConverterProvider {

    private final Map<EnhancedType<?>, AttributeConverter<?>> converterCache = ImmutableMap.of(
            // 1. Add AddressConverter to the internal cache.
            EnhancedType.of(Address.class), new AddressConverter());

    public static CustomAttributeConverterProvider create() {
        return new CustomAttributeConverterProvider();
    }

    // 2. The enhanced client queries the provider for attribute converters if it
    //    encounters a type that it does not know how to convert.
    @SuppressWarnings("unchecked")
    @Override
    public <T> AttributeConverter<T> converterFor(EnhancedType<T> enhancedType) {
        return (AttributeConverter<T>) converterCache.get(enhancedType);
    }

    // 3. Custom attribute converter
    private class AddressConverter implements AttributeConverter<Address> {
        // 4. Transform an Address object into a DynamoDB map.
        @Override
        public AttributeValue transformFrom(Address address) {

            Map<String, AttributeValue> attributeValueMap = Map.of(
                    "street", AttributeValue.fromS(address.getStreet()),
                    "city", AttributeValue.fromS(address.getCity()),
                    "state", AttributeValue.fromS(address.getState()),
                    "zipCode", AttributeValue.fromS(address.getZipCode()));

            return AttributeValue.fromM(attributeValueMap);
        }

        // 5. Transform the DynamoDB map attribute to an Address oject.
        @Override
        public Address transformTo(AttributeValue attributeValue) {
            Map<String, AttributeValue> m = attributeValue.m();
            Address address = new Address();
            address.setStreet(m.get("street").s());
            address.setCity(m.get("city").s());
            address.setState(m.get("state").s());
            address.setZipCode(m.get("zipCode").s());

            return address;
        }

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

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

## `Address` kelas
<a name="ddb-en-client-doc-api-convert-address"></a>

```
public class Address {
                  private String street;
                  private String city;
                  private String state;
                  private String zipCode;

                  public Address() {
                  }

                  public String getStreet() {
                  return this.street;
                  }

                  public String getCity() {
                  return this.city;
                  }

                  public String getState() {
                  return this.state;
                  }

                  public String getZipCode() {
                  return this.zipCode;
                  }

                  public void setStreet(String street) {
                  this.street = street;
                  }

                  public void setCity(String city) {
                  this.city = city;
                  }

                  public void setState(String state) {
                  this.state = state;
                  }

                  public void setZipCode(String zipCode) {
                  this.zipCode = zipCode;
                  }
                  }
```

## Metode pembantu yang menyediakan alamat
<a name="ddb-en-client-doc-api-convert-helper"></a>

Metode pembantu berikut menyediakan peta yang menggunakan `Address` instance kustom untuk nilai daripada `Map<String, String>` contoh generik untuk nilai.

```
    private static Map<String, Address> getAddressesForCustomMappingExample() {
        Address homeAddress = new Address();
        homeAddress.setStreet("100 Any Street");
        homeAddress.setCity("Any Town");
        homeAddress.setState("NC");
        homeAddress.setZipCode("00000");

        Address workAddress = new Address();
        workAddress.setStreet("123 Main Street");
        workAddress.setCity("Any Town");
        workAddress.setState("NC");
        workAddress.setZipCode("00000");

        return Map.of("home", homeAddress,
                "work", workAddress);
    }
```

# Gunakan `EnhancedDocument` tanpa DynamoDB
<a name="ddb-en-client-doc-api-standalone"></a>

Meskipun Anda biasanya menggunakan instance `EnhancedDocument` untuk membaca dan menulis item DynamoDB tipe dokumen, itu juga dapat digunakan secara independen dari DynamoDB. 

Anda dapat menggunakan kemampuan mereka `EnhancedDocuments` untuk mengkonversi antara string JSON atau objek kustom ke peta tingkat rendah `AttributeValues` seperti yang ditunjukkan dalam contoh berikut.

```
    public static void conversionWithoutDynamoDbExample() {
        Address address = new Address();
        address.setCity("my city");
        address.setState("my state");
        address.setStreet("my street");
        address.setZipCode("00000");

        // Build an EnhancedDocument instance for its conversion functionality alone.
        EnhancedDocument addressEnhancedDoc = EnhancedDocument.builder()
                // Important: You must specify attribute converter providers when you build an EnhancedDocument instance not used with a DynamoDB table.
                .attributeConverterProviders(new CustomAttributeConverterProvider(), DefaultAttributeConverterProvider.create())
                .put("addressDoc", address, Address.class)
                .build();

        // Convert address to a low-level item representation.
        final Map<String, AttributeValue> addressAsAttributeMap = addressEnhancedDoc.getMapOfUnknownType("addressDoc");
        logger.info("addressAsAttributeMap: {}", addressAsAttributeMap.toString());

        // Convert address to a JSON string.
        String addressAsJsonString = addressEnhancedDoc.getJson("addressDoc");
        logger.info("addressAsJsonString: {}", addressAsJsonString);
        // Convert addressEnhancedDoc back to an Address instance.
        Address addressConverted =  addressEnhancedDoc.get("addressDoc", Address.class);
        logger.info("addressConverted: {}", addressConverted.toString());
    }

   /* Console output:
          addressAsAttributeMap: {zipCode=AttributeValue(S=00000), state=AttributeValue(S=my state), street=AttributeValue(S=my street), city=AttributeValue(S=my city)}
          addressAsJsonString: {"zipCode":"00000","state":"my state","street":"my street","city":"my city"}
          addressConverted: Address{street='my street', city='my city', state='my state', zipCode='00000'}
   */
```

**catatan**  
Bila Anda menggunakan dokumen yang disempurnakan independen dari tabel DynamoDB, pastikan Anda secara eksplisit menetapkan penyedia konverter atribut pada pembangun.  
Sebaliknya, skema tabel dokumen memasok penyedia konverter ketika dokumen yang disempurnakan digunakan dengan tabel DynamoDB.