DynamoDBMapper支持继承

时间:2016-08-30 07:38:21

标签: amazon-web-services amazon-dynamodb

我使用dynamodb和java类我存储具有以下结构:

@DynamoDBTable(tableName="Animals")
class abstract Animal {

  @DynamoDBHashKey(attributeName = "Id")
  @DynamoDBAutoGeneratedKey
  String id;

}

class Dog extends Animal {
  // ... dog props
}

class Cat extends Animal {
  // ... cat props
}

我想将Dog / Cat的实例保存到数据库并检索它们。准备提供与@JsonTypeInfo等类似的元信息。

如果支持,请告诉我。或者在DynamoDb中存储Java中的多态类型的任何变通方法。

提前致谢,

2 个答案:

答案 0 :(得分:2)

您可以使用上面描述的继承概念。 DynamoDBMapper save()方法应该能够成功保存Dog和Cat。

但是,使用DynamoDBMapper load()检索数据时,需要提供正确的类名。

当您使用Animal.class执行load()方法时,如果将Animal类定义为abstract,则API将抛出“无法实例化类”异常。

获取动物数据的示例load()方法: -

package com.vyshnav.trainfromto.model;

import com.google.gson.annotations.SerializedName;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Generated;

@Generated("org.jsonschema2pojo")
public class Classes {

private String available;
@SerializedName("class-code")
private String classCode;


/**
 *
 * @return
 * The available
 */
public String getAvailable() {
    return available;
}

/**
 *
 * @param available
 * The available
 */
public void setAvailable(String available) {
    this.available = available;
}

/**
 *
 * @return
 * The classCode
 */
public String getClassCode() {
    return classCode;
}

/**
 *
 * @param classCode
 * The class-code
 */
public void setClassCode(String classCode) {
    this.classCode = classCode;
}
}

<强>异常: -

package com.vyshnav.trainfromto.model;

import com.google.gson.annotations.SerializedName;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Generated;

@Generated("org.jsonschema2pojo")
public class Days {

private String runs;
@SerializedName("day-code")
private String dayCode;


/**
 *
 * @return
 * The runs
 */
public String getRuns() {
    return runs;
}

/**
 *
 * @param runs
 * The runs
 */
public void setRuns(String runs) {
    this.runs = runs;
}

/**
 *
 * @return
 * The dayCode
 */
public String getDayCode() {
    return dayCode;
}

/**
 *
 * @param dayCode
 * The day-code
 */
public void setDayCode(String dayCode) {
    this.dayCode = dayCode;
}
}

解决方法1: -

您可以使用 QuerySpec 获取动物数据。这样做的缺点是,您需要单独获取每个键的值,因为您没有使用DynamoDBMapper类获取数据。

dynamoDBMapper.load(Animal.class,id,
                    new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT));

解决方法2: -

您可以将Animal类声明为普通类(即没有抽象)。在这种方法中,您可以使用DynamoDBMapper获取数据。但是,您将看不到子类属性。

如果您知道要获取CAT或DOG对象,则可以在load()期间将其指定为类名。

当你得到狗:

Caused by: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: Failed to instantiate class

当您获得CAT: -

DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);

        Table table = dynamoDB.getTable("Animals");

        ItemCollection<QueryOutcome> items = null;

        QuerySpec querySpec = new QuerySpec();

        querySpec.withKeyConditionExpression("Id = :val1").withValueMap(new ValueMap().withString(":val1", animalId));
        items = table.query(querySpec);

        Iterator<Item> iterator = items.iterator();

        while (iterator.hasNext()) {
            Item itemData = iterator.next();

            System.out.println("Json data ====================>" + itemData.toJSONPretty());
            System.out.println("Dogname : " + itemData.getString("dogname"));
            System.out.println("Catname : " + itemData.getString("catname"));

        }

答案 1 :(得分:-1)

您可以使用@DynamoDBDocument来序列化对象。该文档有一个很好的例子来演示这个注释的用法。