我正在使用Google App Engine数据存储来存储4个字符串值。 String vlaues被添加到servlet中的数据存储区中:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity balances;
Key primaryKey;
String table = "MainTable";
String name = "Values";
primaryKey = KeyFactory.createKey(table, name);
Transaction t = datastore.beginTransaction();
// If the 'table' exists - delete it
datastore.delete(primaryKey);
// Really make sure it's deleted/
t.commit();
t = datastore.beginTransaction();
balances = new Entity("Balances", primaryKey);
updateBalances(balances);
datastore.put(balances);
// Save the new data
t.commit();
resp.sendRedirect("/balance.jsp");
我希望每次运行servlet时都能更新四个String值 - 这就是我首先查找键并删除它的原因。我甚至使用单独的事务来确保这种情况真的发生。
找到并删除密钥,然后添加值。但是当我加载一个检索值的.jsp文件时,实体中“记录”的数量每次增加1。我不明白为什么记录没有被删除。
这是.jsp代码:
<%
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key guestbookKey = KeyFactory.createKey("MainTable", "Values");
Query query = new Query("Balances", guestbookKey);
List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));
%>
<!-- This should always be 1, but it gorws each time the servlet is hit.-->
<%= greetings.size() %>
解
我不知道原问题中代码的问题是什么。但是,我通过使用名为Objectify的库(http://code.google.com/p/objectify-appengine/)实现了在Google App Engine(GAE)上跨会话持久保存String值的目标 - 旨在简化使用GAE上的DataStore。
库本身只是一个.jar文件,可以轻松地添加到Eclipse中的Java项目中。我没有找到使用易于使用的库...主要问题是注册为您要保存的数据建模的类。注册只能进行一次!
只有在我使用Objectify框架注册了该类的Web应用程序添加了一个监听器并且还创建了4个随机数并保存它们之后,才能注册该类:
public class MyListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Register the Account class, only once!
ObjectifyService.register(Account.class);
Objectify ofy = ObjectifyService.begin();
Account balances = null;
// Create the values we wish to persist.
balances = new Account(randomNum(), randomNum(), randomNum(),
randomNum());
// Actually save the values.
ofy.put(balances);
assert balances.id != null; // id was autogenerated
}
public void contextDestroyed(ServletContextEvent event) {
// App Engine does not currently invoke this method.
}
private String randomNum() {
// Returns random number as a String
}
}
..这段代码只在服务器启动时运行一次 - 为此我还需要修改web.xml来添加:
<listener>
<listener-class>.MyListener</listener-class>
</listener>
然后我只有一个读取保存值的.jsp页面:
<%
Objectify ofy = ObjectifyService.begin();
boolean data = false;
// The value "mykey" was hard coded into my Account class enter code here
// since I only wanted access to the same data every time.
Account a = ofy.get(Account.class, "mykey");
data = (null!=a);
%>
这是我的帐户类:
import javax.persistence.*;
public class Account
{
@Id String id = "mykey";
public String balance1, balance2, balance3, balance4;
private Account() {}
public Account(String balance1, String balance2, String balance3, String balance4)
{
this.balance1 = balance1;
this.balance2 = balance2;
this.balance3 = balance3;
this.balance4 = balance4;
}
}
最后一件事......我发现OBjectify documentation非常有助于理解GAE数据存储区而不管Objectify框架
答案 0 :(得分:0)
为了将来参考,我认为你原来的例子因为这行而失败了:
balances = new Entity("Balances", primaryKey);
这实际上并不创建具有primaryKey的实体,但它创建了一个以primaryKey作为祖先键的实体。每次存储时都会自动生成一个id。