Help us understand the problem. What is going on with this article?

Phalconが生成するMySQLのUPDATEクエリーについて

More than 5 years have passed since last update.

useDynamicUpdateについて追記(2013年12月3日)。

Phalcon 1.2.3でどのようなクエリーが生成されるか確認しました。

ModelのSave

findメソッドでSELECT、saveメソッドでUPDATE。

model_save.php
$robots = TheRobots::find(array('id=1'))->getFirst();
$robots->year = $robots->year + 1;
$robots->save();

実行されるSQL。

model_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されないようにできます。

http://docs.phalconphp.com/en/latest/reference/models.html#dynamic-update

ModelのinitializeメソッドでuseDynamicUpdate(true)を実行します。

TheRobots.php
class TheRobots extends \Phalcon\Mvc\Model
{
    public function initialize() {
        $this->useDynamicUpdate(true);
    }
model_save.php
$robots = TheRobots::find(array('id=1'))->getFirst();
$robots->year = $robots->year + 1;
$robots->save();

実行されるSQL。

model_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という独自のクエリー言語で任意のクエリーを実行できます。

modelmanager.php
$this->modelsManager->executeQuery('UPDATE TheRobots SET year = year + 1 WHERE id = 1');

ほぼ普通のSQLですが、上の1行で次のSQLが実行されます。useDynamicUpdateは設定していません。

modelmanager.sql
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になります。

TheRobots.php
class TheRobots extends \Phalcon\Mvc\Model
{
    public function getSource() {
        return 'the_robots';
    }

Phalcon\Db\Adapter\Pdo\Mysqlのexecute

データベースのアダプターを使うと任意のSQLを実行できます。
DIにsetしているアダプターを使用している例です。

adapter.php
$adapter = $this->di->get('db');
$adapter->execute('UPDATE the_robots SET year = year + 1 WHERE id = 1');
adapter.sql
UPDATE the_robots SET year = year + 1 WHERE id = 1

任意のSQLを実行したければアダプターを使いましょう。

pakiln
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした