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

11 浏览
0 Comments

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

这个问题已经在这里有答案:

如何在Laravel中使用多个数据库

我正在构建一个需要连接两个数据库的应用程序。一个是静态数据库,另一个是动态数据库。

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');

连接多个数据库的最佳方式是什么,而不会影响应用程序的性能?

admin 更改状态以发布 2023年5月21日
0
0 Comments

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

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门面指定连接:

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

0
0 Comments

我和你一样也遇到了同样的问题。这篇博客绝对可以帮助你。

Laravel多数据库多租户的终极指南

根据你的情况,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文件添加这些行,告诉composer可以全局使用助手函数。

"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);

因此,您可以像平常一样使用该模型,但它具有动态数据库连接。

0