yii2 动态改变数据库
yii2 change database dynamically
我正在尝试动态移动到另一个数据库。我已经看到几个问题,这些问题显示将 db 文件从一个更改为另一个,他们只是从下一个数据库获取一些信息。但我需要的是完全转移到第二个数据库。我应该怎么做?我已经看到,为了实现这个 dsn(在 db.php 文件中)应该被改变。但是我改了还是没改??我应该可以完全访问第二个数据库并关闭第一个数据库。请给我建议
像 db.php
这样的配置不打算在过程中更改(而 PHP 正在处理)。当请求进入框架时,它们在初始化时加载一次。
作为替代方案,您可以预先在 db.php
中配置第二个数据库,并在它们之间动态更改,如:
Yii::$app->db // your default Database
和
Yii::$app->db2 // Second configured Database, to which you can switch dynamically later
你可以了解一下multiple database connections here
因此,如果您希望 ActiveRecord(例如 User)能够访问两个数据库,您可以定义一些静态变量,指定从哪个数据库访问 read/write。例如:
class User extends \yii\db\ActiveRecord
{
const DB_DATABASE1 = 'db1';
const DB_DATABASE2 = 'db2';
private static $db = self::DB_DATABASE1;
public static function setDb($db)
{
self::$db = $db;
}
public static function getDb()
{
switch (self::$db) {
case self::DB_DATABASE1:
return Yii::$app->db;
case self::DB_DATABASE2:
return Yii::$app->db2;
default:
throw new \Exception("Database is not selected");
}
}
//...
然后在 Controller 中使用它,如:
User::setDb(User::DB_DATABASE1);
$usersDB1 = User::find()->all();
User::setDb(User::DB_DATABASE2);
$usersDB2 = User::find()->all();
在您的 main.php 或 main-local.php 配置中设置多个数据库连接
Yii::$app->db1;
Yii::$app->db2;
Yii::$app->db3;
查询时
$usersDB1=User::find()->all(Yii::$app->db1);
$usersDB2=User::find()->all(Yii::$app->db2);
$usersDB3=User::find()->all(Yii::$app->db3);
全局动态切换到不同的数据库
这里我合并了 above and Write & use a custom Component in Yii2.0
首先,创建一个组件class 来进行数据库切换。在这里,我称它为DbSelector,放在app\components\DbSelector.php
.
namespace app\components;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
class DbSelector extends Component {
const DB_MAIN = 'db';
const DB_SUB1 = 'db1';
const DB_SUB2 = 'db2';
private static $db = self::DB_MAIN;
public static function setDb($db)
{
self::$db = $db;
}
public static function getDb()
{
return \Yii::$app->get(self::$db);
}
}
其次,修改 config/web.php
文件或任何您的配置文件以具有多个数据库,并添加 DbSelector 作为 Yii::$app
组件。
$config = [
'components' => [
//...
'db' => $db,
'db1' => $db1,
'db2' => $db2,
'dbSelector' => [
'class' => 'app\components\DbSelector',
],
//...
],
//...
];
三、在每个模型class中添加如下static function getDb()
调用DbSelector getDb()
:
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
例如,
class DiningTable extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '{{%dining_table}}';
}
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
//...
}
class Customer extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '{{%customer}}';
}
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
//...
}
最后,要全局切换到不同的数据库,请使用 \Yii::$app->dbSelector->setDb(YOUR_PREFERRED_DB)
、
use app\components\DbSelector;
//...
\Yii::$app->dbSelector->setDb(DbSelector::DB_SUB1);
$tables_1 = DiningTable::findAll();
$customers_1 = Customer::find()->where(['<', 'dob', '2000-01-01'])->all();
\Yii::$app->dbSelector->setDb(DbSelector::DB_MAIN);
$tables_main = DiningTable::findAll();
$customers_main = Customer::find()->where(['<', 'dob', '2000-01-01'])->all();
我正在尝试动态移动到另一个数据库。我已经看到几个问题,这些问题显示将 db 文件从一个更改为另一个,他们只是从下一个数据库获取一些信息。但我需要的是完全转移到第二个数据库。我应该怎么做?我已经看到,为了实现这个 dsn(在 db.php 文件中)应该被改变。但是我改了还是没改??我应该可以完全访问第二个数据库并关闭第一个数据库。请给我建议
像 db.php
这样的配置不打算在过程中更改(而 PHP 正在处理)。当请求进入框架时,它们在初始化时加载一次。
作为替代方案,您可以预先在 db.php
中配置第二个数据库,并在它们之间动态更改,如:
Yii::$app->db // your default Database
和
Yii::$app->db2 // Second configured Database, to which you can switch dynamically later
你可以了解一下multiple database connections here
因此,如果您希望 ActiveRecord(例如 User)能够访问两个数据库,您可以定义一些静态变量,指定从哪个数据库访问 read/write。例如:
class User extends \yii\db\ActiveRecord
{
const DB_DATABASE1 = 'db1';
const DB_DATABASE2 = 'db2';
private static $db = self::DB_DATABASE1;
public static function setDb($db)
{
self::$db = $db;
}
public static function getDb()
{
switch (self::$db) {
case self::DB_DATABASE1:
return Yii::$app->db;
case self::DB_DATABASE2:
return Yii::$app->db2;
default:
throw new \Exception("Database is not selected");
}
}
//...
然后在 Controller 中使用它,如:
User::setDb(User::DB_DATABASE1);
$usersDB1 = User::find()->all();
User::setDb(User::DB_DATABASE2);
$usersDB2 = User::find()->all();
在您的 main.php 或 main-local.php 配置中设置多个数据库连接
Yii::$app->db1;
Yii::$app->db2;
Yii::$app->db3;
查询时
$usersDB1=User::find()->all(Yii::$app->db1);
$usersDB2=User::find()->all(Yii::$app->db2);
$usersDB3=User::find()->all(Yii::$app->db3);
全局动态切换到不同的数据库
这里我合并了
首先,创建一个组件class 来进行数据库切换。在这里,我称它为DbSelector,放在app\components\DbSelector.php
.
namespace app\components;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
class DbSelector extends Component {
const DB_MAIN = 'db';
const DB_SUB1 = 'db1';
const DB_SUB2 = 'db2';
private static $db = self::DB_MAIN;
public static function setDb($db)
{
self::$db = $db;
}
public static function getDb()
{
return \Yii::$app->get(self::$db);
}
}
其次,修改 config/web.php
文件或任何您的配置文件以具有多个数据库,并添加 DbSelector 作为 Yii::$app
组件。
$config = [
'components' => [
//...
'db' => $db,
'db1' => $db1,
'db2' => $db2,
'dbSelector' => [
'class' => 'app\components\DbSelector',
],
//...
],
//...
];
三、在每个模型class中添加如下static function getDb()
调用DbSelector getDb()
:
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
例如,
class DiningTable extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '{{%dining_table}}';
}
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
//...
}
class Customer extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '{{%customer}}';
}
public static function getDb()
{
return \Yii::$app->dbSelector->getDb();
}
//...
}
最后,要全局切换到不同的数据库,请使用 \Yii::$app->dbSelector->setDb(YOUR_PREFERRED_DB)
、
use app\components\DbSelector;
//...
\Yii::$app->dbSelector->setDb(DbSelector::DB_SUB1);
$tables_1 = DiningTable::findAll();
$customers_1 = Customer::find()->where(['<', 'dob', '2000-01-01'])->all();
\Yii::$app->dbSelector->setDb(DbSelector::DB_MAIN);
$tables_main = DiningTable::findAll();
$customers_main = Customer::find()->where(['<', 'dob', '2000-01-01'])->all();