是否有人在AWS Java SDK 1.4.2(及更高版本)中对DynamoDB的新命名空间(com.amazonaws.services.dynamodbv2
)和接口进行了更改?根据{{3}},本地中学指数的发布显然需要进行重大修改。
有没有人找到一份指南,详细说明迁移现有代码需要改变什么以及需要做些什么?我正在尝试决定何时最好对现有代码库进行此更改。
答案 0 :(得分:17)
DynamoDB的新 dynamodbv2 命名空间引入了以下不兼容的更改(因为它们不仅仅是附加的,需要更改代码才能切换到新的命名空间):
如果需要,可以逐步将代码迁移到新的Java API。如果您计划向查询本地二级索引的代码添加功能,或者创建具有本地二级索引的表,则需要为代码的该部分使用新API。
如果使用新API创建包含本地辅助索引的表,您仍可以使用 dynamodb 命名空间中的现有代码来执行该表上的所有现有操作。例如,带有 dynamodb 命名空间客户端的PutItem将对使用 dynamodbv2 客户端创建的表进行处理,以及相反的方式。
答案 1 :(得分:9)
DynamoDB AWS Java 1.4.1 => 1.4.2(非详尽的)迁移步骤
好吧,我咬了一下子弹做了。这是我的经历。
首先,更改DynamoDB命名空间:
com.amazonaws.services.dynamodb
=> com.amazonaws.services.dynamodbv2
您注意到的第一件事是缺少类型。最重要的是Key已经不见了。很好的摆脱,因为它太通用的名称。
它现在被替换为Map,因为密钥变得更具有Local Secondary Indexes(LSI)的可塑性。
不幸的是,使用地图和泛型一般很糟糕(参见底部的奖金)。
withHashKeyElement
/ withRangeKeyElement
的流畅界面已经一去不复返了。
接下来,非常仔细地查找/替换被泛型集合替换的DynamoDB类型:
com.amazonaws.services.dynamodb.model.Key
=&gt; Map<String, AttributeValue>
com.amazonaws.services.dynamodb.model.BatchResponse
=&gt; List<Map<String, AttributeValue>>
com.amazonaws.services.dynamodb.model.KeySchema
=&gt; List<KeySchemaElement>
接下来,找到所有破坏的东西。这是一个非常手动过程,需要很好地了解您的代码库和SDK。 具体来说,您必须非常了解您的密钥架构,因为它是所有字符串。幸运的是,在我的情况下,前两个任务大约是90%的变化:
new Map<String, AttributeValue>
,表明Key
以前就在那里。QueryRequest
将withHashKeyValue(AttributeValue)
withRangeKeyCondition(Condition)
合并到了巨型withKeyConditions(Map<String,Condition>)
中
此方法是LSI的核心更改,允许您指定散列/范围以外的内容。它接受的内容比界面更具限制性,但是当您考虑DynamoDB只允许您查询索引属性时,这是合乎逻辑的。DynamoDBQueryExpression
变得通用并改变了界面(不确定原因)。KeySchemaElement
不再需要AttributeType
,但现在需要KeyType
最后,编译并回归测试整个堆栈。
P.S。当我执行所有这些时,version 1.4.4.1刚刚发布到Maven Central。
<强>加成强>
由于Maps是Java缺乏松散类型类的常见解决方案,因此它们无处不在。 一个小帮助库可以真正走向建立这些不那么冗长的方式。 以下是我帮助的一些内容:
public class MakeJavaSuckLess { // TODO: find a shorter class name
public static final float MAX_LOAD_FACTOR = 1.0f;
/**
* Builds a mutable Map from an interlaced sequence of key-value pairs
* where keys are strings and values are VType objects
* @param pairs
* @return
*/
public static <VType> Map<String, VType> asMap(Object... pairs) {
return mergeMaps(null, pairs);
}
/**
* Builds a mutable Map from an interlaced sequence of key-value pairs
* where keys are strings and values are VType objects
* @param pairs
* @return
*/
public static <VType> Map<String, VType> mergeMaps(Map<String, VType> map, Object... pairs) {
final int length = (pairs != null) ? pairs.length/2 : 0;
if (map == null) {
// max out the load factor since most of these don't change
map = new HashMap<String, VType>(length, MAX_LOAD_FACTOR);
}
for (int i=0; i<length; i++) {
String key = asString(pairs[2*i]);
@SuppressWarnings("unchecked")
VType value = (VType)pairs[2*i+1];
map.put(key, value);
}
return map;
}
}
现在创建DynamoDB密钥稍微不那么难看了:
Map<String, AttributeValue> key = MakeJavaSuckLess.asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal"));
Java的泛型中的 Type erasure使得这一点再次变得更加丑陋。您有时需要明确指定VType
:
new GetItemRequest().withKey(MakeJavaSuckLess.<AttributeValue>asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal")));