アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Doctrine 2.0について

こんにちは。小川です。

ブログとは全く関係ないですが昨日引っ越しをしました。今まで埼玉に住んでいたのですが、都内に引っ越してきたので会社まで自転車で通えるようになりました。
入居申し込みから申請を急ピッチで行うことなったおかげでしばらくインターネットに繋げないので発狂しそうです。
入社2年目になりますが、今年度は仕事も生活も1人でこなせるよう、心機一転がんばっていきたいです。

本日のブログはDoctrine 2.0について少しお話ししたいと思います。

Doctrineは現在1.1が最新となりますが、昨年の9月頃から(僕が確認したのがその頃だったのでもっと前からかもしれませんが)Subversionのtrunk上でDoctrine 2.0の開発が進められていました。
現在もまだbranchは作られていないですが、先日Doctrineのブログで2.0に関する記事が投稿されていました。

Glimpse of Doctrine 2.0

記事の最初の方でDoctrine2.0に関連することが3つ挙げられています。

◆ Doctrine 2.0はPHP 5.3以上が必要
◆ Doctrine 2.0は速い
◆ Doctrine 1.x系のメンテナンス期間の延長


1つめですが、現在開発中のPHP 5.3以上が必須環境になります。
2.0では1.x系に比べかなり内部構造が変わります。今回はそれと同時に名前空間を使用した実装になっています。他にも__DIR__定数や__callStatis()メソッドなどPHP 5.3で追加される新たな機能も使われています。内部構造については後ほど話します。

2つめはパフォーマンスが改善されるようです。ブログの記事によると、ハイドレーション(DBから取得した値からレコードオブジェクトを作る機能)が大幅に短縮されるようです。
Doctrine 1.1では5,000件のレコードのハイドレーションに約4.34秒かかっていたものが、Doctrine 2.0では5,000件で約1.43秒、10,000件でも約3.46秒と倍以上速くなっていることがわかります。どちらかというと元が遅いという感じですが、改善されるということは非常にありがたいですね。

3つめについてですが、詳しいことは知りませんがメンテナンスが延長されるようです。PHP 5.3の採用もあって中々移行できないと思われますので非常にありがたいですね。

ブログには他にもいくつか簡単な説明がされています。
もっとも違いがわかるのは、モデルの定義方法でしょう。

Doctrine 1.1



<?php

class User extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('id', 'integer', null, array(
          'primary' => true,
          'auto_increment' => true
        ));
        $this->hasColumn('username', 'string', 255);
    }
}


Doctrine 2.0



<?php

/**
 * @DoctrineEntity
 * @DoctrineTable(name="user")
 */
class User
{
    /**
     * @DoctrineId
     * @DoctrineColumn(type="integer")
     * @DoctrineGeneratedValue(strategy="auto")
     */
    public $id;
    /**
     * @DoctrineColumn(type="varchar", length=255)
     */
    public $username;
}


Doctrine 1.x系ではDoctrineのモデルはDoctrine_Recordというクラスを継承して、その中でカラムやリレーションなどをメソッドとして実行し、定義を行っています。
Doctrine 2.0では同じものとは思えないくらい変わっており、ドキュメントコメント上に定義を行います。それどころか、親クラスの指定すら不要です。

Doctrine 2.0ではリフレクションを用いてドキュメントコメントのパースし、モデルとのマッピングを行っています。
ちなみにマッピングデータはClassMetadataクラスに、ドキュメントコメントのパースなどはAnnotationクラスなどで行う実装になっています。

また構造が大きく変わったと最初にお伝えしましたが、実際にリポジトリをみるとよくわかると思います。

/branches/1.1/lib/Doctrine
/trunk/lib/Doctrine

Doctrine 1.1まではDoctrineクラスを除く全てのクラスがDoctrineディレクトリ以下に配置されていましたが、Doctrine 2.0からはCommon、DBAL、ORMという3つの層に大きくわけられています。

DBAL / DataBaseAbstractionLayer
 データベースの抽象化に関連する、データベースのドライバーや型の情報、コネクションなどのクラスが含まれています。
ORM / ObjectRelationalMapping
 モデルクラス関連やクエリークラスなどが含まれています。
Common
 名前の通り、共通の例外やイベントなどのクラスが含まれています。

1.1まではごちゃごちゃしてる印象がありましたが、非常にすっきりしていますね。
気になるのは1.1まであったPagerやTemplateなどの機能ですが、現在はリポジトリには含まれていないようです。PagerはともかくTemplateシステムは内部で実装してくれないとと思うのですが、Annotationをみるかぎりでは実装されていないようですし、非常に使い勝手の良かった機能なだけに早めに実装をみてみたいところです。

昨年の9月にみたときは、1.1までのモデルクラスであるDoctrine_RecordがEntityというクラスになるという内容でしたがだいぶ変わりましたね。Entityクラスがリポジトリ上から消えたときは目を疑いましたが、ブログに書いたと言うことはモデルクラスに関してはFixしてきたということでしょうか。

Tracのロードマップでは、最初の頃は今年の9月1日にリリースと書いてありましたが今見たら来年の3月1日に変更されていました。まだPHP 5.3が正式にリリースしていませんし、じっくり時間をかけていいものを作ってもらいたいですね。
今後も継続して、Doctrineを追っていこうと思います。