我正在使用 Google App Engine 数据存储来存储 4 个字符串值。字符串值被添加到 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 时更新四个字符串值——这就是为什么我首先查找密钥并删除它的原因。我什至使用单独的事务来确保这真的发生。
找到并删除键,然后添加值。但是,当我加载一个检索值的 .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) 上的会话中保留字符串值的目标 - 该库旨在简化使用GAE 上的 DataStore。
该库本身只是一个 .jar 文件,可以轻松地添加到 Eclipse 中的 Java 项目中。我没有发现使用易于使用的库......主要问题是注册模拟您希望保存的数据的类。注册只能完成一次!
仅在我向我的 Web 应用程序添加一个侦听器后才注册该类,该侦听器使用 Objectify 框架注册了该类,并创建了 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 文档对于理解 GAE 数据存储非常有帮助,无论 Objectify 框架如何