Laravel Multiple Database Connection with Eloquent ORM, Query Builder, Migration & Stored Procedure


How to work with Multiple database connection in Laravel Eloquent ORM, Query Builder, Migration & Stored Procedure


Some time back I have received the following request from one of my follower on techalyst.com, 


for certain reasons I have two database which replicates automatically, first one is master database and second one is slave database, the default connection which is defined in my Laravel Project config/database.php file connect to master database, but some time i want to force Laravel Query Builder , EloquentModels or Schema Migration to connect to my slave database instead of what is originally defined in config/database.php? is this possible?


Yes definitely it is possible to connect Laravel with Multiple Database !,

Laravel makes it extremely simple to Configure Multiple Database Connection for Eloquent ORM, Query Builder and Migration Schema Builder. The database configuration for your application is located at Laravel Project Root Folder, config/database.php. In this file you may define Multiple database connection Configuration for your Laravel Application.

I will explain you this below in two steps,


Step 1: Define Multiple Database Connection

I assume he has two different MySQL Database since he didn't mention which platform is, but we can also connect other database platform which is supported by Laravel core such as SQL Server, Postgres or SQlite etc.. in the same way.

First go to the section where you define your database connection in config/database.php file, if you haven't already defined it, follow one of my earlier post on how to do it, Laravel Database Connection and Configuration.

In the database configuration file config/database.php - you will find a default MySQL databases configuration like the following:


<?php

return [

    'default' => env('DB_CONNECTION', 'mysql_master'),

    'connections' => [

        /* master database connection */

        'mysql' => [
            'driver'    => 'mysql_master',
            'host'      => env('DB_HOST', 'localhost'),
            'database'  => env('DB_DATABASE', 'master_db'),
            'username'  => env('DB_USERNAME', 'demo'),
            'password'  => env('DB_PASSWORD', 'demo'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ]

    ],

];


and if you have defined entries DB_HOST , DB_DATABASE , DB_USERNAME , DB_PASSWORD in your .env file,  Laravel will read from .env file or take the second value passed in the env() method,  and if you see the code well, your master connection is named as mysql_master and which is set as default connection by the line 'default' => env('DB_CONNECTION', 'mysql_master')

copy your entire default connection array and paste it right below and rename the connection to an appropriate name , 

here for demonstration purpose i named the second connection as mysql_slave , as shown below:

<?php

return [

    'default' => env('DB_CONNECTION', 'mysql_master'),

    'connections' => [

        'mysql_master' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST', 'localhost'),
            'database'  => env('DB_DATABASE', 'master_db'),
            'username'  => env('DB_USERNAME', 'demo'),
            'password'  => env('DB_PASSWORD', 'demo'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],
        'mysql_slave' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST_TWO', 'localhost'),
            'database'  => env('DB_DATABASE_TWO', 'slave_db'),
            'username'  => env('DB_USERNAME_TWO', 'demo_slave'),
            'password'  => env('DB_PASSWORD_TWO', 'demo_slave'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ]
    ],
];


if you look carefully, you should have noted , I have renamed .env keys to DB_HOST_TWODB_DATABASE_TWODB_USERNAME_TWO , DB_PASSWORD_TWO in env() method in the mysql_slave connection array. you must define those entries in your .env file in the Laravel Project Root Folder app/.env  or Laravel will use the default value being passed,

We have our default connection still set to mysql_master . This means that, unless we specify otherwise, Laravel Database connections will use the mysql_master connection.


Step 2: Specify Database Connection

in this step , i will show you how to use the connections with Eloquent Models, Query Builder and Migration Schema Builder,


Laravel Eloquent Models Specify Which Database Connection to use 

with Eloquent you can specify which database connection to use in two ways, 

Method 1:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $connection = 'mysql_slave';   
}

if we skip the protected $connection = 'mysql_slave';  Laravel will use the default connection mysql_master   

Method 2:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class YourController extends Controller {

    public function yourMethod(Request $request)
    {
        $userModel = new User();
        $userModel->setConnection('mysql_slave');
        $userModel = $userModel->where('id,'=',1)->get();
        return $userModel;
    }

}

if we skip the $userModel->setConnection('mysql_slave')  Laravel will use the default connection mysql_master   


Laravel Query Builder Specify Which Database Connection to use 

$userModel = DB::connection('mysql_slave')->table('users')->where('id,'=',1)->get();

if we skip the DB::connection()  Laravel will use the default connection mysql_master   


Laravel Migration Schema Builder Specify Which Database Connection to use 

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{  
    public function up()
    {
        Schema::connection('mysql_slave')->create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('username')->unique();
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    ...
}


Laravel Specify Which Database Connection to use while running Stored Procedure

we have to import the following namespaces in top of the controller file where this Stored Procedurebeing called

use Illuminate\Support\Facades\DB;
use Doctrine\DBAL\Driver\PDOConnection;

and then.

$db = DB::connection('mysql_slave')->getPdo();
$db->setAttribute(PDOConnection::ATTR_ERRMODE, PDOConnection::ERRMODE_EXCEPTION);
$db->setAttribute(PDOConnection::ATTR_EMULATE_PREPARES, true);

$queryResult = $db->prepare('call yourprocedurename(?,?)');
$queryResult->bindParam(1, $peram1);
$queryResult->bindParam(2, $$peram2);
$queryResult->execute();
$result_set = $queryResult->fetchAll(PDOConnection::FETCH_ASSOC);
$queryResult->closeCursor();

if we skip the DB::connection()  Laravel will use the default connection mysql_master   


if you have any questions regarding "Laravel Running Multiple Database Connection with Eloquent ORM, Query Builder, Migration and Stored Procedure", please feel free to leave your comment bellow.

Written by Akram Wahid 5 years ago

are you looking for a chief cook who can well craft laravel and vuejs, to make some awsome butterscotch,
yes then it is right time for you to look at my profile.

Do you want to write Response or Comment?

You must be a member of techalyst to proceed!

Continue with your Email ? Sign up / log in

Responses

Be the first one to write a response :(

{{ item.member.name }} - {{ item.created_at_human_readable }}

{{ reply.member.name }} - {{ reply.created_at_human_readable }}