[教程] 如何在一个项目中使用多个数据库

最近stackoverflow推出了Document,我在上面发表了我的在项目中使用多数据库的经验。大家如果有帐号,就帮忙给我点个赞 :blush:

http://stackoverflow.com/documentation/lar...

我在用中文写一次:

Laravel 允许用户使用多个数据库在一个项目中一起使用。如果你需要几个数据库一起使用,你需要注意一些设置。

那么我就来谈谈我自己的一些经验。

Laravel允许使用几个数据库,甚至是不同类型的数据库。

基本设置

在 config/database.php 里,你可以设置默认的数据库连接:

'default' => env('DB_CONNECTION', 'mysql'),

这个名字是表示下面配置的 mysql 项:

'connections' => [

    'sqlite' => [
        'driver' => 'sqlite',
        'database' =>  database_path('database.sqlite'),
        'prefix' => '',
    ],

    'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,
    ],
],

如果你不提数据库连接在你的代码或者命令行中,Laravel只会使用这个默认连接。但是在多数据库连接的使用案例中,就算设置了默认数据库,你也最好在你的使用过程中,写明你的目标数据库的连接名字。

数据库迁移文件

迁移文件, 如果是单数据库,你会用以下设置:

 Schema::create("table",function(Blueprint $table){
     $table->increments('id');
});

如果是多数据库, 你要使用 ···connection()··· 的方法告诉Laravel你是用那个数据连接:

 Schema::connection("sqlite")->create("table",function(Blueprint $table){
     $table->increments('id');
});

命令行Migrate

单数据库时,你会运行一下命令行:

php artisan migrate

但是在多数据库中,你要告诉laravel,你要使用那个数据库来维护你迁移历史:

php artisan migrate:install --database=sqlite

这个命令是创建迁移历史表格在你的目标数据库中

php artisan migrate --database=sqlite

创建数据库表格的命令,历史保存在目标数据库中

php artisan migrate:rollback --database=sqlite

回滚数据库表格的命令,历史保存在目标数据库中

Eloquent Model

在 eloquent模型中配置多数据库, 你需要在 $connection 属性中填写你的数据库连接:

namespace App\Model\Sqlite;
class Table extends Model
{
    protected $table="table";
    protected $connection = 'sqlite';
}

单元测试

Laravel 提供了seeInDatabase($table,$fielsArray,$connection) to 来测试数据库保存的数据.使用时候可以像这样:

$this
    ->json(
        'GET',
        'result1/2015-05-08/2015-08-08/a/123'
    )
     ->seeInDatabase("log", ["field"=>"value"], 'sqlite');

这样,就可以告诉Laravel,你是要测试那个数据库了

单元测试数据库回滚设置

Laravel 允许在测试完成后回滚所有数据。如果是多数据的话,需要设置$connectionsToTransact 属性

use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends TestCase
{
     use DatabaseTransactions;

     $connectionsToTransact =["mysql","sqlite"] //tell Laravel which database need to rollBack

    public function testExampleIndex()
    {
        $this->visit('/action/parameter')
         ->see('items');
    }
}
本帖已被设为精华帖!
本帖由 Summer 于 7年前 加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4
Summer

写的很清晰 :100:

7年前 评论

@Summer 谢谢。 昨天忘记写“单元测试数据库回滚设置”的部分,刚刚已经加上。

自己用laravel写的几个项目都是要连接多数据库的,正好借了个机会把自己的经验整理出来。

7年前 评论

不知道楼主怎么解决多数据库情况下的多对多关联?
比如:

  • users 表在 database_one 数据库
  • tags 表和关联表 user_tagdatabase_two 数据库
  • database_onedatabase_two在不同的服务器。

$user->tags 或者 $tag->users 的时候怎么指定它们的中间表 user_tag 所连接的数据库?
我看了 BelongsToMany 类的代码,它是以关联对象所在的数据库连接为准,比如用 $user->tags 时,会连接到 tags 表所在的数据库,没有找到可以指定中间表的连接的方法。

不知道楼主有没有好的解决方案?

7年前 评论
nickfan

@Summer @caoglish 不知道laravel有没有在query前设置connection的事件,
比如数据对象要水平切分的时候,1-100存在db1,100-200存在db2,200-300存在db3等等。

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!