JDO(Javaデータオブジェクト)を利用して、GoogleAppEngineのデータストアへアクセスする方法を紹介します。
Low Level APIでGAEのデータストアにアクセスすると比べるとデータベースの仕組みを理解するには難しくなってしまっていますが、とても簡単に、複数データをまとめてオブジェクトとして扱える便利な手法です。
PersistenceManagerクラスでデータストアにアクセスする
| メソッド名 | 説明 |
|---|---|
| PersistenceManagerのインスタンス生成時 | PersistenceManagerFactoryクラスをつかって生成すること |
| makePersistent() | オブジェクトの永続化(データストアへの保存)を行う |
| newQuery() | 指定文字列の検索クエリを作成する。 検索クエリをexecuteメソッドで実行することでJDOを取得できる |
JDOを使ってデータストアにアクセスするには、PersistenceManagerクラスのインスタンスが必要です。インスタンス生成にはPersistenceManagerFactoryクラスを利用します。
JDOで定義される永続性(保存される)オブジェクトは通常のJavaのクラスです。感覚としてはインスタンスをそのまま保存し、使いたいときにいつでも取り出せる便利な仕組みです。インスタンス=Javaデータオブジェクトのような関係ですね。
データストアの利用準備
前回のサンプルをベースに、掲示板への投稿(データストアへの保存)と表示(データストアからの取得)してみましょう。
まず、データストアへアクセスするため、PersistenceManagerFactoryクラスを利用するPMFクラスを作成します
■src/PMF.java
package org.jpn.techbooster.sample.guestbook;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
public final class PMF {
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
private PMF() {}
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}
PMFクラスのgetメソッドでPersistenceManagerFactoryクラスのインスタンスが取得できます。
PersistenceManagerFactoryのインスタンス生成は時間がかかる重い処理ですが、インスタンスは再利用可能なため、一度つくってしまえば繰り返す必要はありません。
データストアへの保存
データストアへの保存はPersistenceManagerクラスのmakePersistentメソッドを利用します。
インスタンスをmakePersistentメソッドに引き渡しすだけですので、とても簡単です。
■src/SignGuestbookServlet.java
@SuppressWarnings("serial")
public class SignGuestbookServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String content = req.getParameter("content");
Date date = new Date();
Greeting greeting = new Greeting("ペンギン1号", content, date);
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(greeting);
} finally {
pm.close();
}
resp.sendRedirect("/guestbook.jsp");
}
}
11行目、データストアにアクセスするため、PersistenceManagerのインスタンスを取得します。
13行目、PersistenceManagerクラスのmakePersistentメソッドを使ってGreetingクラスをデータストアに保存します
15行目、closeメソッドでアクセスを完了します
データストアから取得する
掲示板ではメッセージを投稿するだけでなく一覧表示する必要があります。
以下のサンプルでは、データストアへ保存したメッセージを取得して表示しています。
検索クエリを工夫することで日付ソートする、など様々な条件での抽出が可能です。
■war/WEB-INF/guestbook.jsp
<html>
<head>
<link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
</head>
<body>
...省略...
<%
PersistenceManager pm = PMF.get().getPersistenceManager();
String query = "select from " + Greeting.class.getName() + " order by date desc";
List<Greeting> greetings = (List<Greeting>) pm.newQuery(query).execute();
if (greetings.isEmpty()) {
%>
<p>The guestbook has no messages.</p>
<%
} else {
for (Greeting g : greetings) {
if (g.getAuthor() == null) {
%>
<p>An anonymous person wrote:</p>
<%
} else {
%>
<p><b><%= g.getAuthor() %></b> wrote:</p>
<%
}
%>
<blockquote><%= g.getContent() %></blockquote>
<%
}
}
pm.close();
%>
</body>
</html>
JDOデータオブジェクトであるGreetingクラスをデータストアから検索しています。
PersistenceManagerのインスタンスを取得した後、
12行目、検索クエリとなる文字列queryを作っています(日付ソートを条件に加えています)。
13行目、PersistenceManagerクラスのnewQueryメソッドで新しいクエリを作成、データストアからGreetingを取得します。
List greetingsには検索クエリのexecuteメソッドで実行した結果が格納されています。
14行目以降、取得したデータオブジェクトgreetingsを表示する処理を行います。
今回はサンプルということもあり、サニタイジング処理が行われていません。
(実際に作成する際は、ユーザの入力データをそのまま表示しないようにしてください。意図しないHTMLタグや悪意あるコードが実行される虚弱性があります)
おつかれさまでした!