连接多数据库的问题

首先说明下db的设计:

有两个db,分别是daogou和member,在daogou db里有dg_goods表,在member db里没有dg_goods表。

然后贴上db配置main.php:

‘components’=>array(

    [color="#FF0000"][b]'db'[/b][/color]=>array( //主连接,注意主连接的db为member,似乎从连接会依赖它,导致出现问题。


        'class' => 'CDbConnection',


        'connectionString' => 'mysql:host=localhost;port=3309;dbname=[color="#8B0000"]member[/color]',


        'emulatePrepare' => true,


        'username' => 'root',


        'password' => '*****',


        'charset' => 'utf8',


    ),


    [color="#FF0000"][b]'daogou'[/b][/color]=>array(  //从连接 daogou,注意不管从连接的dbname设为什么,都没用,依赖主连接。


        'class' => 'CDbConnection',


        'connectionString' => 'mysql:host=localhost;port=3309;dbname=daogou',


        'emulatePrepare' => true,


        'username' => 'root',


        'password' => '*****',


        'charset' => 'utf8',


    ),


    [color="#FF0000"][b]'member'[/b][/color]=>array( //从连接 member


        'class' => 'CDbConnection',


        'connectionString' => 'mysql:host=localhost;port=3309;dbname=member',


        'emulatePrepare' => true,


        'username' => 'root',


        'password' => '*****',


        'charset' => 'utf8',


    ),

)

下面是model Job.php:

class Job extends CActiveRecord

{

public static function model($className=__CLASS__)


{


    return parent::model($className);


}





public function tableName()


{


    return 'dg_goods'; //存在于daogou db


}





public function get()


{


    $conn = Yii::app()->daogou;


    var_dump($conn); //





}

}

按照正常来说,应该会打印出$conn对象。但是事实上报错,错误信息如下:

[color="#FF0000"]The table "dg_goods" for active record class "Job" cannot be found in the database.[/color]

在database daogou 明明存在 dg_goods表,然后我把主连接的dbname修改为daogou:

    'db'=>array(


        'class' => 'CDbConnection',


        'connectionString' => 'mysql:host=localhost;port=3309;dbname=[color="#8B0000"]daogou[/color]',


        'emulatePrepare' => true,


        'username' => 'root',


        'password' => '*****',


        'charset' => 'utf8',


    ),

就可以正确打印出$conn对象:

object(CDbConnection)#53 (22) {

["connectionString"]=>string(44) "mysql:host=localhost;port=3309;dbname=daogou"

["username"]=>string(4) "root"

}

我把从连接daogou 的dbname去掉:

    'daogou'=>array(


        'class' => 'CDbConnection',


        'connectionString' => 'mysql:host=localhost;port=3309;dbname=',


        'emulatePrepare' => true,


        'username' => 'root',


        'password' => '*****',


        'charset' => 'utf8',


    ),

依然可以打印出$conn对象:

object(CDbConnection)#53 (22) {

["connectionString"]=>string(38) "mysql:host=localhost;port=3309;dbname="

["username"]=>string(4) "root"

}

dbname允许为空?

而且必须有个叫"db"的主连接,删掉或者修改为其他名称后又报错:

CDbConnection.connectionString cannot be empty.

实在弄不明白Yii的多数据库连接原理,现在用的是1.1.4版本,急切需要多数据库连接,哪位帮忙看看如何解决。

我看了这里 如何操作多数据库

qiang哥提到的两种办法:

方法1: 重写getDbConnection(),返回你想要的DB连接。

方法2: 设置CActiveRecord::$db

但不是说1.1支持通过Yii::app()->db1获得从连接吗?

问题在于"从连接"会受"主连接"的影响而导致无法连接正确的db,有谁可以帮帮忙看看什么原因?

实在不行就只能重写getDbConnection()了…

你这个错误是因为在初始化这个Model时调用 getTableName() 时由于你没有重写Model::$db或getDbConnection所以,它当然用默认的 Yii::app()->db 了,这里报错了,而不是运行你的 get() 才报的错啊!

你的问题很简单就是覆盖各个 Model 的 getDbConnection() 即可,最简单就用下面的:

public function getDbConnection()

{

if (self::$db === null)

self::$db = Yii::app()->daogou;

return self::$db;

}

public functin getDbConnection()

{

return Yii::app()->daogou;

}

非常感谢!

这样的确可以,但是我想如果非要在model里重写getDbConnection()方法来改变连接对象,

那么qiang说的支持通过Yii::app()->db1得到连接不就是没有意义了吗?

或者是不是可以这样理解qiang说的意思:可以通过Yii::app()->db1得到连接,前提是需要重写getDbConnection():

public functin getDbConnection()

{

return Yii::app()->db1;

}

即使这样也会有同样的问题,也就是在同一个model里,我需要来回的切换不同的DB连接,当我调用Yii::app()->db2,岂不是又返回db1连接了(初始化就确定了)?这样就无法做到在同一个model里自由切换DB.

如果Yii底层实现的逻辑如你说的那样(获取db连接是在初始化model时候确定,而不是在建立连接的时候确定),我觉得Yii在db配置方面应该为开发者提供足够的支持。

我还是非常喜欢Yii的

他的意思可能多个数据库只是主从之类的冗余,可以从默认的DB组件获取所有表的结构。

但你这个情况相当于分库,库之间完全不同,所以肯定必须重写 getDbConnection() 否则 model 在初始化时无法正确得到 db 的 schema 结构了。

谢谢,看来还是要重写 getDbConnection() :(