Java 如何将HashMap(作为对象属性)保存到数据存储

Java 如何将HashMap(作为对象属性)保存到数据存储,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,我正在使用GAE(谷歌应用程序引擎)数据存储来存储人 每个人都有一个名字、一个唯一的标记、一个他们收到的消息列表(字符串)和一个他们完成的测试列表(字符串)。这些都是 但是,我还想存储一个HashMap,其中包含字符串键和字符串值以及它们已完成的测试的信息 我试图保存的示例地图(请注意,这是示例数据,而不是实际数据) 现在回答我的问题: 如何将HashMaps作为对象属性保存到数据存储 我希望以一种不必为HashMap创建整个类和新的数据存储索引的方式执行此操作。然而,如果这是唯一的办法,我希望

我正在使用GAE(谷歌应用程序引擎)数据存储来存储人

每个人都有一个名字、一个唯一的标记、一个他们收到的消息列表(字符串)和一个他们完成的测试列表(字符串)。这些都是

但是,我还想存储一个HashMap,其中包含字符串键和字符串值以及它们已完成的测试的信息

我试图保存的示例地图(请注意,这是示例数据,而不是实际数据)

现在回答我的问题:

如何将HashMaps作为对象属性保存到数据存储


我希望以一种不必为HashMap创建整个类和新的数据存储索引的方式执行此操作。然而,如果这是唯一的办法,我希望得到通知如何去做。用谷歌搜索这一点并没有产生一种清晰而明显的方法来处理这种情况。

您可以将其保存为嵌入式实体

我建议使用Objectify,它可以简化存储并减少样板文件:


您只需在地图字段上注释@Index即可创建索引。

您可以通过以下方法轻松实现:

这就是将地图保存到数据存储的方式

您也可以采用如下POJO方法(使用Twist):

然后做:

TestInfo info = new TestInfo();
info.setFields(map); 

store().put(info);

请注意,您可以对地图字段使用
@Flat
@Embedded
,如果使用Flat,则表示twist将存储字段而不是嵌入实体,它将是数据存储中实体属性的一部分。否则,使用@Embedded将其存储在EmbeddedEntity中。这取决于你需要什么,但这两个选项是可用的

尽管其他答案可能是正确的,但我主要是在寻找一种不用外部库就能实现这一点的方法

我对前面提到的做了一些研究,发现这确实是我想要的

我写下并接受这个答案,因为它为我的问题提供了一个确切的解决方案,而不仅仅是解决问题的指导方针。我希望通过这种方式来指导将来遇到类似问题的人

现在,拯救此人看起来是这样的:

@Override
public boolean savePerson(Person p) {
    if (p.getEntity() == null) {
        return false;
    }

    p.getEntity().setProperty("name", p.getName());
    p.getEntity().setProperty("token", p.getToken());
    p.getEntity().setProperty("messages", p.getMessages());
    p.getEntity().setProperty("completedTests", p.getCompletedTests());

    EmbeddedEntity ee = new EmbeddedEntity();
    Map<String, String> testInformation = p.getTestInformation();

    for (String key : testInformation.keySet()) { // TODO: maybe there is a more efficient way of solving this
        ee.setProperty(key, testInformation.get(key));
    }

    p.getEntity().setProperty("testInformation", ee);
    DatastoreServiceFactory.getDatastoreService().put(p.getEntity());

    return true;
}
Person p = new Person(id);
p.setName((String) e.getProperty("name"));
p.setToken((String) e.getProperty("token"));
p.setMessages((List<String>) e.getProperty("messages"));
p.setCompletedTests((List<String>) e.getProperty("completedTests"));

