다른 클래스의 속성을 평면화 - AWS SDK for Java 2.x

다른 클래스의 속성을 평면화

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

상속 사용

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

주석이 달린 빈을 사용

주석 접근 방식의 경우 두 클래스 모두 @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 옵션은 속성 기반 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; }

정적 스키마 사용

정적 스키마 접근 방식의 경우 빌더의 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();

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

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; }

구성 사용

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

주석이 달린 빈을 사용

@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; }

평면화 주석을 사용하여 필요한 만큼 다양한 적격 클래스를 병합할 수 있습니다. 다음과 같은 제약이 적용됩니다.

  • 병합한 후에는 모든 속성 이름이 고유해야 합니다.

  • 파티션 키, 정렬 키 또는 테이블 이름이 두 개를 초과해서는 안 됩니다.

정적 스키마 사용

정적 테이블 스키마를 빌드할 때는 빌더의 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();

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

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; }

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

다른 코드에 미치는 영향

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

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

예를 들어 평면화 구성 예제에 표시된 Customer 클래스를 record 속성을 평면화한 경우 및 사용하지 않은 경우와 비교해 보세요. 다음 표에 표시된 것처럼 JSON을 사용하여 차이점을 시각화할 수 있습니다.

평면화 사용 평면화 사용하지 않음
속성 3개 속성 2개
{ "id": "1", "createdDate": "today", "name": "my name" }
{ "id": "1", "record": { "createdDate": "today", "name": "my name" } }

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