こんばんは、ウチイダです。
この前お引き受けしたお仕事で、複数のDBサーバを利用する案件がありました。
- 全データを集積しているDB(マスタDB)から必要な内容を取得し、自前のDB(アプリDB)に保存
- アプリDBには、独自に算出して業務に用いるカラムがある
という感じに開発するもので、モデル自体を別のものとして扱う方がよさそうでした。
というわけで、モデルごとに、別のDBのテーブルと連携させるための設定を調べました。
それをメモしておきます。
ちなみに、利用したLaravelのバージョンは9です。
今後の新規プロジェクトで利用できると思います。
1. .envに接続情報を分けて記載する
.envに、二つのDBの接続情報を記載します。以下のような感じです。
※もちろん、値はすべて仮のものです。
# 自前のDB(アプリDB)接続設定
APP_DB_CONNECTION=app
APP_DB_HOST=app.example.com
APP_DB_PORT=3306
APP_DB_DATABASE=app
APP_DB_USERNAME=app_user
APP_DB_PASSWORD=password
# データを集積しているDB(マスタDB)の接続設定
MASTER_DB_CONNECTION=master
MASTER_DB_HOST=master.example.com
MASTER_DB_PORT=3306
MASTER_DATABASE=master
MASTER_DB_USERNAME=master_user
MASTER_DB_PASSWORD=password
2. LaravelのDB接続設定で、envに記載した内容を反映
config/database.php で、データベースの接続設定がまとめられています。
.envで指定した内容がLaravel内で利用できるように設定していきます。
設定項目が多いように見えますが、デフォルトで「mysql」 という名前の接続情報があるので、それをベースに一部を書き換えるだけなので、それほど難しくはありません。
/* 18行目あたり */
/* デフォルトの接続情報はappにする */
'default' => env('APP_DB_CONNECTION', 'app'),
/* connections の中で、.envに指定した内容を記入する */
'connections' = [
/* アプリDB用の接続設定 */
'app' => [
'driver' => 'mysql',
'url' => env('APP_DB_URL'),
'host' => env('APP_DB_HOST', '127.0.0.1'),
'port' => env('APP_DB_PORT', '3306'),
'database' => env('APP_DATABASE', ''),
'username' => env('APP_DB_USERNAME', ''),
'password' => env('APP_DB_PASSWORD', ''),
'unix_socket' => env('APP_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'),
]) : [],
],
/* マスタDB用の接続設定 */
'app' => [
'driver' => 'mysql',
'url' => env('MASTER_DB_URL'),
'host' => env('MASTER_DB_HOST', '127.0.0.1'),
'port' => env('MASTER_DB_PORT', '3306'),
'database' => env('MASTER_DATABASE', ''),
'username' => env('MASTER_DB_USERNAME', ''),
'password' => env('MASTER_DB_PASSWORD', ''),
'unix_socket' => env('MASTER_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'),
]) : [],
],
],
3. モデルファイルで、接続先のDBを指定する
次に、モデルファイルに$connection を追加し、利用する接続先の名称を指定します。
以下は、アプリDBのsamples テーブルを利用するモデルの例です。
<?php
namespace App\Models\App;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Sample extends Model
{
use HasFactory;
/* アプリDBへ接続する */
protected $connection = 'app';
}
4. モデルを使ってみる
これで準備は整いました。ためしに、コントローラから呼び出してみます。
<?php
namespace App\Http\Controllers;
use App\Models\App\Sample;
class ConnectionTestController extends Controller
{
public function test()
{
/* samples テーブルから1件データを取り出してみる */
dd(Sample::first());
}
}
ルーティング設定してブラウザからアクセスし、データが表示されたら成功です。
同じ要領で、マスタDB用のモデルも作成できます。
cinfig/connection.php に接続情報をまとめていることが理解できていれば、記述するコードの内容は想定してたより難しくありません。
フレームワークごとに設定の仕方はいろいろなので、このあたりは実際に案件を通じて経験したり、じっくりドキュメントなどを読んで理解を深めていくことが不可欠ですね。
おまけ:DB ファサードで接続先を指定する
上記の設定をした前提で、DB ファサードからマスタDBへ接続する場合は以下のようにします。
DB::connection('master')->table('sample')->first();
connection() メソッドを書かなければ、デフォルト設定しているapp が使われます。
以上です。あなたのお役に立てれば幸いです。