トップ  > symfony  > モデル ( doctrine )  > 記事

No.1425 Doctrine2.0がアルファリリースされたので使ってみた

Doctrine2.0がアルファリリースされたので使ってみた

こんにちは、小川です。
本日Doctrine2.0のAlphaバージョンがリリースされました。簡単なチュートリアルも公開されているので、本日は実際に動かしてみたいと思います。

今回のリリースについては以下の記事をご覧ください。
Doctrine - Doctrine 2 Preview Release

以前僕が書いた、「Doctrine2.0について」という記事をご覧になった方でDoctrine1.xをご存じの方はわかるかと思うのですが、Doctrine2.0は全くの別物です。
上記の記事にも書いてあるとおり、実に90%以上ものコードが書き直されています。とはいえ現在はAlphaバージョン。実装されているのはまだまだ最低限の機能でしかありません。CLIやビヘイビアといった機能が実装されるのはまだ先のことでしょう。

さて、本題に入っていきましょう。実際に動かすにあたって、PHP5.3が必要になります。データベースはSQLite3を使用します。
チュートリアルはDocument内の以下のページに書いてあります。
Doctrine ORM for PHP - Introduction - Sandbox Quickstart

まずはインストールです。とりあえずSubversionを使います。

  1. $ svn co http://svn.doctrine-project.org/trunk doctrine2
  2. $ cd doctrine2/tools/sandbox

doctrine2という名前でチェックアウトしてきました。このなかのtools/sandboxに設定済みのファイルやディレクトリが配置されています。
内部のファイル構成は以下のようになっています。

  1. sandbox/
  2.   Entities/
  3.     - モデルクラスを格納するためのディレクトリ
  4.   xml/
  5.     - XML形式のマッピングファイルが作成されるディレクトリ 
  6.   yaml/
  7.     - YAML形式のマッピングファイルが作成されるディレクトリ 
  8.   cli-config.php
  9.     - CLI用の設定ファイル
  10.   config.php
  11.     - アプリケーション用の設定ファイル
  12.   doctrine
  13.     - コマンドファイル
  14.   index.php
  15.     - アプリケーションファイル

xmlとyamlディレクトリは設定次第で使ったり使わなかったりという感じです。僕はphp5.3をphp-5.3.0という名前の実行ファイルとして作成しているので、doctrineコマンドファイルを以下のように変更しました。

  1. #!/usr/bin/env php-5.3.0
  2. <?php
  3.  
  4. include('doctrine.php');

試しにコマンドを実行すると以下のように、利用可能なタスクの一覧が表示されます。

  1. $ ./doctrine
  2. Doctrine Command Line Interface
  3. Available Tasks:
  4. run-sql --file= | --sql=
  5. schema-tool --create | --drop | --update [--dump-sql] [--classdir=]
  6. version

現在はSQLを実行するrun-sql、データベースの生成などを行うschema-tool、バージョンを確認するversionの3つのタスクが有効になっています。このタスクは後ほど、必要に応じて使用していきます。

ではモデルクラスを作成します。Entitiesディレクトリに以下のクラスファイルを作成して、User.phpという名前で保存します。

  1. <?php
  2.  
  3. namespace Entities;
  4.  
  5. /**
  6.  * @Entity
  7.  */
  8. class User
  9. {
  10.   /**
  11.    * @Id
  12.    * @Column(type="integer")
  13.    * @GeneratedValue(strategy="AUTO")
  14.    */
  15.   private $id;
  16.  
  17.   /**
  18.    * @Column(type="string")
  19.    */
  20.   private $name;
  21.  
  22.   public function getId()
  23.   {
  24.     return $this->id;
  25.   }
  26.  
  27.   public function getName()
  28.   {
  29.     return $this->name;
  30.   }
  31.  
  32.   public function setName($name)
  33.   {
  34.     $this->name = $name;
  35.   }
  36. }

これでモデルクラスの定義完了です。ではこのモデルを元にデータベースを作成します。以下のコマンドを実行しましょう。

  1. $ ./doctrine schema-tool --create
  2. Doctrine Command Line Interface
  3. Creating database schema...
  4. Database schema created successfully.

