【问题标题】:Java DynamoDBMapper. Mapping Attribute value 'M'Java DynamoDBMapper。映射属性值“M”
【发布时间】:2016-05-09 21:34:55
【问题描述】:

我刚刚开始我的第一个 DynamoDB 项目,我一直在尝试尽可能多地阅读文档。我认为我的项目的最佳可能性是使用 SDK 中的高级 DynamoDbMapper 来允许 CRUD 操作。

在 DynamoDB 文档中有一种属性值“M”,可以在此处看到 http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html

在较低级别的 java API 中,例如 getItem 或 getItemBatch,此值类型转换为 java.util.map。

但我似乎找不到任何资源说我可以使用 HigherLevel DBMapper 来使用这种数据类型。此处支持的数据类型。 http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.DataTypes.html

我注意到在页面底部,它为创建您自己的更高级别的映射系统提供了一些见解。但我想我会先在这里问一下,然后再深入研究代码以尝试这样做。所以我想我的问题是......无论如何使用 DynamoDBMapper 来处理 Java.Util.Map 数据类型?

我在谷歌上能找到的唯一见解是这个奇怪的 github 错误,用户似乎在做我想做的事。 https://github.com/aws/aws-sdk-java/issues/520

希望这是有道理的。 拉尔夫

【问题讨论】:

  • 你有想过这个吗?

标签: java amazon-web-services dictionary amazon-dynamodb


【解决方案1】:

更新:注意到您需要将 Java.Util.Map 属性映射到 DynamoDB 映射属性,因此以下所有内容都无法回答您的问题,抱歉。在我的例子中,使用了自定义类的属性,而不是 Java.Util.Map 类的属性。


假设您的表名为“my_table”,并假设以下是记录的 json 转储:

{
  uuid: "52f9d257-7998-4379-928b-9d41d70dd8a8",
  my_map: {
    field1: 123,
    field2: 456
  }  
}

(这里 my_map 是 'M' 类型的所需字段)

要将 DynamoDBMapper 用于此类表,您需要创建两个带注释的类,第一个用于表本身:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName="my_table")
public class MyClass {
    private String uuid;
    private MyMapClass myMap; 

    @DynamoDBHashKey(attributeName="uuid")
    public String getUuid() {
        return uuid;
    }   
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    @DynamoDBAttribute(attributeName = "my_map")    
    public MyMapClass getMyMap() {
        return myMap;
    }
    public void setMyMap(MyMapClass myMap) {
        this.myMap = myMap;
    }       
}

第二个——用于 my_map 字段:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;


@DynamoDBDocument
public class MyMapClass {
    private int field1;
    private int field2;

    @DynamoDBAttribute(attributeName = "field1")    
    public int getField1() {
        return field1;
    }
    public void setField1(int field1) {
        this.field1 = field1;
    }

    @DynamoDBAttribute(attributeName = "field2")    
    public int getField2() {
        return field2;
    }
    public void setField2(int field2) {
        this.field2 = field2;
    }
}

这是一个用法示例:

...
DynamoDBMapper dbMapper = new DynamoDBMapper(dbClient);
...
MyClass item = new MyClass();
item.setUuid("52f9d257-7998-4379-928b-9d41d70dd8a8");
MyMapClass map = new MyMapClass();
map.setField1(123);
map.setField2(456);
item.setMyMap(map);
dbMapper.save(item);

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    有点旧的帖子,但我认为值得在这里回答我的经验。 我注意到 DynamoDB Map 是它支持以字符串为键的映射。因此,如果您有 Map 它应该可以工作(转换模式为 ConversionSchemas.V2,如 here 所述(基本上创建您的 DynamoDB 映射器,如下所示 -

    DynamoDBMapper dbMapper = new DynamoDBMapper(dbClient, DynamoDBMapperConfig.DEFAULT);
    

    现在这个 Map 的 Value 部分也应该是受支持的 dynamoDB 数据类型;这意味着它可以有数字、字符串等。

    如果您没有字符串形式的键(或/和值),那么您需要编写自己的转换器。 这是我用于 LocalDate 并使用 Map 作为键的转换器的示例。

     public class LocalDateMapConverter implements DynamoDBTypeConverter< Map<String, Long>, Map<LocalDate, Long>> {
    @Override
    public Map<String, Long> convert(Map<LocalDate, Long> localDateToStringMap) {
        return localDateToStringMap.entrySet()
                .stream()
                .collect(toMap(k -> k.getKey().toString(),
                        Map.Entry::getValue));
    }
    
    @Override
    public Map<LocalDate, Long> unconvert(Map<String, Long> stringToLocalDateMap) {
        return stringToLocalDateMap.entrySet()
                .stream()
                .collect(toMap(k -> LocalDate.parse(k.getKey()),
                        Map.Entry::getValue));
    }
    }
    
    
    
    @DynamoDBTable(tableName = "someTable")
    public class SomeTable {
    
    @DynamoDBHashKey(attributeName = "someKey")
        private String key;
    
    @DynamoDBAttribute(attributeName = "someMapName")
        @DynamoDBTypeConverted(converter = LocalDateMapConverter.class)
        private Map<LocalDate, Long> someMap;
    
    }
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2018-09-15
      • 2017-03-16
      • 2017-07-26
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多