如何将控制器中的数据库添加到应用程序 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?的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数从控制器传递到 YII2 中的布局

如何将Yii2模型作为数组?

Yii2 HOW-TO:最佳实践

Yii2如何将表单请求发送到外部url

如何在 YII2 Advanced 中将 Employee 表中的数据添加到用户表中

将网格视图中的选中行插入到 yii2 中的表中