これでデータベースを見てみました。SQLiteを使用している場合はdatabase.sqliteというファイルが作成されているでしょう。データベースとかの設定はconfig.phpに記述してあります。
データベースを直接みてみます。

  1. $ sqlite3 database.sqlite
  2. sqlite> .tables
  3. User
  4. sqlite> .schema User
  5. CREATE TABLE User (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL);
  6. sqlite> .quit

先ほどクラス定義時に特に指定は行っていないので、クラス名と同じUserという名前のテーブルが作成されています。
個人的には小文字の方が好きなので小文字に変えてみます。Entities/User.phpを開き、クラスのアノテーションを少し変更します。

  1. <?php
  2. ...
  3. /**
  4.  * @Entity
  5.  * @Table(name="user")
  6.  */
  7. class User ...

@Tableというアノテーションを追加しました。これでもう一度Schemaの作成を行います。

  1. $ ./doctrine schema-tool --drop
  2. $ ./doctrine schema-tool --create

これで先ほどと同じ手順で確認するときちんと小文字になっています。アノテーションの種類はたくさんあり、Doctrine/ORM/Mapping /Driver/DoctrineAnnotations.phpの中にアノテーションが1つひとつクラスとして定義されています。@Columnや @Tableに引数のようなものを渡していますが、これは各アノテーションクラスごとにプロパティとして定義されています。ここらへんがどう展開されてい るかなどは同じディレクトリ内のAnnotationDriver.phpに記述されています。
DoctrineAnnotations.phpをみるとスキーマやリレーションの情報以外に、PreUpdateやPostRemoveなどのフックメ ソッドや、Doctrineエクステンション用のDoctrineXなどが用意されているようです。Doctrineエクステンションはいわゆるビヘイビ アですが、Doctrine2.0でどう扱われるかはまだわかりません。実際に記述してもパースする処理は見当たりませんでした。

少し話がそれましたが、モデルの定義が完了してデータベースも完成したのでいよいよそれを使ってデータベースを操作していきましょう。
ではindex.phpを以下のように変更して、User情報を作成してみましょう。

  1. <?php
  2.  
  3. require 'config.php';
  4.  
  5. $user = new \Entities\User;
  6. $user->setName('fivestar');
  7. $em->persist($user);
  8. $em->flush();
  9.  
  10. echo "User saved!\n";

先ほどUser.phpを作成したときにnamespace Entity;を指定したので名前空間を指定して作成します。オブジェクトを作る流れは特に変わりませんが、保存の流れが変わっています。
$emにはDoctrine\ORM\EntityManagerクラスのインスタンスが格納されており、config.phpで作成されています。このEntityManagerクラスはDoctrine2.0において非常に重要な役割をもっているクラスです。
他の方法があるかはまだ詳しく調べていないのですが、基本的な保存の方法はこのEntityManagerを経由して行います。

EntityManagerに対してpersistメソッドを実行してUserクラスを保存対象にし、flushメソッドを実行することでデータベースへ コミットを行っています。EntityManagerの内部で_flushModeというプロパティを持っており、これが FLUSHMODE_IMMIDIATEになっていればpersistした瞬間にflushが行われるようになりますが、デフォルトでは FLUSHMODE_COMMITになっているので明示的にflushを行う必要があります。
トランザクションを発行する場合はEntityManagerに従来と同じくbeginTransaction, commit, rollbackといったメソッドが用意されています。commitメソッドは内部でflushも呼んでいるので、そこの流れは基本的に変わらないと思い ます。

  1. $ php-5.3.0 index.php
  2. User saved!

「User Saved!」が表示されたら保存完了です。保存されたか見てみましょう。直接データベースをみるのではなく、コマンドラインからSQLを実行することが可能です。

  1. $ ./doctrine run-sql --sql="select * from user"
  2. Doctrine Command Line Interface
  3. array(1) {
  4.   [0]=>
  5.   array(2) {
  6.     ["id"]=>
  7.     string(1) "1"
  8.     ["name"]=>
  9.     string(8) "fivestar"
  10.   }
  11. }

