1

我有嵌套对象(组合)用于表示我想要存储的数据,并使用 Dyanmodb 增强客户端作为 AWS Java 版本 2 api 的一部分。在自述文件中,它解释了如何展平对象。在 api 的版本之一中,能够将对象列表作为 json 文档存储在 dyanmodb 中。

public class Customer{
  private String name;
  private List<GenericRecord> recordMetadata;
  //getters and setters for all attributes
}


public class GenericRecord {
  private String id;
  private String details;
  //getters and setters for all attributes
} 

希望它按以下方式存储,而不是为了向后兼容而展平:

{
  "name": "ABC",
 "recordMetadata": [
  {
    "id":"123",
    "details":"hello"

   },
  {
    "id":"456",
    "details":"yellow"

   }
 ]

}

https://github.com/aws/aws-sdk-java-v2/blob/master/services-custom/dynamodb-enhanced/README.md

4

2 回答 2

0

如果我理解,您想将嵌套对象序列化为字符串,就像@DynamoDBTypeConvertedJson注释DynamoDBMapper在 AWS SDK for Java v1 中所做的那样。在适用于 Java 的 AWS 开发工具包 v2 中,没有开箱即用的功能来执行此操作。您必须手动编写自己的转换器,如下所示。

但是将其序列化为字符串确实没有任何好处,因此您可以考虑将其存储为嵌套文档。它不需要对您发布的代码进行任何更改。将其存储为文档确实有一些好处,例如能够更新单个嵌套字段。你永远不知道什么时候会出现需要这个的需求,而且我不知道将它存储为文档有什么缺点。

注意:我认为不适@DynamoDbFlatten用于您的情况,因为展平列表没有意义。

class GenericRecordListConverter implements AttributeConverter<List<GenericRecord>> {

    private static final ObjectMapper MAPPER = new ObjectMapper();

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

    @Override
    public AttributeValue transformFrom(List<GenericRecord> input) {
        try {
            return AttributeValue.builder().s(MAPPER.writeValueAsString(input)).build();
        }
        catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<GenericRecord> transformTo(AttributeValue input) {
        try {
            return MAPPER.readValue(input.s(), new TypeReference<List<GenericRecord>>() {});
        }
        catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public EnhancedType<List<GenericRecord>> type() {
        return EnhancedType.listOf(GenericRecord.class);
    }

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

}
于 2021-02-17T23:32:32.727 回答
0

这已解决,不需要转换器,请参阅:

.addAttribute(EnhancedType.listOf(EnhancedType.documentOf(GenericRecord.class,TableSchema.fromClass(GenericRecord.class))),
                    a -> a.name("recordMetadata").getter(Customer::getRecordMetadata)
                            .setter(Customer::setRecordMetadata)  )

官方回应:

https://github.com/aws/aws-sdk-java-v2/issues/2265

于 2021-02-18T01:46:00.173 回答