[英]How to use multiple databases in Laravel
我想在我的系統中組合多個數據庫。 大多數時候數據庫是MySQL; 但將來可能會有所不同,即管理員可以生成此類使用異構數據庫系統源的報告。
所以我的問題是Laravel 是否提供任何 Facade來處理這種情況? 或者任何其他框架具有更適合問題的能力?
.env
>= 5.0 (在 5.5 上測試)(在 8 上工作) 在.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database1
DB_USERNAME=root
DB_PASSWORD=secret
DB_CONNECTION_SECOND=mysql
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=database2
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=secret
在config/database.php
'mysql' => [
'driver' => env('DB_CONNECTION'),
'host' => env('DB_HOST'),
'port' => env('DB_PORT'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
],
'mysql2' => [
'driver' => env('DB_CONNECTION_SECOND'),
'host' => env('DB_HOST_SECOND'),
'port' => env('DB_PORT_SECOND'),
'database' => env('DB_DATABASE_SECOND'),
'username' => env('DB_USERNAME_SECOND'),
'password' => env('DB_PASSWORD_SECOND'),
],
注意:在
mysql2
中,如果 DB_username 和 DB_password 相同,則可以使用.env
前幾行中提到env('DB_USERNAME')
。
.env
<5.0定義連接
app/config/database.php
return array(
'default' => 'mysql',
'connections' => array(
# Primary/Default database connection
'mysql' => array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'database1',
'username' => 'root',
'password' => 'secret'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Secondary database connection
'mysql2' => array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'database2',
'username' => 'root',
'password' => 'secret'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);
架構
要指定使用哪個連接,只需運行connection()
方法
Schema::connection('mysql2')->create('some_table', function($table)
{
$table->increments('id'):
});
查詢生成器
$users = DB::connection('mysql2')->select(...);
雄辯
在模型中設置$connection
變量
class SomeModel extends Eloquent {
protected $connection = 'mysql2';
}
您還可以通過setConnection
方法或on
靜態方法在運行時定義連接:
class SomeController extends BaseController {
public function someMethod()
{
$someModel = new SomeModel;
$someModel->setConnection('mysql2'); // non-static method
$something = $someModel->find(1);
$something = SomeModel::on('mysql2')->find(1); // static method
return $something;
}
}
注意嘗試與跨數據庫的表建立關系時要小心! 可以這樣做,但它可能帶有一些警告,並且取決於您擁有的數據庫和/或數據庫設置。
使用多個數據庫連接
當使用多個連接時,您可以通過DB
門面的連接方法訪問每個connection
。 傳遞給connection
方法的name
應與config/database.php
配置文件中列出的連接之一相對應:
$users = DB::connection('foo')->select(...);
您還可以使用連接實例上的 getPdo 方法訪問原始的底層 PDO 實例:
$pdo = DB::connection()->getPdo();
有用的鏈接
在 Laravel 5.1 中,您指定連接:
$users = DB::connection('foo')->select(...);
默認,Laravel 使用默認連接。 這很簡單,不是嗎?
在此處閱讀更多信息:http: //laravel.com/docs/5.1/database#accessing-connections
實際上, DB::connection('name')->select(..)
對我不起作用,因為 'name' 必須用雙引號引起來:“name”
盡管如此,選擇查詢是在我的默認連接上執行的。 仍在嘗試弄清楚如何說服 Laravel 以預期的方式工作:更改連接。
編輯:我想通了。 調試 Laravel DatabaseManager 后發現我的 database.php(配置文件)(在 $this->app 中)是錯誤的。 在“連接”部分中,我有諸如“數據庫”之類的東西,其中包含我從中復制它的值。 明確地說,而不是
env('DB_DATABASE', 'name')
我需要放置類似的東西
'myNewName'
因為所有連接都列出了相同的數據庫、用戶名、密碼等值。如果我想訪問至少另一個數據庫名稱,這當然沒有什么意義
因此,每次我想從另一個數據庫中選擇一些東西時,我總是在我的默認數據庫中結束
Laravel 內置支持多種數據庫系統,您需要在config/database.php文件中提供連接詳細信息
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'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,
],
'mysqlOne' => [
'driver' => 'mysql',
'host' => env('DB_HOST_ONE', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE_ONE', 'forge'),
'username' => env('DB_USERNAME_ONE', 'forge'),
'password' => env('DB_PASSWORD_ONE', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
];
一旦你有了這個,你可以為每個連接創建兩個基本模型類並在這些模型中定義連接名稱
//BaseModel.php
protected $connection = 'mysql';
//BaseModelOne.php
protected $connection = 'mysqlOne';
您可以擴展這些模型以為每個數據庫中的表創建更多模型。
你也可以使用 postgres fdw 系統
https://www.postgresql.org/docs/9.5/postgres-fdw.html
您將能夠在 postgres 中連接不同的數據庫。 之后,在一個查詢中,您可以訪問不同數據庫中的表。
如果您想克隆現有系統並為新客戶在新數據庫上運行現有代碼,這不是一個好的解決方案。
我們將不得不編輯數百個雄辯的調用來插入 DB:: connection('foo')
您可以使用多個數據庫連接環境,如下所示
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database1
DB_USERNAME=root
DB_PASSWORD=password
DB_CONNECTION_SECOND=mysql
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=database2
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=password
並在 config/database.php
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql2' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL_SECOND'),
'host' => env('DB_HOST_SECOND', '127.0.0.1'),
'port' => env('DB_PORT_SECOND', '3306'),
'database' => env('DB_DATABASE_SECOND', 'forge'),
'username' => env('DB_USERNAME_SECOND', 'forge'),
'password' => env('DB_PASSWORD_SECOND', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
然后您可以在 controller 中使用,遷移和查詢構建器如下
DB::connection('mysql2')->table("articles")->get();
or
$Model = new Article;
$Model->setConnection('mysql2');
$find = $Model->find(1);
return $find;
or
Schema::connection('mysql2')->create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('body')->nullable();
$table->timestamps();
});
完整的例子和文章
這對我有用
中間件:
<?php
namespace App\Http\Middleware;
use Config;
use Closure;
use DB;
class DBSelect
{
public function handle($request, Closure $next)
{
//$db_name = "db1";
$db_name = "db2";
Config::set('database.connections.mysql.database', $db_name);
DB::reconnect('mysql');
return $next($request);
}
}
全球 Kernel.php
protected $middleware = [
.....
\App\Http\Middleware\DBSelect::class,
];
我從這個答案 ( https://stackoverflow.com/a/64744187/4514022 ) 更改了一些代碼,它對我有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.