在 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日
在运行时更改连接的一种方法是通过配置设置值:
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文件看起来应该是这样的。由于第二个是动态的,所以无需定义数据库。
'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);
因此,您可以像平常一样使用该模型,但它具有动态数据库连接。