如何将 HashMap(作为对象 属性)保存到数据存储区
How to save a HashMap (as object property) to the Datastore
我正在使用 GAE (Google App Engine) 数据存储来存储人员。
每个人都有一个名字、一个唯一的令牌、他们收到的消息列表(字符串)和他们完成的测试列表(字符串)。这些都是supported types.
但是,我还想存储一个包含 String 键和 String 值的 HashMap,其中包含有关它们已完成的测试的信息。
我正在尝试保存的示例地图(请注意,这是示例数据,而非实际数据)
[
<'test_easy_1', 'completed in 3 minutes'>
<'test_easy_2', 'completed in 5 minutes'>
<'test_hard_1', 'completed in 15 minutes'>
<'test_hard_2', 'completed in 3 minutes.. Did you cheat?'>
]
我正在努力挽救这样的人
@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());
p.getEntity().setProperty("testInformation", p.getTestInformation()); // does not work
DatastoreServiceFactory.getDatastoreService().put(p.getEntity());
return true;
}
现在我的问题是:
如何将 HashMap 作为对象属性保存到数据存储区?
我希望以一种不必为 HashMap 创建整个 class 和新数据存储索引的方式执行此操作。但是,如果这是唯一的方法,我想知道如何去做。谷歌搜索并没有找到清晰明了的方法来处理这类情况。
您可以将其另存为嵌入实体。
我建议使用 Objectify,它可以简化存储并减少样板文件:https://code.google.com/p/objectify-appengine/wiki/Entities#Maps
只需在Map字段上注解@Index即可创建索引。
您可以使用 Twist 轻松实现此目的:
Map toSave = new LinkedHashMap();
toSave.put("name", p.getName());
toSave.put("token", p.getToken());
toSave.put("messages", p.getMessages());
toSave.put("completedTests", p.getCompletedTests());
toSave.put("testInformation", p.getTestInformation());
store().put(toSave);
这就是将地图保存到数据存储区的方式。
您也可以采用这样的 POJO 方法(使用 Twist):
@Entity
class TestInfo{
@Id
Long id;
@Flat
Map fields;
}
然后做:
TestInfo info = new TestInfo();
info.setFields(map);
store().put(info);
请注意,您可以对 Map 字段使用 @Flat
或 @Embedded
,如果您使用 Flat,则意味着 twist 将存储不在 EmbeddedEntity 中的字段,它将成为数据存储中的实体。否则,使用 @Embedded 将其存储在 EmbeddedEntity 中。这取决于您的需要,但这两个选项是可用的。
尽管其他答案可能是正确的,但我主要是在寻找一种无需使用外部库即可实现此目的的方法。
我对前面提到的 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);
我正在使用 GAE (Google App Engine) 数据存储来存储人员。
每个人都有一个名字、一个唯一的令牌、他们收到的消息列表(字符串)和他们完成的测试列表(字符串)。这些都是supported types.
但是,我还想存储一个包含 String 键和 String 值的 HashMap,其中包含有关它们已完成的测试的信息。
我正在尝试保存的示例地图(请注意,这是示例数据,而非实际数据)
[
<'test_easy_1', 'completed in 3 minutes'>
<'test_easy_2', 'completed in 5 minutes'>
<'test_hard_1', 'completed in 15 minutes'>
<'test_hard_2', 'completed in 3 minutes.. Did you cheat?'>
]
我正在努力挽救这样的人
@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());
p.getEntity().setProperty("testInformation", p.getTestInformation()); // does not work
DatastoreServiceFactory.getDatastoreService().put(p.getEntity());
return true;
}
现在我的问题是:
如何将 HashMap 作为对象属性保存到数据存储区?
我希望以一种不必为 HashMap 创建整个 class 和新数据存储索引的方式执行此操作。但是,如果这是唯一的方法,我想知道如何去做。谷歌搜索并没有找到清晰明了的方法来处理这类情况。
您可以将其另存为嵌入实体。
我建议使用 Objectify,它可以简化存储并减少样板文件:https://code.google.com/p/objectify-appengine/wiki/Entities#Maps
只需在Map字段上注解@Index即可创建索引。
您可以使用 Twist 轻松实现此目的:
Map toSave = new LinkedHashMap();
toSave.put("name", p.getName());
toSave.put("token", p.getToken());
toSave.put("messages", p.getMessages());
toSave.put("completedTests", p.getCompletedTests());
toSave.put("testInformation", p.getTestInformation());
store().put(toSave);
这就是将地图保存到数据存储区的方式。
您也可以采用这样的 POJO 方法(使用 Twist):
@Entity
class TestInfo{
@Id
Long id;
@Flat
Map fields;
}
然后做:
TestInfo info = new TestInfo();
info.setFields(map);
store().put(info);
请注意,您可以对 Map 字段使用 @Flat
或 @Embedded
,如果您使用 Flat,则意味着 twist 将存储不在 EmbeddedEntity 中的字段,它将成为数据存储中的实体。否则,使用 @Embedded 将其存储在 EmbeddedEntity 中。这取决于您的需要,但这两个选项是可用的。
尽管其他答案可能是正确的,但我主要是在寻找一种无需使用外部库即可实现此目的的方法。
我对前面提到的 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);