Map<String, String> ti = new HashMap<>();
EmbeddedEntity ee = (EmbeddedEntity) e.getProperty("testInformation");
if (ee != null) {
    for (String key : ee.getProperties().keySet()) {
        ti.put(key, (String) ee.getProperty(key));
    }
    p.setTestInformation(ti);
}
p.setEntity(e);
@覆盖
公共布尔值savePerson(Person p){
if(p.getEntity()==null){
返回false;
}
p、 getEntity().setProperty(“name”,p.getName());
p、 getEntity().setProperty(“token”,p.getToken());
p、 getEntity().setProperty(“messages”,p.getMessages());
p、 getEntity().setProperty(“completedTests”,p.getCompletedTests());
EmbeddedEntity ee=新的EmbeddedEntity();
Map testInformation=p.getTestInformation();
对于(字符串键:testInformation.keySet()){//TODO:也许有一种更有效的方法来解决这个问题
ee.setProperty(key,testInformation.get(key));
}
p、 getEntity().setProperty(“testInformation”,ee);
DatastoreServiceFactory.getDatastoreService().put(p.getEntity());
返回true;
}
现在加载人员的方式如下所示:

@Override
public boolean savePerson(Person p) {
    if (p.getEntity() == null) {
        return false;
    }

    p.getEntity().setProperty("name", p.getName());
    p.getEntity().setProperty("token", p.getToken());
    p.getEntity().setProperty("messages", p.getMessages());
    p.getEntity().setProperty("completedTests", p.getCompletedTests());

    EmbeddedEntity ee = new EmbeddedEntity();
    Map<String, String> testInformation = p.getTestInformation();

    for (String key : testInformation.keySet()) { // TODO: maybe there is a more efficient way of solving this
        ee.setProperty(key, testInformation.get(key));
    }

    p.getEntity().setProperty("testInformation", ee);
    DatastoreServiceFactory.getDatastoreService().put(p.getEntity());

    return true;
}
Person p = new Person(id);
p.setName((String) e.getProperty("name"));
p.setToken((String) e.getProperty("token"));
p.setMessages((List<String>) e.getProperty("messages"));
p.setCompletedTests((List<String>) e.getProperty("completedTests"));

Map<String, String> ti = new HashMap<>();
EmbeddedEntity ee = (EmbeddedEntity) e.getProperty("testInformation");
if (ee != null) {
    for (String key : ee.getProperties().keySet()) {
        ti.put(key, (String) ee.getProperty(key));
    }
    p.setTestInformation(ti);
}
p.setEntity(e);
人员p=新人员(id);
p、 setName((字符串)e.getProperty(“名称”);
p、 setToken((字符串)e.getProperty(“token”);
p、 setMessages((列表)e.getProperty(“消息”);
p、 setCompletedTests((列表)e.getProperty(“completedTests”);
Map ti=新的HashMap();
EmbeddedEntity ee=(EmbeddedEntity)e.getProperty(“测试信息”);
如果(ee!=null){
对于(字符串键:ee.getProperties().keySet()){
ti.put(key,(String)ee.getProperty(key));
}
p、 组织形态(ti);
}
p、 实体(e);
@Override
public boolean savePerson(Person p) {
    if (p.getEntity() == null) {
        return false;
    }

    p.getEntity().setProperty("name", p.getName());
    p.getEntity().setProperty("token", p.getToken());
    p.getEntity().setProperty("messages", p.getMessages());
    p.getEntity().setProperty("completedTests", p.getCompletedTests());

    EmbeddedEntity ee = new EmbeddedEntity();
    Map<String, String> testInformation = p.getTestInformation();

    for (String key : testInformation.keySet()) { // TODO: maybe there is a more efficient way of solving this
        ee.setProperty(key, testInformation.get(key));
    }

    p.getEntity().setProperty("testInformation", ee);
    DatastoreServiceFactory.getDatastoreService().put(p.getEntity());

    return true;
}
Person p = new Person(id);
p.setName((String) e.getProperty("name"));
p.setToken((String) e.getProperty("token"));
p.setMessages((List<String>) e.getProperty("messages"));
p.setCompletedTests((List<String>) e.getProperty("completedTests"));

Map<String, String> ti = new HashMap<>();
EmbeddedEntity ee = (EmbeddedEntity) e.getProperty("testInformation");
if (ee != null) {
    for (String key : ee.getProperties().keySet()) {
        ti.put(key, (String) ee.getProperty(key));
    }
    p.setTestInformation(ti);
}
p.setEntity(e);