기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
중첩된 개체의 null 속성을 저장하지 마세요
@DynamoDbIgnoreNulls
주석을 적용하여 DynamoDB에 데이터 클래스 객체를 저장할 때 중첩된 객체의 null 속성을 건너뛸 수 있습니다. 반대로 null 값이 있는 최상위 속성은 데이터베이스에 저장되지 않습니다.
주석이 작동하는 방식을 설명하기 위해 코드 예제에서는 다음 두 개의 Bean을 사용합니다.
다음 데이터 클래스에는 두 개의 InnerBean
필드가 있습니다. 접근자 메서드 getInnerBeanWithoutAnno()
에는 주석이 달려 있지 않습니다. getInnerBeanWithIgnoreNullsAnno()
메서드에는 @DynamoDbIgnoreNulls
로 주석이 달려 있습니다.
@DynamoDbBean public class MyBean { private String id; private String name; private InnerBean innerBeanWithoutAnno; private InnerBean innerBeanWithIgnoreNullsAnno; @DynamoDbPartitionKey public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public InnerBean getInnerBeanWithoutAnno() { return innerBeanWithoutAnno; } public void setInnerBeanWithoutAnno(InnerBean innerBeanWithoutAnno) { this.innerBeanWithoutAnno = innerBeanWithoutAnno; } @DynamoDbIgnoreNulls public InnerBean getInnerBeanWithIgnoreNullsAnno() { return innerBeanWithIgnoreNullsAnno; } public void setInnerBeanWithIgnoreNullsAnno(InnerBean innerBeanWithAnno) { this.innerBeanWithIgnoreNullsAnno = innerBeanWithAnno; } @Override public String toString() { return new StringJoiner(", ", MyBean.class.getSimpleName() + "[", "]") .add("innerBeanWithoutAnno=" + innerBeanWithoutAnno) .add("innerBeanWithIgnoreNullsAnno=" + innerBeanWithIgnoreNullsAnno) .add("id='" + id + "'") .add("name='" + name + "'") .toString(); } }
다음 InnerBean
클래스의 인스턴스는 MyBean
의 필드이며 다음 예제 코드에서 사용됩니다.
@DynamoDbBean public class InnerBean { private String innerBeanFieldString; private Integer innerBeanFieldInteger; public String getInnerBeanFieldString() { return innerBeanFieldString; } public void setInnerBeanFieldString(String innerBeanFieldString) { this.innerBeanFieldString = innerBeanFieldString; } public Integer getInnerBeanFieldInteger() { return innerBeanFieldInteger; } public void setInnerBeanFieldInteger(Integer innerBeanFieldInteger) { this.innerBeanFieldInteger = innerBeanFieldInteger; } @Override public String toString() { return new StringJoiner(", ", InnerBean.class.getSimpleName() + "[", "]") .add("innerBeanFieldString='" + innerBeanFieldString + "'") .add("innerBeanFieldInteger=" + innerBeanFieldInteger) .toString(); } }
다음 코드 예제에서는 InnerBean
객체를 만들고 객체의 두 속성 중 하나만 값으로 설정합니다.
public void ignoreNullsAnnoUsingPutItemExample(DynamoDbTable<MyBean> myBeanTable) { // Create an InnerBean object and give only one attribute a value. InnerBean innerBeanOneAttributeSet = new InnerBean(); innerBeanOneAttributeSet.setInnerBeanFieldInteger(200); // Create a MyBean instance and use the same InnerBean instance both for attributes. MyBean bean = new MyBean(); bean.setId("1"); bean.setInnerBeanWithoutAnno(innerBeanOneAttributeSet); bean.setInnerBeanWithIgnoreNullsAnno(innerBeanOneAttributeSet); Map<String, AttributeValue> itemMap = myBeanTable.tableSchema().itemToMap(bean, true); logger.info(itemMap.toString()); // Log the map that is sent to the database. // {innerBeanWithIgnoreNullsAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200)}), id=AttributeValue(S=1), innerBeanWithoutAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200), innerBeanFieldString=AttributeValue(NUL=true)})} // Save the MyBean object to the table. myBeanTable.putItem(bean); }
DynamoDB로 전송되는 하위 수준 데이터를 시각화하기 위해 코드는 MyBean
객체를 저장하기 전에 속성 맵을 기록합니다.
로깅된 출력은 innerBeanWithIgnoreNullsAnno
가 속성 하나를 출력함을 보여줍니다.
innerBeanWithIgnoreNullsAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200)})
innerBeanWithoutAnno
인스턴스는 두 개의 속성을 출력합니다. 한 속성의 값은 200이고 다른 하나는 null 값 속성입니다.
innerBeanWithoutAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200), innerBeanFieldString=AttributeValue(NUL=true)})
다음 JSON 표현을 사용하면 DynamoDB에 저장된 데이터를 더 쉽게 확인할 수 있습니다.
{ "id": { "S": "1" }, "innerBeanWithIgnoreNullsAnno": { "M": { "innerBeanFieldInteger": { "N": "200" } } }, "innerBeanWithoutAnno": { "M": { "innerBeanFieldInteger": { "N": "200" }, "innerBeanFieldString": { "NULL": true } } } }
다음 StaticTableSchema
버전의 테이블 스키마를 데이터 클래스 주석에 사용할 수 있습니다.
public static TableSchema<MyBean> buildStaticSchemas() { StaticTableSchema<InnerBean> innerBeanStaticTableSchema = StaticTableSchema.builder(InnerBean.class) .newItemSupplier(InnerBean::new) .addAttribute(String.class, a -> a.name("innerBeanFieldString") .getter(InnerBean::getInnerBeanFieldString) .setter(InnerBean::setInnerBeanFieldString)) .addAttribute(Integer.class, a -> a.name("innerBeanFieldInteger") .getter(InnerBean::getInnerBeanFieldInteger) .setter(InnerBean::setInnerBeanFieldInteger)) .build(); return StaticTableSchema.builder(MyBean.class) .newItemSupplier(MyBean::new) .addAttribute(String.class, a -> a.name("id") .getter(MyBean::getId) .setter(MyBean::setId) .addTag(primaryPartitionKey())) .addAttribute(String.class, a -> a.name("name") .getter(MyBean::getName) .setter(MyBean::setName)) .addAttribute(EnhancedType.documentOf(InnerBean.class, innerBeanStaticTableSchema), a -> a.name("innerBeanWithoutAnno") .getter(MyBean::getInnerBeanWithoutAnno) .setter(MyBean::setInnerBeanWithoutAnno)) .addAttribute(EnhancedType.documentOf(InnerBean.class, innerBeanStaticTableSchema, b -> b.ignoreNulls(true)), a -> a.name("innerBeanWithIgnoreNullsAnno") .getter(MyBean::getInnerBeanWithIgnoreNullsAnno) .setter(MyBean::setInnerBeanWithIgnoreNullsAnno)) .build(); }