`

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 CComponent

	public 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();
	//表结构缓存ID
	public $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.php
	public $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接口,能够像遍历数组一样遍历自身
这里不再详述每个类的内部细节,我们只需要了解用法即可。 

 

1
0
分享到:
评论

相关推荐

    yii-1.1.13源码

    `yiisoft/yii/framework`是核心框架目录,包含基础类和核心组件,如CApplication、CController、CModel等。其他如` yiisoft/yii/framework/web`针对Web应用的组件,`yiisoft/yii/framework/db`用于数据库操作。 2. ...

    Yii框架执行流程及部分源码分析

    `CApplication`是Yii框架的核心类,负责管理应用的生命周期。构造函数中,它会执行以下操作: - 解析配置,创建组件实例。 - 加载组件的配置。 - 注册错误处理和异常处理机制。 - 初始化Yii的类自动加载器。 -...

    Yii权威指南思维导图

    另外,Yii还提供了CDbConnection和CDbCommand类来支持更底层的SQL操作。 路由管理是Yii框架的重要特性,它决定了URL如何映射到控制器的动作。Yii的URL管理器(CUrlManager)可以配置为生成和解析友好的SEO优化的URL...

    Yii+Framework+v1.1.10类参考中文手册(CHM版)

    以下是一些主要的Yii框架核心类及其作用: 1. **CApplication**: 是所有Yii应用的基础,它管理全局状态、配置、事件和异常处理。 2. **CWebApplication**: 扩展自CApplication,专用于Web应用,处理HTTP请求和响应...

    php 框架yii 数据库 DAO

    Yii DAO主要由以下几个核心类组成: - `CDbConnection`:表示到数据库的连接。 - `CDbCommand`:表示执行的SQL语句。 - `CDbDataReader`:表示查询结果集中的行流。 - `CDbTransaction`:表示数据库事务。 **3. ...

    yii框架源代码

    3. **数据库操作**:Yii的`CDbConnection`和`CDbCommand`类封装了数据库连接和SQL执行,ORM(对象关系映射)通过` CActiveRecord `提供,使得数据库操作更加便捷。 4. **缓存管理**:Yii支持多种缓存机制,如APC、...

    yii添删改查实例

    在Yii框架中,DAO是通过CDbConnection类来实现的,它代表了一个数据库连接。为了建立一个数据库连接,开发者需要提供一个数据源名称(DSN)、用户名和密码。DSN的格式依据所使用的数据库驱动而有所不同,比如对于...

    yii-1.1.5.r2654.zip

    - **db**:数据库相关的组件,如CDbConnection、CDbCommand等。 - **web**:Web应用程序相关的类,如CController、CView等。 - **widgets**:预定义的可重用的Web小部件,如CMenu、CLinkPager等。 2. **docs**:...

    Working with Database(数据库开发工作).docx

    通过对《Working with Database(数据库开发工作).docx》文档的分析,我们可以看到,Yii框架为开发者提供了强大且灵活的数据库编程支持。无论是通过DAO还是AR,开发人员都能够高效地进行数据库操作,并且可以轻松地...

    Yii操作数据库的3种方法

    Yii 提供了一个名为 `CDbConnection` 的组件,该组件提供了对数据库的基本操作。使用 `CDbConnection`,我们可以执行原生 SQL 语句。下面是一个简单的示例: ```php $sql = ""; // 原生态 sql 语句 xx::model()->...

    Yii实现多数据库主从读写分离的方法

    Yii框架实现多数据库主从读写分离主要依赖于对Yii框架的数据库类进行扩展,使得开发者可以在同一应用中使用多个数据库配置进行读写分离。通常,在读写分离的架构中,一个主库用于处理所有的写操作,而多个从库负责读...

    Yii学习总结之数据访问对象 (DAO)

    在Yii中,数据访问对象主要通过以下四个核心类来实现其功能: 1. CDbConnection:这个类代表数据库连接。通过创建CDbConnection的实例并调用其active属性,开发者可以建立或关闭与数据库的连接。数据库连接信息通过...

    Yii操作数据库实现动态获取表名的方法

    在Yii框架中,数据库操作是应用开发的核心部分。在某些情况下,我们可能需要动态地获取数据库中的表名,尤其在数据库结构不确定或者需要频繁切换不同数据库时。本文将详细介绍如何在Yii框架中实现这一功能。 首先,...

    YII动态模型(动态表名)支持分析

    然后,将这个数据库组件赋值给DTable类的静态变量: ```php DTable::$db=Yii::app()->getComponent('db-other'); ``` 这样,就可以使用DTable类来操作指定的数据库连接了: ```php $memo=DTable::model('{{memo}}...

    Yii框架实现多数据库配置和操作的方法

    在Yii中,数据库操作是非常核心的功能,框架支持灵活的数据库配置和管理,包括多数据库支持。本文将详细讲解如何在Yii中实现多数据库配置和操作。 首先,Yii的默认配置通常只包含一个数据库连接,但这可以通过配置...

Global site tag (gtag.js) - Google Analytics