原文发表于:Phalcon入门教程之模型CURD(2)php
上一篇 Phalcon入门教程之模型CURD(1) 中介绍了 Phalcon
模型的 insert
和 select
操做,本篇将介绍 update
和 delete
的用法。文中所用的示例代码皆沿用上一篇的数据表,这里不在赘述。html
Phalcon
模型更新记录的示例代码以下:git
$articleModel = new ArticlesModel(); //先调用 findFirst() 获取一条记录,返回值是当前模型对象 $article = $articleModel->findFirst([ 'conditions' => 'aid = :aid:', 'bind' => [ 'aid' => 3 ], ]); if($article) { //使用返回的模型对象调用 update() 函数执行更新操做 $result = $article->update([ 'title' => 'Phalcon更新测试1', ]); //update() 函数返回值为boolean var_dump($result); }
监听到的SQL语句以下:github
SELECT * FROM `test_articles` WHERE `test_articles`.`aid` = :aid LIMIT :APL0 UPDATE `test_articles` SET `title` = ?, `introduce` = ?, `status` = ?, `view_number` = ?, `is_recommend` = ?, `is_top` = ?, `create_by` = ?, `create_time` = ?, `modify_by` = ?, `modify_time` = ? WHERE `aid` = ?
经过代码和SQL语句,能够看出在调用 update()
函数以前,必需要先调用 findFirst()
函数获取一条记录。这是由于 update()
函数内部是默认使用主键做为更新条件的,因此 update()
函数没有更新条件这个参数,只能经过主键来更新。可是每次执行更新操做的时候,都要执行两条SQL语句(先 select
后 update
),在性能上会有所损耗。下面跟你们分享只执行一条 update
SQL语句的办法( 前提是已经知道主键值):shell
$articleModel = new ArticlesModel(); $articleModel->aid = 3; //为主键成员属性赋值 $result = $articleModel->update([ 'title' => 'Phalcon更新测试', ]);
上述代码运行以后,抛出一个异常:数据库
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'introduce' cannot be null
意思是 introduce
字段值不能为空。咱们回头再看前面监听到的 update
SQL语句,执行 update()
函数的时候,把 test_articles
表中的全部字段都更新了。也就是说,调用 update()
函数的时候,须要更新表中的全部字段,而不能只更新某个字段或者一部分字段,因此此处,须要传入所有字段作为参数:app
$articleModel = new ArticlesModel(); $articleModel->aid = 3; $result = $articleModel->update([ 'title' => 'Phalcon更新测试', 'introduce' => "Phalcon入门教程2", 'status' => 2, 'view_number' => 2, 'is_recommend' => 1, 'is_top' => 1, 'create_by' => 1, 'create_time' => date('Y-m-d H:i:s'), 'modify_by' => 1, 'modify_time' => date('Y-m-d H:i:s') ]); if(!$result){ throw new \Exception('数据更新失败'); } //获取影响行数(假设DI中注册的数据库服务名称为“db”) $affectedRows = $this->getDI()->get('db')->affectedRows();
每次更新数据的时候,都须要将全部字段所有更新,显然不符合咱天朝广大开发者的习惯,那有没有办法实现只更新部分字段呢?frontend
除了写原生SQL,或者经过PHQL的方式能够实现更新部分字段以外,Phalcon
中并无提供能够直接使用的函数。不过,咱们能够经过其余方法来曲线救国一下,下面是我封装的函数:函数
//文件路径:marser/app/frontend/models/ArticlesModel.php /** * 封装phalcon model的update函数,实现仅更新数据变动字段,而非全部字段更新 * @param array|null $data * @param null $whiteList * @return bool */ public function iupdate(array $data = null, $whiteList = null) { if (count($data) > 0) { //获取当前模型驿应的数据表全部字段 $attributes = $this->getModelsMetaData()->getAttributes($this); //取全部字段和须要更新的数据字段的差集,并过滤 $this->skipAttributesOnUpdate(array_diff($attributes, array_keys($data))); } return parent::update($data, $whiteList); }
函数很简单,先获取当前模型对应数据表的全部字段,并和须要更新的数据字段之间取差集,而后调用 skipAttributesOnUpdate
函数进行过滤。上述更新部分字段的示例代码就能够修改为:性能
$articleModel = new ArticlesModel(); $articleModel->aid = 3; //注意这里的函数名 $result = $articleModel->iupdate([ 'title' => 'Phalcon更新测试', ]); if(!$result){ throw new \Exception('数据更新失败'); } $affectedRows = $this->getDI()->get('db')->affectedRows();
至此就能更新成功,并能获取影响行数。
这里提一下,Phalcon
模型的 update()
函数有一个注意点。当更新的数据和表中的数据相同时,update()
函数会返回 true
值,可是影响行数倒是0。
Phalcon
模型的 save()
函数会判断当前模型对象中主键成员属性是否有值,如有值,就内部调用 update()
函数执行更新操做;若没值,就内部调用 create()
函数执行插入操做。
删除记录和更新记录相似,要先调用 findFirst()
以后,再调用 delete()
函数删除一条数据。咱们在知道主键的状况,也能够直接给主键成员属性赋值:
$articleModel = new ArticlesModel(); $articleModel->aid = 4; $result = $articleModel->delete(); $affectedRows = $this->getDI()->get('db')->affectedRows();
值得注意的是,不论主键ID是否存在,delete()
都会返回 true
值,而影响行数会正常返回。因此建议根据影响行数来判断是否执行成功。
若是须要批量删除,或者使用非主键做为删除条件,那么只能写原生SQL或者PHQL去删除数据,固然也能够本身封装一个函数。
以上代码已托管在github:https://github.com/KevinJay/m...
最后,欢迎你们加入QQ群交流讨论: