

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

# 다른 클래스의 속성을 평면화
<a name="ddb-en-client-adv-features-flatmap"></a>

테이블 속성이 상속 또는 구성을 통해 여러 Java 클래스에 분산되어 있는 경우 DynamoDB 향상된 클라이언트 API는 속성을 하나의 클래스로 병합할 수 있도록 지원합니다.

## 상속 사용
<a name="ddb-en-client-adv-features-flatmap-inheritance"></a>

클래스에서 상속을 사용하는 경우 다음 방법을 사용하여 계층 구조를 평면화하세요.

### 주석이 달린 빈을 사용
<a name="ddb-en-client-adv-features-flatmap-inheritance-anno"></a>

주석 접근 방식의 경우 두 클래스 모두 `@DynamoDbBean` 주석을 포함해야 하며 클래스에는 기본 키 주석이 하나 이상 있어야 합니다.

다음은 상속 관계가 있는 데이터 클래스의 예를 보여줍니다.

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer extends GenericRecord {
    private String name;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

@DynamoDbBean
public abstract class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

Lombok의 [`onMethod` 옵션](https://projectlombok.org/features/experimental/onX)은 속성 기반 DynamoDB 주석(예: `@DynamoDbPartitionKey`)을 생성된 코드에 복사합니다.

```
@DynamoDbBean
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord {
    private String name;
}

@Data
@DynamoDbBean
public abstract class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

### 정적 스키마 사용
<a name="ddb-en-client-adv-features-flatmap-inheritance-static"></a>

정적 스키마 접근 방식의 경우 빌더의 `extend()` 메서드를 사용하여 부모 클래스의 속성을 자식 클래스로 축소합니다. 이는 다음 예에서 주석 라인 1 뒤에 표시됩니다.

```
        StaticTableSchema<org.example.tests.model.inheritance.stat.GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.GenericRecord.class)
                        // The partition key will be inherited by the top level mapper.
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getId)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getCreatedDate)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<org.example.tests.model.inheritance.stat.Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.Customer.class)
                        .newItemSupplier(org.example.tests.model.inheritance.stat.Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(org.example.tests.model.inheritance.stat.Customer::getName)
                                .setter(org.example.tests.model.inheritance.stat.Customer::setName))
                        // 1. Use the extend() method to collapse the parent attributes onto the child class.
                        .extend(GENERIC_RECORD_SCHEMA)     // All the attributes of the GenericRecord schema are added to Customer.
                        .build();
```

이전 정적 스키마 예제는 다음의 데이터 클래스를 사용합니다. 정적 테이블 스키마를 작성할 때 매핑이 정의되므로 데이터 클래스에는 주석이 필요하지 않습니다.

#### 데이터 클래스
<a name="gunk"></a>

------
#### [ Standard data class ]

```
public class Customer extends GenericRecord {
    private String name;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}


public abstract class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
```

------
#### [ Lombok ]

```
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord{
    private String name;
}

@Data
public abstract class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

## 구성 사용
<a name="ddb-en-client-adv-features-flatmap-comp"></a>

클래스에서 컴포지션을 사용하는 경우 다음 방법을 사용하여 계층 구조를 평면화하세요.

### 주석이 달린 빈을 사용
<a name="ddb-en-client-adv-features-flatmap-comp-anno"></a>

`@DynamoDbFlatten` 주석은 포함된 클래스를 평면화합니다.

다음 데이터 클래스 예제는 `@DynamoDbFlatten` 주석을 사용하여 포함된 `GenericRecord` 클래스의 모든 속성을 `Customer` 클래스에 효과적으로 추가합니다.

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer {
    private String name;
    private GenericRecord record;

    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    @DynamoDbFlatten
    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

@DynamoDbBean
public class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
@DynamoDbBean
public class Customer {
    private String name;
    @Getter(onMethod_=@DynamoDbFlatten)
    private GenericRecord record;
}

@Data
@DynamoDbBean
public class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

평면화 주석을 사용하여 필요한 만큼 다양한 적격 클래스를 병합할 수 있습니다. 다음과 같은 제약이 적용됩니다.
+ 병합한 후에는 모든 속성 이름이 고유해야 합니다.
+ 파티션 키, 정렬 키 또는 테이블 이름이 두 개를 초과해서는 안 됩니다.

### 정적 스키마 사용
<a name="ddb-en-client-adv-features-flatmap-comp-static"></a>

정적 테이블 스키마를 빌드할 때는 빌더의 `flatten()` 메서드를 사용하세요. 포함된 클래스를 식별하는 접근자 및 설정자 메서드도 제공합니다.

```
        StaticTableSchema<GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(GenericRecord.class)
                        .newItemSupplier(GenericRecord::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(GenericRecord::getId)
                                .setter(GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(GenericRecord::getCreatedDate)
                                .setter(GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getName)
                                .setter(Customer::setName))
                        // Because we are flattening a component object, we supply a getter and setter so the
                        // mapper knows how to access it.
                        .flatten(GENERIC_RECORD_SCHEMA, Customer::getRecord, Customer::setRecord)
                        .build();
```

이전 정적 스키마 예제는 다음의 데이터 클래스를 사용합니다.

#### 데이터 클래스
<a name="ddb-en-client-adv-features-flatmap-comp-static-supporting"></a>

------
#### [ Standard data class ]

```
public class Customer {
    private String name;
    private GenericRecord record;

    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

public class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
public class Customer {
    private String name;
    private GenericRecord record;
}

@Data
public class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

빌더 패턴을 사용하여 필요한 만큼 다양한 적격 클래스를 평면화할 수 있습니다.

## 다른 코드에 미치는 영향
<a name="ddb-en-client-adv-features-flatmap-compare"></a>

`@DynamoDbFlatten` 속성(또는 `flatten()` 빌더 메서드)을 사용하는 경우 DynamoDB의 항목은 구성된 객체의 각 속성에 대한 속성을 포함합니다. 또한 작성 객체의 속성도 포함됩니다.

반대로 작성된 클래스로 데이터 클래스에 주석을 달고 `@DynamoDbFlatten`를 사용하지 않는 경우 항목은 구성된 객체와 함께 단일 속성으로 저장됩니다.

예를 들어 [평면화 구성 예제](#ddb-en-client-adv-features-flatmap-comp-anno)에 표시된 `Customer` 클래스를 `record` 속성을 평면화한 경우 및 사용하지 않은 경우와 비교해 보세요. 다음 표에 표시된 것처럼 JSON을 사용하여 차이점을 시각화할 수 있습니다.


****  

| 평면화 사용 | 평면화 사용하지 않음 | 
| --- | --- | 
| 속성 3개 | 속성 2개 | 
|  <pre>{<br />  "id": "1",<br />  "createdDate": "today",<br />  "name": "my name"<br />}</pre>  |  <pre>{<br />  "id": "1",<br />  "record": {<br />      "createdDate": "today",<br />      "name": "my name"<br />  }<br />}</pre>  | 

특정 속성을 찾을 것으로 예상하는 다른 코드가 DynamoDB 테이블에 액세스하는 경우 차이가 중요해집니다.