定义和使用多个数据库连接

对于新的单机web应用,多数据库连接并不常用。但是,当你为一个已经存在的系统附加一个应用是,你很可能需要另外一个数据库连接。

在本节中,你将会学习如何定义多个数据库连接并利用DAO、Query Builder和Active Record模型使用它们。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 创建两个MySQL数据库,名字分别叫db1db2
  3. db1中创建一个名叫post的表:
  1. DROP TABLE IF EXISTS 'post';
  2. CREATE TABLE IF NOT EXISTS 'post' (
  3. 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. 'title' VARCHAR(255) NOT NULL,
  5. 'text' TEXT NOT NULL,
  6. PRIMARY KEY ('id')
  7. );
  1. db2中创建一个名叫comment的表:
  1. DROP TABLE IF EXISTS 'comment';
  2. CREATE TABLE IF NOT EXISTS 'comment' (
  3. 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. 'text' TEXT NOT NULL,
  5. 'post_id' INT(10) UNSIGNED NOT NULL,
  6. PRIMARY KEY ('id')
  7. );

如何做…

  1. 首先配置数据库连接。打开config/main.php文件,按照官方指南中的描述,定义一个主连接:
  1. 'db' => [
  2. 'connectionString' =>'mysql:host=localhost;dbname=db1',
  3. 'username' => 'root',
  4. 'password' => '',
  5. 'charset' => 'utf8',
  6. ],
  1. 复制它,重命名db组件为db2,并相应修改connectionString。同时,你需要按照如下方式添加class
  1. 'db2' => [
  2. 'class'=>'yii\db\Connection',
  3. 'connectionString' => 'mysql:host=localhost;dbname=db2',
  4. 'username' => 'root',
  5. 'password' => '',
  6. 'charset' => 'utf8',
  7. ],
  1. 现在你有两个数据库连接,你可以按如下方式利用DAO和Query Builder使用它们:
  1. $rows1 = Yii::$app->db->createCommand($sql)->queryAll();
  2. $rows2 = Yii::$app->db2->createCommand($sql)->queryAll();
  1. 现在,如何我们需要使用Active Record模型,首先我们需要使用Gii创建Post和Comment模型。你可以为每一个模型选择一个合适的连接。当你创建Comment模型时,将数据库连接ID设置为db2,如下截图所示:

定义和使用多个数据库连接 - 图1

  1. 现在你可以按往常一样使用Comment模型,并创建controllers/DbController.php
  1. <?php
  2. namespace app\controllers;
  3. use app\models\Post;
  4. use app\models\Comment;
  5. use yii\helpers\ArrayHelper;
  6. use yii\helpers\Html;
  7. use yii\web\Controller;
  8. /**
  9. * Class DbController.
  10. * @package app\controllers
  11. */
  12. class DbController extends Controller
  13. {
  14. public function actionIndex()
  15. {
  16. $post = new Post();
  17. $post->title = 'Post #'.rand(1, 1000);
  18. $post->text = 'text';
  19. $post->save();
  20. $posts = Post::find()->all();
  21. echo Html::tag('h1', 'Posts');
  22. echo Html::ul(ArrayHelper::getColumn($posts, 'title'));
  23. $comment = new Comment();
  24. $comment->post_id = $post->id;
  25. $comment->text = 'comment #'.rand(1, 1000);
  26. $comment->save();
  27. $comments = Comment::find()->all();
  28. echo Html::tag('h1', 'Comments');
  29. echo Html::ul(ArrayHelper::getColumn($comments,
  30. 'text'));
  31. }
  32. }
  1. 运行db/index多次,然后你将会看到记录保存到了两个数据库中,如下截图所示:

定义和使用多个数据库连接 - 图2

工作原理…

在Yii中,你可以通过配置文件添加和配置你自己的组件。对于非标准的组件,例如db2,你必须指定组件类。类似地,你可以添加db3db4或者其他组件,例如facebookApi。剩余的数组键值对分别赋值给了组件的公共属性。

更多…

依赖于使用的RDBMS,有一个额外的事情可以做,能让我们更方便的使用多个数据库。

跨数据库关系

如果你使用的是MySQL,你可以为你的模型创建跨数据库的关系。为了做到这一步,你应该为Comment模型的表名添加数据库名称:

  1. class Comment extends \yii\db\ActiveRecord
  2. {
  3. //...
  4. public function tableName()
  5. {
  6. return 'db2.comment';
  7. }
  8. //...
  9. }

现在,如果在Post模型中你定义了一个评论关系,你可以按如下方式使用:

  1. $posts = Post::find()->joinWith('comments')->all();

参考

欲了解更多信息,参考http://www.yiiframework.com/doc-2.0/guide-db-dao.html#creating-dbconnections