原文發表於: Phalcon入門教程之模型
Phalcon
提供了四種方式操做Mysql數據庫:模型、PHQL、數據庫抽象層以及原生SQL。不論何種方式,首先都須要在DI中註冊 db
服務才能正常使用:php
// 文件路徑:app/core/services.php $di -> setShared('db', function () use($config) { $dbconfig = $config -> database -> db; $dbconfig = $dbconfig -> toArray(); if (!is_array($dbconfig) || count($dbconfig)==0) { throw new \Exception("the database config is error"); } $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array( "host" => $dbconfig['host'], "port" => $dbconfig['port'], "username" => $dbconfig['username'], "password" => $dbconfig['password'], "dbname" => $dbconfig['dbname'], "charset" => $dbconfig['charset']) ); return $connection; });
數據庫鏈接信息配置以下:html
// 文件路徑:app/config/system.php return array( //數據庫表配置 'database' => array( //數據庫鏈接信息 'db' => array( 'host' => '127.0.0.1', 'port' => 3306, 'username' => 'admin', 'password' => 'admin', 'dbname' => 'test', 'charset' => 'utf8', ), //表前綴 'prefix' => 'test_', ), );
在咱們開發過程當中,有時候須要經過SQL語句來分析定位問題。那麼,咱們須要將ORM生成的底層SQL記錄到日誌中。修改DI中註冊的 db
服務以下:git
//文件路徑:app/core/services.php $di -> setShared('db', function () use($config) { $dbconfig = $config -> database -> db; $dbconfig = $dbconfig -> toArray(); if (!is_array($dbconfig) || count($dbconfig)==0) { throw new \Exception("the database config is error"); } $eventsManager = new \Phalcon\Events\Manager(); // 分析底層sql性能,並記錄日誌 $profiler = new Phalcon\Db\Profiler(); $eventsManager -> attach('db', function ($event, $connection) use ($profiler) { if($event -> getType() == 'beforeQuery'){ //在sql發送到數據庫前啓動分析 $profiler -> startProfile($connection -> getSQLStatement()); } if($event -> getType() == 'afterQuery'){ //在sql執行完畢後中止分析 $profiler -> stopProfile(); //獲取分析結果 $profile = $profiler -> getLastProfile(); $sql = $profile->getSQLStatement(); $params = $connection->getSqlVariables(); (is_array($params) && count($params)) && $params = json_encode($params); $executeTime = $profile->getTotalElapsedSeconds(); //日誌記錄 $currentDay = date('Ymd'); $logger = new \Phalcon\Logger\Adapter\File(ROOT_PATH . "/app/cache/logs/{$currentDay}.log"); $logger -> debug("{$sql} {$params} {$executeTime}"); } }); $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array( "host" => $dbconfig['host'], "port" => $dbconfig['port'], "username" => $dbconfig['username'], "password" => $dbconfig['password'], "dbname" => $dbconfig['dbname'], "charset" => $dbconfig['charset']) ); /* 註冊監聽事件 */ $connection->setEventsManager($eventsManager); return $connection; });
經過代碼能夠看到,不只是底層SQL,還將SQL綁定的參數(PDO預處理)和SQL執行時間也記錄到日誌中了。日誌記錄demo以下:github
SELECT `users`.`uid` AS `uid`, `users`.`mobile` AS `mobile` FROM `users` WHERE `users`.`uid` = :uid LIMIT :APL0 {"uid":1,"APL0":1} 0.034402132034302
花括號({}
)中的就是SQL預處理時綁定的參數,最後的浮點數就是SQL執行時間(單位爲秒)。sql
模型類的命名必須符合駝峯命名法,並且須繼承自 Phalcon\Mvc\Model
類:shell
// 文件路徑:app/frontend/models/ArticlesModel.php class Articles extends \Marser\App\Frontend\Models\BaseModel { // \Marser\App\Frontend\Models\BaseModel繼承自 \Phalcon\Mvc\Model 類。 // 此處是再次封裝一個基礎模型類, 以方便後續的通用方法封裝 //... }
默認狀況下,Articles
模型類對應的數據表名是 articles
;如果 ArticlesTags
模型類,則對應的數據庫表名是 articles_tags
, 即類名對應着表名。若是想映射到其餘數據庫表,可使用 setSource()
方法設置:數據庫
// 文件路徑:app/frontend/models/ArticlesModel.php class Articles extends \Marser\App\Frontend\Models\BaseModel { public function initialize() { $this->setSource("articles_tags"); } }
在項目開發中,建議一個數據表對應着一個模型類。即便是關聯表,也強烈建議建立其對應的模型類,由於 Phalcon
中提供的連表操做,都是基於模型類的(後續的教程會分享)。json
在進行數據庫表設計的時候,有時會在表名前加上一段前綴,如 test_articles
。咱們依然能夠經過 setSource()
映射數據表:app
// 文件路徑:app/frontend/models/ArticlesModel.php class Articles extends \Marser\App\Frontend\Models\BaseModel { public function initialize() { $this->setSource("test_articles"); } }
假設,咱們的項目中有100張數據表,那麼就意味着有100個模型類。此時咱們在每一個模型類中都必須調用 setSource()
來映射完整的表名。若是某天咱們須要修改這100張表的前綴,那麼將要修改這100個模型類,不只耗時耗力還麻煩。咱們嘗試着將此處理過程提取出來進行封裝:frontend
// 文件路徑: app/frontend/models/ArticlesModel.php class ArticlesModel extends \Marser\App\Frontend\Models\BaseModel { /** * 表名 */ const TABLE_NAME = 'articles'; public function initialize(){ parent::initialize(); //映射數據表(補上表前綴) $this->set_table_source(self::TABLE_NAME); } }
在 BaseModel
模型基類中的 set_table_source()
方法定義以下:
// 文件路徑: app/frontend/models/BaseModel.php class BaseModel extends \Phalcon\Mvc\Model { public function initialize(){ } /** * 映射數據表(補上表前綴) * @param string $tableName * @param null $prefix */ protected function set_table_source($tableName, $prefix = null){ //默認從配置中讀取表前綴配置 empty($prefix) && $prefix = $this->getDI()->get('config')->database->prefix; //拼接成完整表名以後,再經過setSource()映射數據表 $this->setSource($prefix . $tableName); } }
咱們在每一個模型類中定義一個 類常量
來存儲無前綴的表名,再經過 set_table_source()
成員方法來拼接表前綴並映射。眼尖的讀者,應該在上面的數據庫鏈接信息配置中有看到 prefix
的表前綴配置。
仍是以上面爲例,此時咱們就不須要修改100個模型類的代碼,而只需修改配置文件中的 prefix
配置便可。
以上代碼已託管在github:https://github.com/KevinJay/m...
最後,歡迎你們加入QQ羣交流討論: