たいていのプロジェクトで扱うデータベースは1つですが、これが2つあるいは3つのデータベースにアクセスするとなったら、どう対応するのでしょう?というのが今回のテーマです。
データベースのコネクション
まず、データベースのコネクションに関しての説明です。扱うデータベースが1つとすると、
... DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=db1 DB_USERNAME=root DB_PASSWORD=password ...
と設定します。これらの環境変数は、以下のconfig/database.phpにおいてのデータベース接続のための値となります。
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_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'),
]) : [],
],
...
扱うデータベースが2つのとき
デフォルトのデータベースへのコネクションが、mysqlとすると、もう1つ扱うデータベースを mysql2 として、先のconfig/database.phpに追加することができます。
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
// デフォルトのデータベース
'mysql' => [
...
],
// 第2のデータベース
'mysql2' => [
'driver' => 'mysql',
'url' => env('DB2_URL'),
'host' => env('DB2_HOST', '127.0.0.1'),
'port' => env('DB2_PORT', '3306'),
'database' => env('DB2_DATABASE', 'laravel'),
'username' => env('DB2_USERNAME', 'root'),
'password' => env('DB2_PASSWORD', ''),
'unix_socket' => env('DB2_SOCKET', ''),
'charset' => env('DB2_CHARSET', 'utf8mb4'),
'collation' => env('DB2_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では、環境関数名は皆DB2_のプレフィックスとなっていることに注意を。
.envでは、こんな感じに設定します。
... DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=db1 DB_USERNAME=root DB_PASSWORD=password DB2_HOST=localhost DB2_PORT=3307 DB2_DATABASE=db2 DB2_USERNAME=root2 DB2_PASSWORD=password2 ...
第2のデータベースにアクセスするには
さて、第2のデータベースにアクセスしてみましょう。
クエリビルダーでは、以下のようにconnection()の引数に第2のデータベースのコネクション mysql2 を指定するだけです。
DB::connection('mysql2')->table('user')->get();
Eloquentではどうでしょう。
まず、第2のデータベースのモデルを作成します。
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class RemoteUser extends Model
{
protected $table = 'users';
protected $connection = 'mysql2'; // ここでコネクションを指定
}
ここでは、デフォルトのデータベースと同じように、第2のデータベースでも users というテーブルが存在すると仮定します。
通常と違って、mysql2のコネクションが指定されていることも注意を。
この設定なら、クエリの実行はデフォルトのデータベースのEloquetとまったく変わりません。簡単ですね。
RemoteUser::all();
Eloquentで動的にコネクションを指定
先のEloquentはモデル内ですでに指定されている固定のコネクションでしたが、前もってわからないときはどうしましょう。
つまりモデルの定義が以下のようなときのことです。
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class RemoteUser extends Model
{
protected $table = 'users';
}
このようなときは、クエリ実行時において、以下のようにコネクションを指定します。
RemoteUser::on('mysql2')->get();
上では、RemoteUser::on('mysql2')は、Illuminate\Database\Eloquent\Builderを返すので、RemoteUser::on('mysql2')::all()とは出来ないことに注意を。
