BigTableに特化したSlim3DataStoreの使い方[GoogleAppEngine][Slim3][Java]
Google App EngineのサンプルではBigTableを扱う例でJDO/JPAを利用していますが、Slim3DataStoreの方が使い易く、高速です。
例えばExampleという名前のテーブルがあったときにJDOでの操作は、Example、PMFクラスがある前提で書くと
PersistenceManager pm = PMF.get().getPersistenceManager(); List<Example> examples; try { Query query = pm.newQuery(Example.class); try{ examples = (List<Example>) query.execute(); //以下examplesを利用した処理を書く。 }finally{ query.closeAll(); } } finally { pm.close(); }
というようにメンドクサイです。なのでSlim3DataStoreを使うと簡単です。
- 使い方
- とりあえずGAEプロジェクトを立ち上げましょう。Eclipseのプラグインを利用して立ち上げた前提で話をすすめます。
- Slim3本家からhttp://sites.google.com/site/slim3appengine/とってきます。ファイルを解凍するとslim3-brankというフォルダが出来ます。"slim3-blank>war>WEB-INF>lib"の中のslim-X.X.X.jar(バージョンが異なります。私のは1.0.1)を"プロジェクト名>war>WEB-INF>lib"内に突っ込みます。それから追加されたjarファイルの上で右クリック>ビルドパス>ビルドパスに追加 で追加します。
-
- 次にWEB-INF以下のweb.xmlに
<filter> <filter-name>datastoreFilter</filter-name> <filter-class>org.slim3.datastore.DatastoreFilter</filter-class> </filter> <filter-mapping> <filter-name>datastoreFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
を追加してください。今回はデータストアとして利用するだけなのでフィルターはこれだけしか追加しませんが、Slim3には色々フィルターがあるそうです。
-
- 次にプロジェクト直下にフォルダを作ります。名前は適当で結構です。私は"lib"としました。その中にダウンロードしたslim3-blankフォルダの"slim3-blank>lib>slim3-gen-X.X.X.jar"を追加します。
- プロジェクトの名前上で右クリックし、"Javaコンパイラー>注釈処理"の項目で"プロジェクト固有の設定を可能にする"にチェックを入れ、"生成されるソース・ディレクトリ"がデフォルトでは".apt_generated"になっていると思うので"generated"にします。
- "注釈処理>ファクトリー・パス"でも"プロジェクト固有の設定を可能にする"にチェックをいれ、先程の"プロジェクト名>lib>slim-gen.X.X.X.jar"を追加します。コレで終わりです。
- 使ってみる
Example.java
import org.slim3.datastore.Attribute; import org.slim3.datastore.Datastore; import org.slim3.datastore.Model; import com.google.appengine.api.datastore.Key; @Model public class Example { @Attribute(primaryKey = true) private Key internalKey; private String message; private String permalink; public Example() { } public Example(String permalink, String message) { this.message = message; this.permalink = permalink; this.internalKey = createKey(permalink); } public Key getInternalKey() { return this.internalKey; } public void setInternalKey(Key key) { this.internalKey = key; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public String getPermalink() { return permalink; } public void setPermalink(String permalink) { this.permalink = permalink; } public static Key createKey(String permalink) { if (permalink == null) { throw new IllegalArgumentException(); } return Datastore.createKey(Example.class, permalink); } }
こんなプログラムを書き、保存すると"generated"ディレクトリに、"com/example/ExampleMeta.java"というファイルが自動作成されます。
SlimSample.java
import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slim3.datastore.Datastore; import com.google.appengine.api.datastore.Key; import com.sun.org.apache.bcel.internal.generic.ARRAYLENGTH; @SuppressWarnings("serial") public class SlimSample extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); resp.getWriter().println("Hello, world"); resp.setCharacterEncoding("utf-8"); Example sample = new Example("voiceActor", "沢城みゆき"); Datastore.put(sample); } }
これを実行するとExampleというテーブルが生成され
ID/Name | message | permalink |
name=voiceActor | 沢城みゆき | voiceActor |
とデータが追加されていると思います。
Key parentKey = Datastore.createKey(Example.class, "voiceActor"); Example example = new Example(); example.setMessage("沢城みゆき"); example.setInternalKey(parentKey);
としても書けますが、Example.javaの中に引数ありコンストラクタとcreateKeyメソッドを書いてあるので簡潔に書くことができます。
また、Keyで親子関係を指定できます。
Key parentKey = Datastore.createKey(Example.class, "voiceActor"); Key childKey = Datastore.createKey(parentKey, Example.class, "hirano"); Example example = new Example(); example.setInternalKey(childKey); example.setMessage("平野綾"); Datastore.put(example);
と書くことでvoiceAcotor>hiranoという関係を指定できます。voiceActor以下に"sawashiro"、"sanada"などを次々突っ込んで行って、
List<Example> list = Datastore.query(Example.class,parentKey).asList(); for(Example example : list){ resp.getWriter().println(example.getMessage()); System.out.println(example.getMessage()); }
と書くとvoiceActorの子要素を全て取ってくることができます。
わかりにい説明ですが、使ってみると使いやすさにびっくりします。
以下のサイト様を参考にさせていただきました
http://songofcloud.gluegent.com/2009/11/slim3-datastore2.html
http://sites.google.com/site/slim3documentja/