多个数据库连接和Yii 2.0

时间:2014-12-02 16:43:01

标签: yii2

我有两个数据库,每个数据库都有相同字段的相同表,但如何在Yii 2.0中同时获取所有两个数据库中的所有记录?

4 个答案:

答案 0 :(得分:99)

首先,您需要配置您的数据库,如下所示:

return [
'components' => [
    'db1' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=db1name', //maybe other dbms such as psql,...
        'username' => 'db1username',
        'password' => 'db1password',
    ],
    'db2' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=db2name', // Maybe other DBMS such as psql (PostgreSQL),...
        'username' => 'db2username',
        'password' => 'db2password',
    ],
],
];

然后你可以简单地说:

// To get from db1
Yii::$app->db1->createCommand((new \yii\db\Query)->select('*')->from('tbl_name'))->queryAll()

// To get from db2
Yii::$app->db2->createCommand((new \yii\db\Query)->select('*')->from('tbl_name'))->queryAll()

如果您使用的是活动记录模型,则可以在模型中定义:

public static function getDb() {
    return Yii::$app->db1;
}

//Or db2
public static function getDb() {
    return Yii::$app->db2;
}

然后:

如果您在db1方法中设置了getDb(),则会从db1获取结果,依此类推。

ModelName::find()->select('*')->all();

答案 1 :(得分:19)

添加: 我按照提供的答案,但仍然有错误: "未知组件ID:db"

经过一些测试,这是我发现的:函数getDB只被称为 AFTER 与db建立连接。因此,您无法删除或重命名' db'在配置文件中。相反,你需要打电话给' db'正常进行,然后再覆盖它。

解决方案(对我来说)如下:

config/web.php中,在db下面添加第二个数据库配置,如下所示:

'db' => require(__DIR__ . '/db.php'),
'db2' => [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=name',
    'username' => 'user',
    'password' => 'password',
    'charset' => 'utf8',
    'on afterOpen' => function ($event) {
        $event->sender->createCommand("SET time_zone = '+00:00'")->execute();
    },
],

请勿重命名db。找不到db会导致错误。你可以任意命名db2

现在在模型中,添加以下代码:

class ModelNameHere extends \yii\db\ActiveRecord {

   // add the function below:
   public static function getDb() {
       return Yii::$app->get('db2'); // second database
   }

现在将覆盖默认的db配置。

我希望能帮助别人。

注意:您可以将db2的配置包含在另一个文件中,但不能将其包含在db.php文件中(显然)。而是创建一个名为db2.php的文件,并像db一样调用它:

'db' => require(__DIR__ . '/db.php'),    
'db2' => require(__DIR__ . '/db2.php'),

由于

答案 2 :(得分:1)

我们的情况稍微复杂一点,我们有一个父母"数据库,其中包含一个包含一个或多个" child"的名称的表。数据库。 原因是Yii项目是为每个客户端实例化的,子数据库的数量取决于客户端,数据库名称也是任意的(尽管遵循模式)。

所以我们覆盖 \yii\db\ActiveRecord 如下:

class LodgeActiveRecord extends \yii\db\ActiveRecord
{

public static function getDb()
{
    $lodgedb = Yii::$app->params['lodgedb'];
    if(array_key_exists( $lodgedb, Yii::$app->params['dbs'])) {
        return Yii::$app->params['dbs'][ $lodgedb ];
    }
    $connection = new \yii\db\Connection([
        'dsn' => 'mysql:host=localhost;dbname=' . $lodgedb,
        'username' => Yii::$app->params['dbuser'],
        'password' => Yii::$app->params['dbpasswd'],
        'charset' => 'utf8',
    ]);
    $connection->open(); // not sure if this is necessary at this point
    Yii::$app->params['dbs'][ $lodgedb ] = $connection;
    return $connection;
}

}

在调用任何数据库函数之前,首先将Yii::$app->params['lodgedb']设置为所需数据库的名称:

Yii::$app->params['lodgedb'] = $lodge->dbname; // used by LodgeActiveRecord

您的模型类除了从LodgeActiveRecord扩展后才会改变:

class BookingRooms extends \app\models\LodgeActiveRecord

答案 3 :(得分:0)

如果您使用schmunk42/yii2-giiant生成模型类,则有一个'modelDb'属性,可以将其设置为使用'db'以外的数据库组件。