Datastore Java APIを使ってみよう!
Google App EngineのデータストアにアクセスするためのJava標準APIは「Java Data Objects(JDO)」「Java Persistence API(JPA)」の2種類があります。Google Plugin for Eclipseでは、プロジェクト作成時にJDOの設定ファイルが自動生成されるので、今回の記事では、JDOの使い方を説明したいと思います。
まずは、永続化対象となるデータクラスのソースコードを見てみましょう。
@PersistenceCapable(identityType = IdentityType.APPLICATION) // (1)
public class StoreData {
@PrimaryKey // (2)
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) // (3)
private Long id;
@Persistent // (4)
private String name;
@Persistent // (4)
private Integer data;
public StoreData(String name, Integer data) {
this.name = name;
this.data = data;
}
}
- データの一意性を保障してほしい範囲を指定します。この場合、アプリケーションの全バージョンを通して一意であることが保障されます。
- メンバー変数idをプライマリーキーに設定します。
- キーの自動設定方法を指定します。
- メンバー変数name, dataが永続化対象であることを指定します。
データの一意性を保障する範囲を設定する@PersistenceCapableのidentityTypeには、APPLICATION、DATASTORE、UNSPECIFIEDの3項目が指定できますが、筆者が試した範囲では3つともスコープが同じように見えましたので、通常はAPPLICATIONを指定しておけば良いでしょう。
データをストアしたときに、自動的に振られるキーは1,2,3,4……とインクリメントされていますが、突然1001,1002,1003……などの大きな数字に飛ぶことがあります。これは、データストアが複数のサーバ上で稼動しており、保存されたデータのキーの一意性を簡単に保障するための工夫だと考えられます。
おそらく、「サーバAには0」「サーバBには1000」「サーバCには2000」と初期値が設定されており、データを保存するように指示されたサーバは自分のサーバの初期値から始まる数値からインクリメントしており、キーを1000個使い切ると次の1000個を予約するのだと考えられます。
IdGeneratorStrategy.IDENTITY以外の設定も試してみましたが、すべてGoogle App Engine上でエラーになりました。保存データに連番を振りたい場合、プログラムで努力するしかないようです。
次にデータクラスを永続化するソースコードを見てみましょう。
PersistenceManagerFactory pmfInstance = JDOHelper
.getPersistenceManagerFactory("transactions-optional"); // (1)
StoreData storeData = new StoreData("蕎麦", "10"); // (2)
PersistenceManager pm = pmfInstance.getPersistenceManager(); // (3)
try {
pm.makePersistent(storeData); // (4)
} finally {
pm.close(); // (5)
}
- src/META-INF/jdoconfig.xmlに記述してある、transactions-optionalの設定をロードします。
- 先ほどのデータクラスに永続化したいデータを設定します。
- 設定(1)のPersistenceManagerを取得します。
- 永続化します。
- PersistenceManagerを閉じます。
最後に、データストアからデータを取得する部分のソースコードを見てみましょう。
PersistenceManager pm = PMF.get().getPersistenceManager(); // (1) String query = "select from " + StoreData.class.getName(); // (2) List<StoreData> list = (List<StoreData>) pm.newQuery(query).execute(); // (3)
- PersistenceManagerを取得します。
- StoreDataデータクラスの一覧を取得する、SQLライクな文法でクエリーを定義します。
- (2)のクエリーを実行し、List<StoreData>を取得します。
