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タグや悪意あるコードが実行される虚弱性があります)
おつかれさまでした!