首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Yii分析十:Yii核心组件之数据库类CDbConnection

2012-06-26 
Yii分析10:Yii核心组件之数据库类CDbConnection?数据库类几乎是每个PHP框架必不可少的组件之一,Yii的数据

Yii分析10:Yii核心组件之数据库类CDbConnection

?

数据库类几乎是每个PHP框架必不可少的组件之一,Yii的数据库核心主要包含两类,一类是管理数据库连接的CDbConnection及相关类,另一类是ORM(Object Relation Model),即管理数据库表记录的CActiveRecord及相关类。

首先我将介绍和分析数据库连接管理类CDbConnection,CDbConnect作为CApplication的核心组件,在应用初始化时会自动进行初始化,对于使用者来说,需要在配置文件中将配置CDbConnection的初始化配置:

?

//protected/config/main.php:'components'=>array(……'db'=>array(//连接字符串,设置数据库类型,数据库主机地址,数据库名'connectionString' => 'mysql:host=localhost;dbname=blog',//用户名'username' => 'root',//密码'password' => '123456',//字符集'charset' => 'utf8',),……

?

?在应用初始化时,会自动初始化CDbConnectiont:

?

//CApplication:abstract class CApplication extends CModule//构造函数public function __construct($config=null){……//注册核心组件$this->registerCoreComponents();……}……protected function registerCoreComponents(){//核心组件列表$components=array(……'db'=>array('class'=>'CDbConnection',),……};//调用父类函数注册$this->setComponents($components);}//CModule:abstract class CModule extends CComponentpublic function setComponents($components,$merge=true){foreach($components as $id=>$component){//如果是接口IApplicationComponent的一个实例//调用setComponent//CDbConnect继承自CApplicationComponent//CApplicationCompnent继承了IApplicationCompnent接口if($component instanceof IApplicationComponent)$this->setComponent($id,$component);else if(isset($this->_componentConfig[$id]) && $merge)$this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);else$this->_componentConfig[$id]=$component;}}public function setComponent($id,$component){if($component===null)unset($this->_components[$id]);else{$this->_components[$id]=$component;//初始化组件if(!$component->getIsInitialized())$component->init();}}}

?

?

接下来我们看看CDbConnect在初始化阶段,都做了那些事情:

?

/*** CDbConnection与CDbCommand、CDbDataReader和CDbTransaction一起合作提供对DBMS的数据访问功能* 它使用PDO作为数据库连接驱动*/class CDbConnection extends CApplicationComponent{//以下属性在配置文件中设置public $connectionString;public $username='';public $password='';public $charset;//表结构缓存时间,单位是秒,默认不缓存public $schemaCachingDuration=0;//表结构缓存排除列表public $schemaCachingExclude=array();//表结构缓存IDpublic $schemaCacheID='cache';//自动连接,默认为true,如果设置为false,在使用时才会连接public $autoConnect=true;//模仿prepare,默认为false,PDO会使用原生的prepare,对于某些数据库(例如MySql),最好设置为true,这样就不会使用有bug的PDO原生prepare,关于PDO的prepare相关信息可以查阅:http://php.net/manual/en/pdo.prepare.phppublic $emulatePrepare=false;//是否记录绑定变量(如果使用prepare方式进行查询,如果记录sql语句,是看不到绑定变量的值的),调试时使用public $enableParamLogging=false;//是否记录SQL语句,调试时使用public $enableProfiling=false;//数据表前缀public $tablePrefix;//在建立数据库连接之后立即执行的SQL语句public $initSQLs;//目前支持的数据库驱动public $driverMap=array('pgsql'=>'CPgsqlSchema',    // PostgreSQL'mysqli'=>'CMysqlSchema',   // MySQL'mysql'=>'CMysqlSchema',    // MySQL'sqlite'=>'CSqliteSchema',  // sqlite 3'sqlite2'=>'CSqliteSchema', // sqlite 2'mssql'=>'CMssqlSchema',    // Mssql driver on windows hosts'dblib'=>'CMssqlSchema',    // dblib drivers on linux (and maybe others os) hosts'sqlsrv'=>'CMssqlSchema',   // Mssql'oci'=>'COciSchema',        // Oracle driver);……//初始化public function init(){//调用父类初始化parent::init();//if($this->autoConnect)$this->setActive(true);}……public function setActive($value){//如果需要设置的状态与当前状态不同if($value!=$this->_active){if($value)$this->open();else$this->close();}}protected function open(){if($this->_pdo===null){if(empty($this->connectionString))throw new CDbException(Yii::t('yii','CDbConnection.connectionString cannot be empty.'));try{Yii::trace('Opening DB connection','system.db.CDbConnection');//创建PDO实例$this->_pdo=$this->createPdoInstance();//初始化连接$this->initConnection($this->_pdo);$this->_active=true;}catch(PDOException $e){//异常处理……}}}……//创建PDO实例protected function createPdoInstance(){$pdoClass='PDO';if(($pos=strpos($this->connectionString,':'))!==false){$driver=strtolower(substr($this->connectionString,0,$pos));if($driver==='mssql' || $driver==='dblib')$pdoClass='CMssqlPdoAdapter';}return new $pdoClass($this->connectionString,$this->username,$this->password,$this->_attributes);}……//初始化连接protected function initConnection($pdo){$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);if($this->emulatePrepare && constant('PDO::ATTR_EMULATE_PREPARES'))$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);if($this->charset!==null){$driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));//pg,mysql,mysqli需要设置字符编码if(in_array($driver,array('pgsql','mysql','mysqli')))$pdo->exec('SET NAMES '.$pdo->quote($this->charset));}//如果有初始化SQL,则执行if($this->initSQLs!==null){foreach($this->initSQLs as $sql)$pdo->exec($sql);}}}
?

?

?

以上便是CDbConnect初始化的过程,其实CDnConnection主要功能是为用户封装了PDO的实例,并且自定义了一些配置,方便用户使用。

?

如果我们在项目中不想使用应用核心组件数据库连接,想自定义一个数据库连接,那么可以直接创建CDbConnection的对象:


$connection=new CDbConnection($dsn,$username,$password);//CDbConnection的祖先类Ccomponent包含有__isset方法,自动会调用名称为set[attribute]的方法,即会调用CdbConnection::setActive方法$connection->active=true;
?如果想直接执行一条SQL:
$command=$connection->createCommand($sqlStatement);$command->execute();   //// 执行SQL获取结果$reader=$command->query();//$row代表一条记录foreach($reader as $row) ...
与CDbConnection密切相关的几个类有:
CDbCommand:用户生成SQL语句,执行SQL语句CDbTransaction:用于管理数据库事务的类CDbDataReader:用于管理SQL语句执行结果的类,实现了Iterator接口,能够像遍历数组一样遍历自身这里不再详述每个类的内部细节,我们只需要了解用法即可。?

?

热点排行