現在は配列をそのまま出しているだけですが、とりあえず正しくインサートできている(らしい)ことが確認できました。
ではこのデータをアプリケーションで取得する方法を書いていきます。index.phpを以下のように上書きします。

  1. <?php
  2.  
  3. require 'config.php';
  4.  
  5. $q = $em->createQuery('select u from Entities\User u where u.name = ?1');
  6. $q->setParameter('1', 'fivestar');
  7.  
  8. $user = $q->getSingleResult();
  9.  
  10. echo "Hello: " . $user->getName() . "!\n";

  1. $ php-5.3.0 index.php
  2. Hello: fivestar!

EntityManagerにcreateQueryというメソッドを発行してDQLを渡しています。このcreateQueryは Doctrine\ORM\Queryクラスを作成するメソッドです。プレースホルダが?1というふうになっていますが、この?のあとの数字をキーにパラ メータを指定するようになっています。現在の実装ではsetParameterかsetParametersメソッドで値を渡してあげる必要があるようで す。getSingleResultメソッドはfetchOneメソッドと同じようにクエリを実行し単一のエンティティを返すメソッドです。 getResultやgetArrayResult、getSingleScalarResultなどのメソッドがあり、いくつかの方法でクエリの実行内 容を取得することが可能なようです。

実装をみていたら今までのDoctrine_QueryのメソッドチェーンでDQLを組み立てる実装はこのQueryクラスには実装されていませんでし た。Doctrine_Queryクラスに対応するのはDoctrine\ORM\QueryBuilderクラスになります。先ほどの内容を QueryBuilderを使って行います。


  1. <?php
  2.  
  3. require 'config.php';
  4.  
  5. $qb = $em->createQueryBuilder()->select('u')->from('Entities\User u')->where('u.name = ?1');
  6. $qb->setParameter('1', 'fivestar');
  7.  
  8. $user = $qb->getQuery()->getSingleResult();
  9.  
  10. echo "Hello: " . $user->getName() . "!\n";

  1. $ php-5.3.0 index.php
  2. Hello: fivestar!

QueryBuilderは正確にはDQLを作成するためのクラスで、getQueryメソッドを実行して内部でビルドしたDQLを元にQueryクラス を作成する、というところまで行ってくれます。Doctrine_Queryと違いwhereなどの単位でパラメータを設定できなかったり、select が必須だったりしています。他にもQuery\Exprというクラスがあり、それを用いてクエリの構築を行うような仕組みになっていたりしています。この あたりは今後実装されていくのではと思います。


チュートリアルはここまでになります。最近はあまりソースを追っていなかったので深いところまでは書けないのですが、現状ではまだまだ使えるレベルには なっていないというのが率直な感想です。リリースはまだまだ先の話で、ロードマップでは2010年の3月にリリース予定のようです。まだ半年先のことです のでこれからどんどん機能が実装されていくでしょう。

現在DoctrineのブログでもDoctrine2.0の話が増えてきており、今後も様々な情報が配信されると思います。今はまだまだ評価できないですが、リリースが待ち遠しいです。

引用元

更新:2009/09/03 08:45 カテゴリ: symfony  > モデル ( doctrine ) ▲トップ

FuelPHP

Mac

フロントエンド開発

web開発

プロマネ

マネタイズ

プレゼン

webサービス運用

webサービス

Linux

サーバ管理

MySQL

ソース・開発

svn・git

PHP

HTML・CSS

JavaScript

ツール, ライブラリ

ビジネス

テンプレート

負荷・チューニング

Windows

メール

メール・手紙文例

CodeIgniter

オブジェクト指向

UI・フロントエンド

cloud

マークアップ・テキスト

Flash

デザイン

DBその他

Ruby

PostgreSQL

ユーティリティ・ソフト

Firefox

ハードウェア

Google

symfony

OpenPNE全般

OpenPNE2

Hack(賢コツ)

OpenPNE3

リンク

個人開発

その他

未確認

KVS

ubuntu

Android

負荷試験

オープンソース

社会

便利ツール

マネー

Twig

食品宅配

WEB設計

オーディオ

一般常識

アプリ開発

Python

サイトマップ

うずら技術ブログ

たませんSNS

rss2.0