如何将控制器中的数据库添加到应用程序 Yii2?
Posted
技术标签:
【中文标题】如何将控制器中的数据库添加到应用程序 Yii2?【英文标题】:How to add database in controller to app Yii2? 【发布时间】:2018-08-16 11:15:55 【问题描述】:我有一个 Yii2 项目,这个应用程序应该在多个数据库之间传输数据,并且应该同时连接到它们。
问题是用户发送了正确的数据库(在用户的请求中),我不想在应用程序开始时连接到所有数据库,原因有两个:
-
数据库数量巨大
在某些请求中,连接到一个 db 就足够了,连接到所有这些是无用的,可能会影响处理速度。
所以我应该在控制器中创建一个数据库连接。我无法在 raw php
中创建连接,因为我想将连接传递给我的一些模型,并且我的模型应该使用新数据库传输数据。
换句话说,我想从一个模型创建实例,但使用多个数据库。
我曾尝试像这样将 db 添加到我的项目中,但它会抛出 can not add property to Component or App
。
这些是我的代码不起作用:
Yii::$app->db2 = [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=databasename',
'username' => 'username',
'password' => 'pass',
'charset' => 'utf8',
];
和
Yii::$app->components->db2 = [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=databasename',
'username' => 'username',
'password' => 'pass',
'charset' => 'utf8',
];
【问题讨论】:
您需要在 config/web.php 中为每个数据库连接创建配置。在相应的模型中,您需要使用 function public static function getDb() return Yii::$app->get('myNewDB'); 【参考方案1】:要访问数据库,您也可以在不使用应用程序组件的情况下构建 db connect,在这种情况下,您首先需要通过创建 `yii\db\Connection 的实例来连接到 db:
$yourdb = new yii\db\Connection([
'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
您可以访问数据库,例如:
$posts = $db->createCommand('SELECT * FROM post')->queryAll();
https://www.yiiframework.com/doc/guide/2.0/en/db-dao#creating-db-connections
【讨论】:
如何将此连接传递给模型的公共静态函数 getDb? 您可以重新定义相关的 getDb .. 并传递您需要的值 .. 只需将 getDb 添加到您的模型中 .. 可以根据需要工作 .. 您可以将连接存储在全局参数中并检索 getDb 中的相关值...有几种方法.. 我可以将一个模型的两个实例连接到两个不同的数据库吗? 这对我来说似乎是一个新问题 .. 并且不清楚您在寻找什么 .. .. 无论如何 .. 您应该管理两个不同的连接(例如:getDb1 和 getDb2)以进行访问您每次都需要的数据库,但模型可以与多个数据库一起使用 .. 相关的数据库表必须具有相同的结构 /schema【参考方案2】:在您的配置文件中,将取决于您使用的模板,对于config/db.php
中的基本模板,高级模板将为/common/config/main-local.php
。为每个数据库的内部组件创建两个数组,例如:
'components' => [
'db1' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=db',
'username' => 'username',
'password' => 'pass',
'charset' => 'utf8',
],
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=whateveritscalled;dbname=db2',
'username' => 'user',
'password' => 'pass',
'charset' => 'utf8',
],
]
];
那么你应该可以像这样访问它们:
Yii::$app->db1->createCommand()
Yii::$app->db2->createCommand()
【讨论】:
【参考方案3】:这种方式需要使用Application::set()
来配置组件:
Yii::app->set('db2', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=databasename',
'username' => 'username',
'password' => 'pass',
'charset' => 'utf8',
]);
Yii::$app->db2->createCommand($sql)->execute();
还要注意,Yii 使用延迟加载来启动组件。即使你配置了DB连接组件,只要你不使用它,这个组件就不会被初始化,也不会打开连接。因此,您可以安全地配置 1000 个 DB 组件 (db1, db2, ... db1000
),并且只使用一个 - 其他 999 个组件不会初始化,只会打开一个 DB 连接。
但是,如果您有这么多的数据库,您可以考虑创建某种DbManager
,它将存储所有可用的连接配置并根据请求初始化连接(如Yii::$app->dbManager->get('123'); // <- returns connection nr 123
) - 它应该比注册额外的更干净数千个组件,绝对比在控制器中设置数据库连接组件更干净。
【讨论】:
以上是关于如何将控制器中的数据库添加到应用程序 Yii2?的主要内容,如果未能解决你的问题,请参考以下文章