本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
适用于 Java 的 SDK 版本 1 和版本 2 之间的 DynamoDB 映射 API 更改
创建客户端
| 应用场景 | V1 | V2 |
|---|---|---|
|
正常实例化 |
|
|
|
最小实例化 |
|
|
|
带属性转换器* |
|
|
*V2 中的扩展与 V1 中的属性转换器大致对应。使用扩展自定义 DynamoDB 增强型客户端操作 部分包含有关 V2 中扩展的更多信息。
建立到 DynamoDB 表/索引的映射
在 V1 中,通过 bean 注释指定 DynamoDB 表名。在 V2 中,使用一种工厂方法 table() 来生成代表远程 DynamoDB 表的 DynamoDbTable 实例。table() 方法的第一个参数是 DynamoDB 表名。
| 应用场景 | V1 | V2 |
|---|---|---|
|
将 Java POJO 类映射到 DynamoDB 表 |
|
|
|
映射到 DynamoDB 二级索引 |
《DynamoDB 开发人员指南》中讨论 V1 |
本指南中的 使用二级索引 部分提供了更多信息。 |
表操作
本节介绍大多数标准使用案例的 V1 和 V2 之间存在差异的操作 API。
在 V2 中,所有涉及单个表的操作都是在 DynamoDbTable 实例上调用,而不是在增强型客户端上调用。增强型客户端包含可以针对多个表的方法。
在下面名为表操作的表中,POJO 实例被称为 item 或称为某个具体类型(例如 customer1)。对于 V2 示例,名为 table 的实例是先前调用 enhancedClient.table() 的结果,该调用返回对 DynamoDbTable 实例的引用。
请注意,即使未显示,也可以使用 fluent 使用者模式调用大多数 V2 操作。例如,
Customer customer = table.getItem(r → r.key(key));
or
Customer customer = table.getItem(r → r.key(k -> k.partitionValue("id").sortValue("email")))
对于 V1 操作,表操作(在下方)包含一些常用的表单,并未涵盖所有重载表单。例如,load() 方法有以下重载:
mapper.load(Customer.class, hashKey)
mapper.load(Customer.class, hashKey, rangeKey)
mapper.load(Customer.class, hashKey, config)
mapper.load(Customer.class, hashKey, rangeKey, config)
mapper.load(item)
mapper.load(item, config)
表操作(在下方)显示了常用的表单:
mapper.load(item) mapper.load(item, config)
| 应用场景 | V1 | V2 |
|---|---|---|
|
将 Java POJO 写入 DynamoDB 表 DynamoDB 操作: |
在 V1 中, |
|
|
从 DynamoDB 表中将项目读取到 Java POJO DynamoDB 操作: |
|
|
|
从 DynamoDB 表中删除项目 DynamoDB 操作: |
|
|
|
查询 DynamoDB 表或二级索引并返回分页列表 DynamoDB 操作: |
|
使用返回的 |
|
查询 DynamoDB 表或二级索引并返回列表 DynamoDB 操作: |
|
使用返回的 |
|
扫描 DynamoDB 表或二级索引并返回分页列表 DynamoDB 操作: |
|
使用返回的 |
|
扫描 DynamoDB 表或二级索引并返回列表 DynamoDB 操作: |
|
使用返回的 |
|
批量读取多个表中的多个项目 DynamoDB 操作: |
|
|
|
批量将多个项目写入多个表 DynamoDB 操作: |
|
|
|
批量删除多个表中的多个项目 DynamoDB 操作: |
|
|
|
批量写入/删除多个项目 DynamoDB 操作: |
|
|
|
执行事务性写入 DynamoDB 操作: |
|
|
|
执行事务性读取 DynamoDB 操作: |
|
|
|
获取查询中匹配项的计数 DynamoDB 操作:使用 |
|
|
|
获取扫描中匹配项的计数 DynamoDB 操作:使用 |
|
|
|
在 DynamoDB 中创建与 POJO 类对应的表 DynamoDB 操作: |
前面的语句生成一个低级别的创建表请求;用户必须在 DynamoDB 客户端中调用 |
|
|
在 DynamoDB 中执行并行扫描 DynamoDB 操作:使用 |
|
用户需要处理工作线程并为每个分段调用
|
|
将 Amazon S3 与 DynamoDB 集成以存储智能 S3 链接 |
|
不支持,因为它将 Amazon S3 与 DynamoDB 结合在一起。 |
映射类和属性
在 V1 和 V2 中,都使用 bean 样式的注释将类映射到表。V2 还提供了其他方法来为特定使用案例定义架构,例如使用不可变类。
bean 注释
下表显示了 V1 和 V2 中使用的特定使用案例的等效 bean 注释。Customer 类场景用于说明参数。
V2 中的注释(以及类和枚举)遵循驼峰命名法规范,使用“DynamoDb”,而不是“DynamoDB”。
| 应用场景 | V1 | V2 |
|---|---|---|
| 将类映射到表 |
|
表名在调用 DynamoDbEnhancedClient#table() 方法时定义。 |
| 将类成员指定为表属性 |
|
|
| 将类成员指定为哈希键/分区键 |
|
|
| 将类成员指定为范围键/排序键 |
|
|
| 将类成员指定为二级索引哈希键/分区键 |
|
|
| 将类成员指定为二级索引范围键/排序键 |
|
|
| 映射到表时忽略此类成员 |
|
|
| 将类成员指定为自动生成的 UUID 键属性 |
|
默认情况下,不加载提供此功能的扩展;您必须将扩展添加到客户端生成器中。 |
| 将类成员指定为自动生成的时间戳属性 |
|
默认情况下,不加载提供此功能的扩展;您必须将扩展添加到客户端生成器中。 |
| 将类成员指定为自动递增的版本属性 |
|
提供此功能的扩展会自动加载。 |
| 将类成员指定为需要自定义转换 |
|
|
| 将类成员指定为存储为另一个属性类型 |
|
使用 |
| 指定一个可以序列化为 DynamoDB 文档(JSON 风格的文档)或子文档的类 |
|
使用增强型文档 API。请参阅以下资源:
|
V2 附加注释
| 应用场景 | V1 | V2 |
|---|---|---|
| 如果 Java 值为 null,则将类成员指定为不存储为 Null 属性 | 不适用 |
|
| 如果所有属性都为 null,则将类成员指定为空对象 | 不适用 |
|
| 为类成员指定特殊更新操作 | 不适用 |
|
| 指定一个不可变类 | 不适用 |
|
| 将类成员指定为自动递增的计数器属性 | 不适用 |
提供此功能的扩展会自动加载。 |
配置
在 V1 中,通常使用 DynamoDBMapperConfig 的实例来控制特定行为。您可以在创建映射器时或在发出请求时提供配置对象。在 V2 中,配置特定于操作的请求对象。
| 应用场景 | V1 | V1 中的默认设置 | V2 |
|---|---|---|---|
|
|||
| 批量加载/写入重试策略 |
|
重试失败的项目 | 在底层 DynamoDBClient 中配置重试策略。请参阅本指南中的在AWS SDK for Java 2.x 中配置重试行为。 |
| 一致性读取 |
|
EVENTUAL |
默认情况下,读取操作的一致性读取为 false。在请求对象上使用 .consistentRead(true) 覆盖。 |
| 包含编组器/解组器集合的转换架构 |
静态实现与旧版本向后兼容。 |
V2_COMPATIBLE |
不适用。这是一项遗留特性,指的是 DynamoDB 的最早版本(V1)存储数据类型的方式,而在增强型客户端中不再保留此行为。DynamoDB V1 中的一个行为示例是将布尔值存储为数字而不是布尔值。 |
| 表名称 |
静态实现与旧版本向后兼容 |
使用注释或根据类来推断 |
表名在调用 |
| 分页加载策略 |
选项包括:LAZY_ |
LAZY_LOADING |
|
| 请求指标收集 |
|
null |
在构建标准 DynamoDB 客户端时在 ClientOverrideConfiguration 中使用 metricPublisher()。 |
| 保存行为 |
选项包括 |
UPDATE |
在 V2 中,您可以显式调用
|
| 类型转换器工厂 |
|
标准类型转换器 |
使用以下方式在 bean 上设置
|
每个操作的配置
在 V1 中,某些操作(例如 query())可以通过提交给操作的“表达式”对象来进行高度灵活的配置。例如:
DynamoDBQueryExpression<Customer> emailBwQueryExpr = new DynamoDBQueryExpression<Customer>() .withRangeKeyCondition("Email", new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList( new AttributeValue().withS("my"))); mapper.query(Customer.class, emailBwQueryExpr);
在 V2 中,不使用配置对象,而是使用生成器对请求对象设置参数。例如:
QueryEnhancedRequest emailBw = QueryEnhancedRequest.builder() .queryConditional(QueryConditional .sortBeginsWith(kb -> kb .sortValue("my"))).build(); customerTable.query(emailBw);
条件
在 V2 中,条件表达式和筛选表达式使用 Expression 对象来表达,该对象封装了条件以及名称和筛选条件的映射。
| 应用场景 | 操作 | V1 | V2 |
|---|---|---|---|
| 预期的属性条件 | save()、delete()、query()、scan() |
|
已弃用;改用 ConditionExpression。 |
| 条件表达式 | delete() |
|
|
| 筛选表达式 | query()、scan() |
|
|
| 查询的条件表达式 | query() |
|
|
类型转换
默认转换器
在 V2 中,SDK 为所有常见类型提供了一组默认转换器。既可以在整体提供程序级别更改类型转换器,也可以为单个属性更改类型转换器。您可以在 AttributeConverter
为属性设置自定义转换器
在 V1 中,您可以使用 @DynamoDBTypeConverted 对 getter 方法添加注释,以指定在 Java 属性类型和 DynamoDB 属性类型之间进行转换的类。例如,CurrencyFormatConverter 可以在 Java Currency 类型和 DynamoDB 字符串之间应用转换,如以下代码段所示。
@DynamoDBTypeConverted(converter = CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
上一个代码段的 V2 等效代码如下所示。
@DynamoDbConvertedBy(CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
注意
在 V1 中,您可以将注释应用于属性本身、类型或用户定义的注释,V2 仅支持将注释应用于 getter。
添加类型转换器工厂或提供程序
在 V1 中,您可以提供自己的类型转换器集,也可以通过在配置中添加类型转换器工厂来覆盖您在意的类型。类型转换器工厂扩展 DynamoDBTypeConverterFactory,通过获取对默认集的引用并对其进行扩展来完成覆盖。以下代码段演示了如何执行此操作。
DynamoDBTypeConverterFactory typeConverterFactory =
DynamoDBTypeConverterFactory.standard().override()
.with(String.class, CustomBoolean.class, new DynamoDBTypeConverter<String, CustomBoolean>() {
@Override
public String convert(CustomBoolean bool) {
return String.valueOf(bool.getValue());
}
@Override
public CustomBoolean unconvert(String string) {
return new CustomBoolean(Boolean.valueOf(string));
}}).build();
DynamoDBMapperConfig config =
DynamoDBMapperConfig.builder()
.withTypeConverterFactory(typeConverterFactory)
.build();
DynamoDBMapper mapperWithTypeConverterFactory = new DynamoDBMapper(dynamo, config);
V2 通过 @DynamoDbBean 注释提供了类似的功能。您可以提供单个 AttributeConverterProvider 或一个有序的 AttributeConverterProvider 链。请注意,如果您提供自己的属性转换器提供程序链,则将覆盖默认的转换器提供程序,且必须在链中包括它才能使用其属性转换器。
@DynamoDbBean(converterProviders = {
ConverterProvider1.class,
ConverterProvider2.class,
DefaultAttributeConverterProvider.class})
public class Customer {
...
}
本指南中关于属性转换的部分包含了 V2 的完整示例。