Doctrine_RawSqlは生のSQLクエリを構築するための便利なインターフェイスを提供します。Doctrine_Queryと同じように、Doctrine_RawSqlは配列とオブジェクト取得のための手段を提供します。
OracleでクエリヒントもしくはCONNECTキーワードのようなデータベース固有の機能を活用したいときに生のSQLを使う方法は便利です。
Doctrine_RawSqlオブジェクトの作成は簡単です:
// test.php
// ...
$q = new Doctrine_RawSql();
オプションとして接続パラメータが与えられた場合Doctrine_Connectionのインスタンスが受け取られます。Connectionsの章で接続の作成方法を学びます。
// test.php
// ...
$conn = Doctrine_Manager::connection();
$q = new Doctrine_RawSql($conn);
Doctrine_RawSqlを使う際に最初に注意しなければならないことは波かっこ({})で選択するフィールドを置かなければならないことです。またすべての選択されたコンポーネントに対してaddComponent()を呼び出さなければなりません。
次の例はこれらの使い方を明確にします:
// test.php
// ...
$q->select('{u.*}')
->from('user u')
->addComponent('u', 'User');
$users = $q->execute();
print_r($users->toArray());
addComponent()メソッドを使用してuserテーブルはUserクラスにバインドしていることに注目してください。
次のことに注意を払ってください:
複数のコンポーネントから取得するときaddComponent()コールは少し複雑になります。どのテーブルがどのコンポーネントにバインドされるのか伝えるだけでなく、どのコンポーネントがどれに所属するのかパーサーに伝えなければならないからです。
次の例においてすべてのusersとphonenumbersを取得します。最初に新しいDoctrine_RawSqlオブジェクトを作成し選択する部分を追加します:
// test.php
// ...
$q = new Doctrine_RawSql();
$q->select('{u.*}, {p.*}');
FROMの部分をuserテーブルからphonenumberテーブルへのJOINクエリに追加してすべてを一緒にマッピングする必要があります:
// test.php
// ...
$q->from('user u LEFT JOIN phonenumber p ON u.id = p.user_id')
userテーブルをUserクラスにバインドしUserクラスのエイリアスとしてuも追加します。Userクラスを参照するときにこのエイリアスが使われます。
// test.php
// ...
$q->addComponent('u', 'User u');
phonenumberテーブルにバインドされる別のテーブルを追加します:
// test.php
// ...
$q->addComponent('p', 'u.Phonenumbers p');
PhonenumberクラスはUserの電話番号を指し示していることに注意してください。
あたかもDoctrine_Queryオブジェクトを実行するようにDoctrine_RawSqlクエリを実行できます:
// test.php
// ...
$users = $q->execute();
echo get_class($users) . "\n";
echo get_class($users[0]) . "\n";
echo get_class($users[0]['Phonenumbers'][0]) . "\n";
上記の例が実行されるときに次の内容が出力されます:
$ php test.php
Doctrine_Collection
User
Phonenumber
この章はすぐに役に立つかもしれませんしそうでないかもしれません。多くの場合Doctrine Query Languageは複雑なデータセットを読み取るために十分です。しかしDoctrine_Queryができる範囲を超えるものが必要であればDoctrine_RawSqlが役立ちます。
以前の章でたくさんのYAMLスキーマファイルとその例を見てきましたが独自のものを書く練習は十分ではありません。次の章ではモデルをYAMLスキーマファイルとして維持する詳細な方法を説明します。