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/