原文發表於: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羣交流討論: