ゲストブックアプリケーション
それでは、JDOを使ってデータを保存するゲストブックアプリケーションを作ってみましょう。
プロジェクトの作成
Eclipseのツールバーから「New Web Application Project」を選択します。
プロジェクトの設定情報として、このサンプルでは次の値を設定します。
- Project nameに「guestbook」を入力します
- Packageに「guestbook」を入力します
- 今回もGWT(Google Web Toolkit)を使用しないため、「Use Google Web Toolkit」のチェックを外しておきます
それ以外の項目はデフォルトのままとします。
設定ファイル
Quercusを有効にするために「war/WEB-INF」以下にある次の3つのファイルを修正、追加します。
- appengine-web.xml(App Engine定義ファイル)
- web.xml(デプロイメント記述子ファイル)
- php.ini(Quercus用PHP設定ファイル)
これらの設定ファイルについては前編と同じ値を設定します。
ゲストブックのエントリを永続化するクラス
最初にゲストブックのエントリを永続化するためのクラス、Entryクラスを作成します。
Entryクラスでは名前とコメント、投稿日時を定義し、永続化するためのアノテーションを宣言します。
// (1)App Engineデータストアに対して永続化の対象とすることを宣言
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Entry {
private static final TimeZone TZ = TimeZone.getTimeZone("Asia/Tokyo");
// (2)永続化対象のフィールド
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent
private String name;
@Persistent
private String comment;
@Persistent
private Date date;
// (3)コンストラクタ
public Entry(String name, String comment) {
this.name = name;
this.comment = comment;
this.date = new Date();
}
// (4)日付を文字列に変換して返す
public String getDateAsString() {
SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 文字列に変換する際のTimeZoneを"Asia/Tokyo"に設定する
df.setTimeZone(TZ);
return df.format(this.date);
}
// その他のgetter/setter
}
ここでは、次のような処理を実装しています。
- EntryクラスがApp Engineデータストアの永続化対象であることを宣言
- 永続化対象のフィールドに@Persistentアノテーションを付加
- コンストラクタでは名前とコメントを設定可能
- 登録日時を文字列に変換して返す
主キーとしてLong型のIdフィールドを定義し、値は自動生成します。
登録日時はコンストラクタで設定します。
このとき、TimeZoneを"Asia/Tokyo"として設定します。
PHPでEntryクラスをラップするためのクラス
この例ではなるべくPHPで頑張ることを目的にしていますので、JavaのEntryクラスをラップするためのPHPクラスを定義します。
PHPのラップクラスとして「GuestBook」を次のように定義します。
<?php
// (1)使用するJavaのクラスをインポートする
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import guestbook.Entry;
import guestbook.PMF;
class GuestBook {
// (2)Entryクラスのインスタンスをメンバ変数として持つ
private $entry;
public function __construct($name, $comment, $entry) {
if ($name != null && $comment != null) {
$this->entry = new Entry($name, $comment);
} else if ($entry != null) {
$this->entry = $entry;
}
}
// (3)Entryインスタンスに対するgetter関数
public function getId() {
return $this->entry->getId();
}
public function getName() {
return $this->entry->getName();
}
public function getComment() {
return $this->entry->getComment();
}
public function getDate() {
return $this->entry->getDateAsString();
}
// (4)App Engineデータストアに保存
public function put() {
if ($this->entry == null) {
return;
}
$pm = PMF::get()->getPersistenceManager();
try {
$pm->makePersistent($this->entry);
} catch (Exception $e) {
var_dump($e->Message);
}
$pm->close();
}
// (5)App EngineデータストアからEntryクラスのインスタンス一覧を取得
public static function all($size) {
$pm = PMF::get()->getPersistenceManager();
$query = "select from guestbook.Entry order by date desc range 0," . $size;
try {
$entries = $pm->newQuery($query)->execute();
for($i = 0; $i < $size; $i++)
{
$entry = $entries[$i];
if ($entry == null)
break;
$book = new GuestBook(null, null, $entry);
$array[] = $book;
}
} catch (Exception $e) {
var_dump($e->Message);
}
$pm->close();
return $array;
}
// (6)Idを指定してEntryクラスのインスタンスを削除
public static function deleteById($id) {
$pm = PMF::get()->getPersistenceManager();
$query = "select from guestbook.Entry where id == " . $id;
try {
$entries = $pm->newQuery($query)->execute();
$size = count($entries);
if ($size > 0) {
$entry = $entries[0];
$pm->deletePersistent($entry);
}
} catch (Exception $e) {
var_dump($e->Message);
}
$pm->close();
}
}
?>
- 使用するJavaのクラスをインポートする
- JavaのEntryクラスのインスタンスをメンバ変数として持つ
- JavaのEntryインスタンスに対するgetter関数
- App Engineデータストアに保存
- App EngineデータストアからEntryクラスのインスタンス一覧を取得
- Idを指定してEntryクラスのインスタンスを削除
QuercusではJavaのクラスも使うことができます。ここでは使用するJavaのクラスをimport命令でインポートしています。
実際の値はJavaのEntryクラスで管理するため、PHPのGuestBookクラスではEntryクラスのインスタンスを持ちます。
後述するデータ表示用PHPスクリプトから値を取得するためのgetter関数を定義します。Entryクラスのメソッドを呼び出します。
PersistenceManagerクラスのインスタンスを使用してEntryクラスのインスタンスを保存します。
引数として受け取った値を取得数の上限として、Entryクラスのインスタンスを取得します。JDOQLのRange句を使用しています。
主キーであるIdの値を指定してApp EngineデータストアよりEntryクラスのインスタンスを取得し、nullでなければ削除します。クエリ文字列のfrom句にはEntryクラスのFQCNを指定しています。
