たいていのプロジェクトで扱うデータベースは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()とは出来ないことに注意を。

メルマガ購読の申し込みはこちらから。

By khino