原文发表于: 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群交流讨论: