こんにちは、牧野です。
エアコンの入っている部屋にいることが多いせいか、最近夏バテ気味です。。。
さて、今日はDoctrineについてのTIPSです。symfonyとDoctrineの組み合わせで使う中で、役立ちそうなことをいくつか紹介します。
1.複数のデータベースに接続
config/databases.ymlとconfig/doctrine/schema.ymlを次のように書きます。
databases.yml
all:
main:
class: sfDoctrineDatabase
param:
classname: DoctPDO
dsn: mysql:dbname=shop_test;host=localhost
username: root
password:
encoding: utf8
persistent: true
pooling: true
sub:
class: sfDoctrineDatabase
param:
classname: DoctPDO
dsn: mysql:dbname=news_test;host=localhost
username: root
password:
encoding: utf8
persistent: true
pooling: true
ここではコネクションを表す名前を「main」と「sub」にしています。好きな名前でかまいません。
schema.ymlには「connection: (コネクションを表す名前)」を追加します。
News:
connection: sub
tableName: news
columns:
id:
type: integer(8)
unsigned: 1
primary: true
autoincrement: true
title: string(2147483647)
body: string(2147483647)
actAs:
Timestampable: { }
ところで、symfonyのdoctrineコマンドには、データベースからschema.ymlを生成する
symfony doctrine:build-schema
があります。現状ではこれを使うとconnectionの行が消えてしまうので気をつけましょう。
2.sqlの数を減らす
Doctrineは、1つのモデルから関連するモデルを芋づる式に簡単に引っ張ってこれて便利です。
ただ、DQLの書き方を気を付けないと大量のSQLが実行されてしまうことがあります。
アクション内
//書き方その1
$this->result_list = Doctrine_Query::create()
->from('PurchaseLog l')
->execute();
//書き方その2
$this->result_list = Doctrine_Query::create()
->from('PurchaseLog l')
->leftJoin('l.Shop s')
->leftJoin('l.Items i')
->leftJoin('i.Category c')
->execute();
テンプレート
<table>
<?php foreach ($result_list as $val): ?>
<tr>
<td><?php echo $val->id; ?></td>
<td><?php echo $val->purchase_date; ?></td>
<td><?php echo $val->Shop->shop_name; ?></td>
<td>
<?php foreach ($val->Items as $val2): ?>
<?php echo $val2->item_name; ?>(<?php echo $val2->Category->category_name; ?>)<br>
<?Php endforeach; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
Joinメソッドを書いておかないと1つのデータを表示する度にSQLが実行されます。(上の結果は、表示するデータが1件の場合です。)
一覧画面のデータ数が多い場合は特に注意です。
3.関連データをまとめて削除
あるデータを消す時に、紐付くデータもまとめて消したい、という時は、schema.ymlに
cascade: [delete]
を追加します。
以下の書き方の場合、Userテーブルのデータを消すと、紐付いているProfileデータも
削除されます。
User:
tableName: user
columns:
id:
type: integer(8)
unsigned: 1
primary: true
autoincrement: true
profile_id: integer(8)
...
relations:
Profile:
local: profile_id
foreign: id
type: one
cascade: [delete]
actAs:
Timestampable: { }
以上、DoctrineのTIPSでした。