在laravel中动态连接多个数据库[重复]

Posted

技术标签:

【中文标题】在laravel中动态连接多个数据库[重复]【英文标题】:Connect multiple databases dynamically in laravel [duplicate] 【发布时间】:2018-12-07 01:25:08 【问题描述】:

我正在构建一个需要连接 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');

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

【问题讨论】:

试试setConnection方法$someModel->setConnection($connection); 抛出错误Class App\Models\TableNewData does not exist 你没有app\Models\TableNewData.php类吗?检查类命名空间 是的,我有课,只有在放置 setConnection 方法后才会收到上述错误 尝试运行composer dumpautoload 来处理类不存在的异常。 【参考方案1】:

我和你有同样的问题。这个博客绝对可以帮到你。

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 文件中来告诉作曲家辅助函数可以全局使用。

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

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

【讨论】:

【参考方案2】:

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

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(...);

【讨论】:

我必须将代码保存在哪里?在 config/database.php 或模型或中间件中?我有 100 多个数据库,每次我必须连接 1 个静态数据库,而另一个是剩余 100 个数据库中的一个 您是说每个数据库都有自己独特的连接凭据?如果是这种情况,我会将它们存储在数据库中并进行查找以找到必要的用户名/密码。我已经在拥有 1000 多个客户的大型 SAS 应用程序中看到了这种方法,每个客户都有自己的数据库。 是的。主数据库将具有用户名/密码和连接名称。我没有将凭据详细信息存储在数据库中,而是将它们保存在 config/database.php 文件中 在数据库或代码中存储连接详细信息不是我的问题。我面临动态调用该数据的问题。如果我静态提供连接详细信息,它工作正常,但我无法动态提供连接详细信息 这就是我在回答中使用config(...) 所展示的内容。每次有请求进来时,使用 config helper 来设置连接细节。这将设置容器中的值,您无需调用 setConnection 或其他任何东西。这只是一个示例,其中defaultconfig/database.php 中为mysql

以上是关于在laravel中动态连接多个数据库[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Laravel多个数据库PHPUnit [重复]

Laravel多个数据库同时使用所有[重复]

laravel 使用多个数据库,查询语法 [重复]

如何使用 Laravel Eloquent 在不同服务器上的多个数据库之间执行连接查询?

Laravel 动态更改连接

Laravel多数据库[重复]