2

Google App Engine データストアを使用して 4 つの文字列値を保存しています。String 値は、サーブレットのデータストアに追加されます。

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");

サーブレットが実行されるたびに 4 つの 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 上のデータストアの。

ライブラリ自体は単なる .jar ファイルであり、Eclipse の Java プロジェクトに簡単に追加できます。使いやすいライブラリを使用しているとは思いませんでした...主な問題は、保存したいデータをモデル化するクラスを登録することです。登録は1回のみ!

クラスを 1 回だけ登録するには、Objectify フレームワークにクラスを登録し、4 つの乱数を作成して保存する Web アプリにリスナーを追加しました。

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
    }
}

.. このコードは、サーバーの起動時に 1 回だけ実行されます。これを行うには、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 のドキュメントは、Objectify フレームワークに関係なく、GAE データストアを理解するのに非常に役立ちました。

4

1 に答える 1

0

将来の参考のために、元の例は次の行のために失敗したと思います:

balances = new Entity("Balances", primaryKey);

これは実際には primaryKey を持つエンティティを作成しませんが、primaryKey を祖先キーとして持つエンティティを作成します。保存するたびに自動的に生成された ID を取得します。

于 2013-04-09T12:50:39.137 に答える