DynamoDBTypeConverter for DynamoDB document field without annotations
DynamoDBTypeConverter for DynamoDB document field without annotations
我在 DynamoDB 中有一些条目,其中有一个字段,在 DynamoDB 文档格式中:
{ "foo" : { "N" : "45" }, "bar" : { "N" : "12" }}
我有一个 Java class 表示文档类型:
public class FooBar {
private final int foo;
private final int bar;
public FooBar(
int foo,
int bar
) {
this.foo = foo;
this.bar = bar;
}
public int getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
我想使用 DynamoDB mapper 获取行并将其放入 table(为简洁起见,省略了表示整行的中间 class)。我不想将 DynamoDB 注释(@DynamoDBDocument
、@DynamoDBAttribute
等)添加到 FooBar
class,因为它们需要零参数构造函数和 setter方法,但这应该是一个 immutable 数据对象。
所以想用DynamoDBTypeConverter (as described here)自己写转换,但是找不到suitable'source'类型(来代替[?]
):
class FooBarConverter implements DynamoDBTypeConverter<[?], FooBar> {
@Override
public [?] convert(FooBar object) {
...
}
@Override
public FooBar unconvert([?] object) {
...
}
}
- 似乎最自然的地图失败并显示
DynamoDBMappingException: not supported; requires @DynamoDBTyped or @DynamoDBTypeConverted
- 字符串,这似乎是一个合理的默认值,不会出错,但提供给
convert()
方法的字符串始终为空
- Dynamo 不支持似乎包罗万象的对象,并且失败
DynamoDBMappingException: could not resolve type of class FooBarConverter
如果把Javaclass和存储格式都看成是不可修改的,有什么办法呢?
我找到了适合源的类型 - AttributeValue
。这是转换器:
public class FooBarConverter implements DynamoDBTypeConverter<AttributeValue, FooBar> {
@Override
public AttributeValue convert(FooBar object) {
return new AttributeValue()
.addMEntry("foo", new AttributeValue().withN(Integer.toString(object.getFoo())))
.addMEntry("bar", new AttributeValue().withN(Integer.toString(object.getBar())));
}
@Override
public FooBar unconvert(AttributeValue object) {
Map<String, AttributeValue> objectM = object.getM();
int foo = Integer.parseInt(objectM.get("foo").getN());
int bar = Integer.parseInt(objectM.get("bar").getN());
return new FooBar(foo, bar);
}
}
此外,class 表示 Dynamo 中的整行:
public class FooBarRow {
private String key;
private FooBar fooBar;
public FooBarRow(
String key,
FooBar fooBar
) {
this.key = key;
this.fooBar = fooBar;
}
public FooBarRow() {
}
@DynamoDBHashKey
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@DynamoDBTypeConverted(converter = FooBarConverter.class)
public FooBar getFooBar() {
return fooBar;
}
public void setFooBar(FooBar fooBar) {
this.fooBar = fooBar;
}
}
现在,使用 DynamoDBMapper
保存和加载 FooBarRow
个实例效果很好。
public class FooBarMain {
public static void main(String[] args) {
DynamoDBMapper mapper = new DynamoDBMapper(
AmazonDynamoDBClientBuilder.standard().build(),
DynamoDBMapperConfig
.builder()
.withTableNameOverride(new DynamoDBMapperConfig.TableNameOverride("foobar"))
.build()
);
mapper.save(new FooBarRow("foobar1", new FooBar(123, 4)));
mapper.load(FooBarRow.class, "foobar1").getFooBar();
}
}
我在 DynamoDB 中有一些条目,其中有一个字段,在 DynamoDB 文档格式中:
{ "foo" : { "N" : "45" }, "bar" : { "N" : "12" }}
我有一个 Java class 表示文档类型:
public class FooBar {
private final int foo;
private final int bar;
public FooBar(
int foo,
int bar
) {
this.foo = foo;
this.bar = bar;
}
public int getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
我想使用 DynamoDB mapper 获取行并将其放入 table(为简洁起见,省略了表示整行的中间 class)。我不想将 DynamoDB 注释(@DynamoDBDocument
、@DynamoDBAttribute
等)添加到 FooBar
class,因为它们需要零参数构造函数和 setter方法,但这应该是一个 immutable 数据对象。
所以想用DynamoDBTypeConverter (as described here)自己写转换,但是找不到suitable'source'类型(来代替[?]
):
class FooBarConverter implements DynamoDBTypeConverter<[?], FooBar> {
@Override
public [?] convert(FooBar object) {
...
}
@Override
public FooBar unconvert([?] object) {
...
}
}
- 似乎最自然的地图失败并显示
DynamoDBMappingException: not supported; requires @DynamoDBTyped or @DynamoDBTypeConverted
- 字符串,这似乎是一个合理的默认值,不会出错,但提供给
convert()
方法的字符串始终为空 - Dynamo 不支持似乎包罗万象的对象,并且失败
DynamoDBMappingException: could not resolve type of class FooBarConverter
如果把Javaclass和存储格式都看成是不可修改的,有什么办法呢?
我找到了适合源的类型 - AttributeValue
。这是转换器:
public class FooBarConverter implements DynamoDBTypeConverter<AttributeValue, FooBar> {
@Override
public AttributeValue convert(FooBar object) {
return new AttributeValue()
.addMEntry("foo", new AttributeValue().withN(Integer.toString(object.getFoo())))
.addMEntry("bar", new AttributeValue().withN(Integer.toString(object.getBar())));
}
@Override
public FooBar unconvert(AttributeValue object) {
Map<String, AttributeValue> objectM = object.getM();
int foo = Integer.parseInt(objectM.get("foo").getN());
int bar = Integer.parseInt(objectM.get("bar").getN());
return new FooBar(foo, bar);
}
}
此外,class 表示 Dynamo 中的整行:
public class FooBarRow {
private String key;
private FooBar fooBar;
public FooBarRow(
String key,
FooBar fooBar
) {
this.key = key;
this.fooBar = fooBar;
}
public FooBarRow() {
}
@DynamoDBHashKey
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@DynamoDBTypeConverted(converter = FooBarConverter.class)
public FooBar getFooBar() {
return fooBar;
}
public void setFooBar(FooBar fooBar) {
this.fooBar = fooBar;
}
}
现在,使用 DynamoDBMapper
保存和加载 FooBarRow
个实例效果很好。
public class FooBarMain {
public static void main(String[] args) {
DynamoDBMapper mapper = new DynamoDBMapper(
AmazonDynamoDBClientBuilder.standard().build(),
DynamoDBMapperConfig
.builder()
.withTableNameOverride(new DynamoDBMapperConfig.TableNameOverride("foobar"))
.build()
);
mapper.save(new FooBarRow("foobar1", new FooBar(123, 4)));
mapper.load(FooBarRow.class, "foobar1").getFooBar();
}
}