View on GitHub

yii2-cookbook-chinese

Yii Application Development Cookbook(Third Edition)中文翻译

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

对于新的单机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的表:
DROP TABLE IF EXISTS 'post';
CREATE TABLE IF NOT EXISTS 'post' (
  'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  'title' VARCHAR(255) NOT NULL,
  'text' TEXT NOT NULL,
  PRIMARY KEY ('id')
);
  1. db2中创建一个名叫comment的表:
DROP TABLE IF EXISTS 'comment';
CREATE TABLE IF NOT EXISTS 'comment' (
  'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  'text' TEXT NOT NULL,
  'post_id' INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY ('id')
);

如何做…

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

  1. 现在你可以按往常一样使用Comment模型,并创建controllers/DbController.php
<?php
namespace app\controllers;
use app\models\Post;
use app\models\Comment;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\web\Controller;
/**
 * Class DbController.
 * @package app\controllers
 */

class DbController extends Controller
{
    public function actionIndex()
    {
        $post = new Post();
        $post->title = 'Post #'.rand(1, 1000);
        $post->text = 'text';
        $post->save();
        $posts = Post::find()->all();
        echo Html::tag('h1', 'Posts');
        echo Html::ul(ArrayHelper::getColumn($posts, 'title'));
        $comment = new Comment();
        $comment->post_id = $post->id;
        $comment->text = 'comment #'.rand(1, 1000);
        $comment->save();
        $comments = Comment::find()->all();
        echo Html::tag('h1', 'Comments');
        echo Html::ul(ArrayHelper::getColumn($comments,
            'text'));
    }
}
  1. 运行db/index多次,然后你将会看到记录保存到了两个数据库中,如下截图所示:

工作原理…

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

更多…

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

跨数据库关系

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

class Comment extends \yii\db\ActiveRecord
{
//...
    public function tableName()
    {
        return 'db2.comment';
    }
//...
}

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

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

参考

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