symfony & Doctrine

symfonyでプログラミングを始める場合、今までSQLを記述してきた人にとってはPropelが障害になることが多いようです。
今回はsymfonyで使用可能なO/Rマッパ Doctrineを紹介したいと思います。

symfonyで採用されているデフォルトのO/Rマッパ PropelはSQLをほとんど書かずにオブジェクト操作でDBにアクセスする設計になっています。このオブジェクト操作でDBにアクセスする方法は、慣れれば別にそれほど悪くないと思います。

でも、普段SQLに慣れている人にとっては、SQLを考える、それに対応するクライテリアを考える、実装、というようにSQLからクライテリアが必要になってしまいます。そのため、直感的な操作が中々難しくなるかもしれません。

そこで、今回紹介するDoctrineの登場です。DoctrineはよりSQLに近い、DQLというものを使用してDBを操作します。

ちなみにDoctrineはHibernateにインスパイアされて作成されています。PropelがApache TorqueのPHP版なので、Javaを普段から使用している人にとっては自分の好みでどちらを使用したいかがはっきりするのではないでしょうか。

それでは、Doctrineの使用方法です。まず用意するのは、PHP5.2以上、symfonyのプロジェクトとSubversionです。インストール方法は、symfonyのプラグインsfDoctrinePluginを参照してください。

なお、2007年10月時点でDoctrineは1.0.0 RC1となっており、正式リリースが近くなってきました。そのため、仕様の変更もそれほどないと思います。symfonyのプラグインについても、活発に開発されているので、svn updateしながら最新版を使いつづけていきましょう。

sfDoctrinePluginをインストールするとsymfonyのコマンドにdoctrine-xxxxというpropel-xxxxと同じようなコマンドが追加されるので、propelと同様にモデルを作成します。なお、Propelで作成したアプリケーションをいきなりDoctrineに変更するのはかなり大変だと思うので、新しいアプリケーションで試した方がよいと思います。


propel:
  sample:
    id:
    name: varchar(255)

上記のschema.ymlに対応するデータベースがある場合は、symfony doctrine-build-schemaでDoctrine用のスキーマを作成することができます。

Propelと比較すると以下のようになります。


<?php
// 新規作成
// Propel
$sample = new Sample;
$sample->setName('hoge');
$sample->save();
// Doctrine
$sample = new Sample;
$sample->set('name', 'hoge');
$sample->save();
// プライマリーキーからの検索
// Propel
$sample = SamplePeer::retrieveByPk($id);
// Doctrine
$sample = Doctrine::getTable('Sample')->find($id);
// 普通の検索
// Propel
$c = new Criteria
$c->add(SamplePeer::NAME, 'hoge', Criteria::EQUAL);
$sample_list = SamplePeer::doSelect($c);
// Doctrine
$sample_list = Doctrine_Query::create()->from('Sample s')
  ->where('s.name = ?', 'hoge')->execute();

Criteriaを使用するかしないかで、普通の検索は随分と異なります。where addWhereメソッドを繰り返すことで、ANDの条件を追加することもできますし、whereメソッド内でANDやORも使用することができるので、SQLとあまり変わらない感覚で実行することができます。このDQLについては、解説ページを見るとかなり詳しく書いてあります。(修正: where メソッドではなく複数のWHERE句をつなげる場合は addWhereメソッドを使用します。)

Propelでできる大抵のこと(CRUDやADMIN、ページャーなどなど)はDoctrineでもできるので、Propelに困っている人はDoctrineを使用してみてください。

※なお、以前のhttp://svn.symfony-project.com/plugins/sfDoctrinePlugin/branches/0.1を使用していた人は、注意してバージョンアップしてください。スキーマファイルをsymfony doctrine-convert-schemaで再作成し、モデルの再構築を行います。それ以外にも、sfDoctrineクラスが廃止されているので、Doctrineクラスに変更する必要があったり、Warningが発生することもあります。