AWS Java 开发工具包中 DynamoDB v2 的迁移详细信息?
是否有人在 AWS Java 开发工具包 1.4.2(及更高版本)中对 DynamoDB 的新命名空间 () 和接口进行了更改?本地二级指数的发布显然需要根据1.4.2发行说明进行重大更改。com.amazonaws.services.dynamodbv2
有没有人找到一个指南,详细说明了哪些更改以及迁移现有代码需要发生什么?我正在尝试决定何时最好地对现有代码库进行此更改。
是否有人在 AWS Java 开发工具包 1.4.2(及更高版本)中对 DynamoDB 的新命名空间 () 和接口进行了更改?本地二级指数的发布显然需要根据1.4.2发行说明进行重大更改。com.amazonaws.services.dynamodbv2
有没有人找到一个指南,详细说明了哪些更改以及迁移现有代码需要发生什么?我正在尝试决定何时最好地对现有代码库进行此更改。
DynamoDB 的新 dynamodbv2 命名空间引入了以下不兼容的更改(因为它们不是简单的累加,并且需要更改代码才能切换到新的命名空间):
如果需要,可以将代码增量迁移到新的 Java API。如果您计划向代码添加查询本地二级索引的功能,或者使用本地二级索引创建表,则需要对该部分代码使用新的 API。
如果您使用新 API 创建具有本地二级索引的表,您仍然可以使用 dynamodb 命名空间中的现有代码对该表执行所有现有操作。例如,具有 dynamodb 命名空间客户端的 PutItem 将针对使用 dynamodbv2 客户端创建的表,反之亦然。
DynamoDB AWS Java 1.4.1 = > 1.4.2(非详尽)迁移步骤
好吧,我咬紧牙关,做到了。这是我的经验。
首先,更改 DynamoDB 命名空间:
com.amazonaws.services.dynamodb
=> com.amazonaws.services.dynamodbv2
您注意到的第一件事是缺少类型。最主要的是Key已经消失了。很好,因为它的名字太通用了。它现在被Map所取代,这是有道理的,因为键通过本地二级索引(LSI)变得更具延展性。不幸的是,在Java中使用地图和泛型通常很糟糕(请参阅底部的奖金)。/ 的流畅接口已经一去不复返了。withHashKeyElement
withRangeKeyElement
接下来,非常仔细地查找/替换被泛型集合替换的 DynamoDB 类型:
com.amazonaws.services.dynamodb.model.Key
=> Map<String, AttributeValue>
com.amazonaws.services.dynamodb.model.BatchResponse
=> List<Map<String, AttributeValue>>
com.amazonaws.services.dynamodb.model.KeySchema
=> List<KeySchemaElement>
接下来,找到所有损坏的东西。这是一个非常手动的过程,需要很好地了解您的代码库和SDK。具体来说,您必须非常了解您的密钥架构,因为它都是从现在开始的字符串。幸运的是,在我的情况下,前两个任务大约是90%的变化:
new Map<String, AttributeValue>
Key
QueryRequest
合并到 mega withKeyConditions(Map<String,Condition>)
此方法是 LSI 的核心更改,允许您指定哈希/范围以外的内容。它接受的内容比接口更具限制性,但当您认为 DynamoDB 仅允许您查询索引属性时,这是合乎逻辑的。withHashKeyValue(AttributeValue)
withRangeKeyCondition(Condition)
DynamoDBQueryExpression
变得通用并更改了其界面(不知道为什么)。KeySchemaElement
不再需要,但现在需要AttributeType
KeyType
最后,编译和回归测试整个堆栈。
附言:当我执行所有这些操作时,版本1.4.4.1刚刚发布到Maven Central。
奖金
由于Maps是Java缺乏松散类型类的常见解决方案,因此它们无处不在。一个小小的辅助 lib 真的可以大大有助于构建这些不那么冗长的内容。以下是我的助手的一些内容:
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泛型中的类型擦除使这在其他地方再次更加丑陋。您有时需要显式指定:VType
new GetItemRequest().withKey(MakeJavaSuckLess.<AttributeValue>asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal")));