2015-01-15 51 views
3

我正在使用GAE(Google App Engine)數據存儲來存儲人員。如何將HashMap(作爲對象屬性)保存到數據存儲

每個人都有一個名字,一個獨特的標記,他們收到的消息列表(字符串),並測試他們完成列表(字符串)。這些都是supported types

不過,我也想存儲包含字符串鍵和字符串值與他們已經完成了測試信息的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; 
} 

現在對於我的問題:

如何將HashMaps作爲對象屬性保存到數據存儲?

我希望的方式在那裏我不必創建一個完整的類和新的數據存儲指標只是爲HashMap中執行此。但是,如果這是唯一的出路,我想知道如何去做。谷歌搜索這並沒有導致明確和明顯的方式來處理這種情況。

回答

5

儘管其他的答案可能是正確的,我主要是尋找一種方式來實現這一目標,而無需使用外部庫。

我已經做beforementioned 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); 
-1

您可以輕鬆地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方法(用捻):

@Entity 
class TestInfo{ 
    @Id 
    Long id; 
    @Flat 
    Map fields; 
} 

然後做:

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

store().put(info); 

注意,您可以使用@Flat@Embedded的地圖領域,如果你使用扁平它意味着Twist將存儲不在EmbeddedEntity中的字段,它將成爲數據存儲中實體屬性的一部分。否則,使用@Embedded將其存儲在EmbeddedEntity中。這取決於你需要什麼,但這兩個選項是可用的。