Touya
(Humandong)
December 8, 2009, 3:14am
1
在Yii的文档中没有看到关于多DB连接的内容,好不容易在论坛里找到相关的,得到的答案是覆盖Model中的getDbConnection函数,如果这样的话,那么某一个Model岂不是只能对应某一个DB,典型的MySQL Master/Slave应用中,表结构是一样的,是否可以共用Model呢?
比如定义main.php中:
‘master’ => require_once(‘db_master_define.php’),
‘slave’ => require_once(‘db_slave_define.php’),
而某个表的Model是User.php
是否可以在程序中这样调用:
User::model(‘master’)->find();
User::model(‘slave’)->find();
?
Touya
(Humandong)
December 8, 2009, 4:48am
3
这篇帖子里也没有一个定论啊,看起来Yii并没有buildin的多DB连接支持,只能依靠hack,这样代码可读性会降低。
有时未必一定是读用slave,写用master,所以定义自己的AR类,添加onBeforeXXX函数并不能解决所有问题。
我觉得Yii框架还是应该把Model和DBConnection分开,能够传递参数给model
例如以前接触到的框架中,就有Model和Schema之分,
1 Schema类代表一个DB,在其下可以有多个表示Table结构和关系的Class
2 Model调用Schema类,初始化时输入连接参数
这样我可以定义两个Model:DBMaster和DBSlave,它们调用的Schema是相同的,只是连接参数不同
代码里就可以用app()->dbmaster->schema(‘Table’)->find();
app()->dbslave->schema(‘Table’)->find();
qiang
(Qiang Xue)
December 8, 2009, 12:01pm
4
一个比较简单的办法是如下定义一个AR基类:
class BaseActiveRecord extends CActiveRecord
{
public function use($db=null)
{
self::$db=Yii::app()->$db;
return $this;
}
}
class Post extends BaseActiveRecord { ... }
Post::model()->findAll(); // use 'db'
Post::model()->use('db2')->findAll(); // use 'db2'
Post::model()->findAll(); // use 'db2'
因为CActiveRecord::$db可以动态修改,你也可以创造出更加优美的一些实现。
touya:
got it!帅!
直接在connection维护
这个方法挺透明的;
对模型层等均透明
//日志组件的配置
return array(
‘class’=>‘CDbConnectionExt’,
‘emulatePrepare’ => true,
‘charset’ => ‘utf8’,
//主数据库配置
‘connectionString’ => ‘mysql:host=localhost;dbname=a;port=3306’,
‘username’ => ‘root’,
‘password’ => ‘11’,
//从数据库配置
‘slaveConfig’=>array(
array(‘connectionString’=>‘mysql:host=localhost;dbname=a;port=3306’,‘username’=>‘root’,‘password’=>‘11’,),
array(‘connectionString’=>‘mysql:host=localhost;dbname=a;port=3306’,‘username’=>‘root’,‘password’=>‘11’,),
array(‘connectionString’=>‘mysql:host=localhost;dbname=a;port=3306’,‘username’=>‘root’,‘password’=>‘11’,),
array(‘connectionString’=>‘mysql:host=localhost;dbname=a;port=3306’,‘username’=>‘root’,‘password’=>‘11’,),
),
);