在Laravel中动态连接多个数据库

时间:2018-06-28 04:37:15

标签: php database laravel multiple-databases connection

我正在构建一个需要连接2个数据库的应用程序。第一个是静态的,另一个是动态的。 config / database.php就像

'mysql' => 
array (
  'driver' => 'mysql',
  'host' => '127.0.0.1',
  'port' => '3306',
  'database' => 'blog',
  'username' => 'root',
  'password' => '',
  'unix_socket' => '',
  'charset' => 'utf8mb4',
  'collation' => 'utf8mb4_unicode_ci',
  'prefix' => '',
  'strict' => true,
  'engine' => NULL,
),
'business2' => 
array (
  'driver' => 'mysql',
  'host' => '127.0.0.1',
  'port' => '3306',
  'database' => 'blog2',
  'username' => 'root',
  'password' => '',
  'unix_socket' => '',
  'charset' => 'utf8mb4',
  'collation' => 'utf8mb4_unicode_ci',
  'prefix' => '',
  'strict' => true,
  'engine' => NULL,
),

和模型代码类似

Class  TableNewData extends Model
{
    protected $connection = 'business3';
    protected $table = 'table2_data';
    public function getData()
    {
        return $this->get()->toArray();
    }
}

如果我提供静态连接详细信息,我就可以连接多个数据库,但是如果我提供诸如动态连接详细信息,则我将无法连接数据库

 $connection = Session::get()->connection;  

$connection=$_SESSION('connection');

在不影响应用程序性能的情况下动态连接多个数据库的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

我和你有同样的问题。该博客绝对可以帮助您。

The Ultimate Guide for Laravel Multi Tenant with Multi Database

根据您的情况,这是config / database.php文件的外观。由于第二个是动态的,因此无需定义数据库。

'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'blog'),
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', 'password'),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => 'InnoDB',
    ],
'business' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => '',
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', 'password'),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => 'InnoDB',
    ], 

基本上,设置一个数据库帮助程序功能,该功能在运行时连接到数据库,然后在正确的中间件中调用它。我只是将帮助程序文件放在database / utilities / helpers.php

function connect($hostname, $username, $password, $database)
{
    // Erase the tenant connection, thus making Laravel get the default values all over again.
    DB::purge('business');
    // Make sure to use the database name we want to establish a connection.
    Config::set('database.connections.tenant.host', $hostname);
    Config::set('database.connections.tenant.database', $database);
    Config::set('database.connections.tenant.username', $username);
    Config::set('database.connections.tenant.password', $password);
    // Rearrange the connection data
    DB::reconnect('business');
    // Ping the database. This will throw an exception in case the database does not exists.
    Schema::connection('tenant')->getConnection()->reconnect();
}

不要忘记告诉作曲家,可以通过将这些行添加到composer.json文件中来全局使用helper函数。

"autoload": {
    "classmap": [
        "database"
    ],
    "files":[
        "database/utilities/helpers.php"
    ],
    "psr-4": {
        "App\\": "app/"
    }
},

您还希望拥有应该扩展的静态和动态模型,以定义要使用的数据库连接。

class StaticModel extends Model
{
    protected $connection = 'mysql';
}
class DynamicModel extends Model
{
    protected $connection = 'business';
}

在中间件中,根据数据库名称建立动态数据库连接。

connect(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_SYMBOL') . $databasename);

因此,您可以正常使用该模型,但是它具有动态数据库连接

答案 1 :(得分:1)

在运行时更改连接的一种方法是通过config设置值:

config(['database.connections.mysql' => [
    'driver'    => 'mysql',
    'host'      => env('DB_HOST', 'localhost'),
    'database'  => env('DB_DATABASE', 'my_database'),
    'username'  => env('DB_USERNAME', 'my_user'),
    'password'  => env('DB_PASSWORD', 'my_password'),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
    'strict'    => false,
]]);

例如,可以将其应用于中间件以在租户数据库之间动态切换。

您还可以通过数据库外观指定连接:

DB::connection('mysql_2')->select(...);