现在项目中多数会用到数据库多库的切换场景,在Yii中是如何实践的呢?
其实通过动态设置
Yii::app()->setComponent(array('key'=>数据库连接的配置文件));
具体代码:
<?php
class FSDB extends CComponent {
/**
* 以$cityCode为键的二维数组。
* @var array
*/
private static $dbInstance = array();
/**
* 数据库配置前缀。
*
* @var string
*/
const DB_ID = 'web_db_';
/**
* 私有构造方法,防止类被直接实例化。
*/
private function __construct() {
}
/**
* 获取唯一实例。
*
* @param string $cityCode 城市简拼
* @return instance of object
*/
public static function Instance($cityCode) {
if(!isset(self::$dbInstance[$cityCode])) {
self::$dbInstance[$cityCode] = self::init($cityCode);
}
return self::$dbInstance[$cityCode];
}
/**
* 初始化函数。
* @param string $cityCode 城市简拼
* @param Object Yii 框架对象实例
*/
public static function init($cityCode) {
$dbLink = self::DB_ID.$cityCode;
if(Yii::app()->hasComponent($dbLink)) {
return Yii::app()->$dbLink;
}
$dbConf = self::_getCityDBConfig($cityCode);
if(FALSE === $dbConf) {
throw new CException("Did not declare the database configuration!");
}
Yii::app()->setComponents(array($dbLink => $dbConf));
return Yii::app()->$dbLink;
}
/**
* 获取城市DB配置。
*
* @param string $cityCode 城市简拼
* @return boolean|array DB配置或假
*/
private static function _getCityDBConfig($cityCode){
$cityCode = strtoupper($cityCode);
$dbconfig = self::_getMasterConf($cityCode);
if($slave){
$dbconfig['slaves'] = self::_getSlaveConf($cityCode);
}
return $dbconfig;
}
/**
* 取主库配置文件。
*
* @param string $cityCode
* @return array
*/
private static function _getMasterConf($cityCode) {
return array(
'class' => 'DbConnection',
'connectionString' => mysql:host=;dbname=;port=",
'emulatePrepare' => true,
'username' => ,
'password' => ,
'tablePrefix' => 't_',
'charset' => 'utf8',
'enableProfiling' => true, //
'enableParamLogging' => true, //
);
}
/**
* 取从库配置文件。
*
* @param string $cityCode
* @return array
*/
private static function _getSlaveConf($cityCode) {
return array(
array(
'connectionString' => mysql:host=;dbname=;port=",
'emulatePrepare' => true,
'username' => ,
'password' => ,
'charset' => 'UTF8',
'tablePrefix' => 't',
'enableParamLogging' => YII_DEBUG,
'schemaCacheID' => 'cache',
'schemaCachingDuration' => 0,
)
);
}
}
调用方法:
<?
$cityCode = 'bj';
$dbx = FSDB::Instance($cityCode);
$result = $dbx->createCommand("select 8 * 8;")->queryAll();
?>