useDynamicUpdateについて追記(2013年12月3日)。
Phalcon 1.2.3でどのようなクエリーが生成されるか確認しました。
ModelのSave
findメソッドでSELECT、saveメソッドでUPDATE。
$robots = TheRobots::find(array('id=1'))->getFirst();
$robots->year = $robots->year + 1;
$robots->save();
実行されるSQL。
SELECT `the_robots`.`id`, `the_robots`.`name`, `the_robots`.`type`, `the_robots`.`year` FROM `the_robots` WHERE `the_robots`.`id` = 1
UPDATE `the_robots` SET `name` = 'doraemon', `type` = 'cat', `year` = 2056 WHERE `id` = '1'
全カラムがUPDATEされました。
できれば変更のないカラム更新は避けたい。
ModelのuseDynamicUpdate
useDynamicUpdateで変更のないカラムをUPDATEされないようにできます。
ModelのinitializeメソッドでuseDynamicUpdate(true)を実行します。
class TheRobots extends \Phalcon\Mvc\Model
{
public function initialize() {
$this->useDynamicUpdate(true);
}
$robots = TheRobots::find(array('id=1'))->getFirst();
$robots->year = $robots->year + 1;
$robots->save();
実行されるSQL。
SELECT `the_robots`.`id`, `the_robots`.`name`, `the_robots`.`type`, `the_robots`.`year` FROM `the_robots` WHERE `the_robots`.`id` = 1
UPDATE `the_robots` SET `year` = 2076 WHERE `id` = '1'
ModelManagerのexecuteQuery
ModelManagerでPHQLという独自のクエリー言語で任意のクエリーを実行できます。
$this->modelsManager->executeQuery('UPDATE TheRobots SET year = year + 1 WHERE id = 1');
ほぼ普通のSQLですが、上の1行で次のSQLが実行されます。useDynamicUpdateは設定していません。
SELECT `the_robots`.`id`, `the_robots`.`name`, `the_robots`.`type`, `the_robots`.`year` FROM `the_robots` WHERE `the_robots`.`id` = 1
START TRANSACTION
UPDATE `the_robots` SET `name` = 'doraemon', `type` = 'cat', `year` = `the_robots`.`year` + 1 WHERE `id` = '1'
COMMIT
トランザクションが実行され、全カラム更新となりました。
TheRobotsにuseDynamicUpdate(true)を実行していた場合は次の様に値の変更があったカラムのみになります。
SELECT `the_robots`.`id`, `the_robots`.`name`, `the_robots`.`type`, `the_robots`.`year` FROM `the_robots` WHERE `the_robots`.`id` = 1
START TRANSACTION
UPDATE `the_robots` SET `year` = `the_robots`.`year` + 1 WHERE `id` = '1'
COMMIT
ちなみにPHQLではUPDATEの後ろは「テーブル名」ではなくて「モデル名」です。
モデルにモデル名とは異なるテーブル名をマッピングしていた場合に注意しましょう。
次のコードのようにマッピングしていた場合はUPDATE TheRobots
になります。
class TheRobots extends \Phalcon\Mvc\Model
{
public function getSource() {
return 'the_robots';
}
Phalcon\Db\Adapter\Pdo\Mysqlのexecute
データベースのアダプターを使うと任意のSQLを実行できます。
DIにsetしているアダプターを使用している例です。
$adapter = $this->di->get('db');
$adapter->execute('UPDATE the_robots SET year = year + 1 WHERE id = 1');
UPDATE the_robots SET year = year + 1 WHERE id = 1
任意のSQLを実行したければアダプターを使いましょう。