

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 변경할 수 없는 데이터 클래스로 작업
<a name="ddb-en-client-use-immut"></a>

DynamoDB 향상된 클라이언트 API의 매핑 기능은 변경할 수 없는 데이터 클래스와 함께 작동합니다. 불변 클래스에는 접근자만 포함되며 SDK가 클래스의 인스턴스를 생성하는 데 사용하는 빌더 클래스가 필요합니다. 변경 불가능한 클래스는 [Customer 클래스에](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) 표시된 `@DynamoDbBean` 주석을 사용하는 대신 사용할 빌더 클래스를 나타내는 매개변수를 사용하는 `@DynamoDbImmutable` 주석을 사용합니다.

다음 클래스는 `Customer`의 변경할 수 없는 버전입니다.

```
package org.example.tests.model.immutable;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbImmutable(builder = CustomerImmutable.Builder.class)
public class CustomerImmutable {
    private final String id;
    private final String name;
    private final String email;
    private final Instant regDate;

    private CustomerImmutable(Builder b) {
        this.id = b.id;
        this.email = b.email;
        this.name = b.name;
        this.regDate = b.regDate;
    }

    // This method will be automatically discovered and used by the TableSchema.
    public static Builder builder() { return new Builder(); }

    @DynamoDbPartitionKey
    public String id() { return this.id; }

    @DynamoDbSortKey
    public String email() { return this.email; }

    @DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name")
    public String name() { return this.name; }

    @DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"})
    public Instant regDate() { return this.regDate; }

    public static final class Builder {
        private String id;
        private String email;
        private String name;
        private Instant regDate;

        // The private Builder constructor is visible to the enclosing CustomerImmutable class.
        private Builder() {}

        public Builder id(String id) { this.id = id; return this; }
        public Builder email(String email) { this.email = email; return this; }
        public Builder name(String name) { this.name = name; return this; }
        public Builder regDate(Instant regDate) { this.regDate = regDate; return this; }

        // This method will be automatically discovered and used by the TableSchema.
        public CustomerImmutable build() { return new CustomerImmutable(this); }
    }
}
```

`@DynamoDbImmutable`를 사용해 데이터 클래스에 주석을 달 때는 다음 요구 사항을 충족해야 합니다.

1. `Object.class`의 오버라이드도 아니고 `@DynamoDbIgnore`를 사용해 주석이 추가되지도 않은 모든 메서드는 DynamoDB 테이블의 속성에 대한 접근자여야 합니다.

1. 모든 접근자는 빌더 클래스에 해당하는 대소문자를 구분하는 설정자를 가져야 합니다.

1. 다음 시공 조건 중 하나만 충족해야 합니다.
   + 빌더 클래스에는 공개 기본 생성자가 있어야 합니다.
   + 데이터 클래스에는 매개 변수를 사용하지 않고 빌더 클래스의 인스턴스를 반환하는 이름이 `builder()`로 지정된 공용 정적 메서드가 있어야 합니다. 이 옵션은 변경할 수 없는 `Customer` 클래스에 표시됩니다.

1.  빌더 클래스에는 매개 변수를 사용하지 않고 변경 불가능한 클래스의 인스턴스를 반환하는 `build()`로 이름이 지정된 공용 메서드가 있어야 합니다.

변경할 수 없는 클래스를 위한 `TableSchema`를 만들려면 다음 코드 조각과 같이 `TableSchema`의 `fromImmutableClass()` 메서드를 사용하세요.

```
static final TableSchema<CustomerImmutable> customerImmutableTableSchema = 
                         TableSchema.fromImmutableClass(CustomerImmutable.class);
```

변경 가능한 클래스에서 DynamoDB 테이블을 생성할 수 있는 것처럼, 다음 코드 조각 예제와 같이 `DynamoDbTable`의 `createTable()`를 *한 번* 호출하여 변경할 수 없는 클래스에서 테이블을 생성할 수 있습니다.

```
static void createTableFromImmutable(DynamoDbEnhancedClient enhancedClient, String tableName, DynamoDbWaiter waiter){
    // First, create an in-memory representation of the table using the 'table()' method of the DynamoDb Enhanced Client.
    // 'table()' accepts a name for the table and a TableSchema instance that you created previously.
    DynamoDbTable<CustomerImmutable> customerDynamoDbTable = enhancedClient
            .table(tableName, TableSchema.fromImmutableClass(CustomerImmutable.class));
        
    // Second, call the 'createTable()' method on the DynamoDbTable instance.
    customerDynamoDbTable.createTable();
    waiter.waitUntilTableExists(b -> b.tableName(tableName));
}
```

## Lombok과 같은 타사 라이브러리를 사용
<a name="ddb-en-client-use-immut-lombok"></a>

[Project Lombok과](https://projectlombok.org/) 같은 타사 라이브러리는 변경할 수 없는 객체와 관련된 보일러러플레이트 코드를 생성하는 데 도움이 됩니다. DynamoDB 향상된 클라이언트 API는 데이터 클래스가 이 단원에 자세히 설명된 규칙을 따르는 한 이러한 라이브러리와 함께 작동합니다.

다음 예제에서는 Lombok 주석이 있는 변경 불가능한 `CustomerImmutable` 클래스를 보여줍니다. Lombok의 `onMethod` 기능이 속성 기반 DynamoDB 주석(예:`@DynamoDbPartitionKey`)을 생성된 코드에 복사하는 방법에 주목하세요.

```
@Value
@Builder
@DynamoDbImmutable(builder = Customer.CustomerBuilder.class)
public class Customer {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;

    @Getter(onMethod_=@DynamoDbSortKey)
    private String email;

    @Getter(onMethod_=@DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name"))
    private String name;

    @Getter(onMethod_=@DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"}))
    private Instant createdDate;
}
```