Birden Çok Veritabanı Bağlantısını Kullanarak Laravel Nasıl Çalıştırılır

Son zamanlarda Laravel hakkında çoklu veritabanı bağlantısı kullanarak araştırma yapıyordum. Başka bir model farklı bir bağlantı kullanıyorsa Eloquent'in ilişkisini nasıl kullandığını veya başka bir tablo başka bir veritabanındaysa, sorgu oluşturucunun nasıl bir araya getirileceğini merak ediyordum.

Hadi başlayalım.

TL; DR

Bir sürü hikaye okumayı sevmiyor musun? Sadece koda atla:

Laravel'i yükleyin

Laravel'i kurmak kolaydır, sadece internet bağlantınız olduğundan ve makinenizin Laravel'i kurmak için minimum gereksinimleri olduğundan emin olun.

İlerleme tamamlanana kadar bekleyin ve veritabanımızı kurmaya hazırız.

Veri Tabanı Hazırlama ve Yapılandırma

Araştırma için MySQL ve SQL Server kullanarak 3 farklı veritabanı ve 2 farklı veritabanı motoru kullanacağım.

  1. laramultidb veritabanı adı mysql olan MySQL motor kullanıyor.
  2. laramultidb2 veritabanı ismi ile mysql2 MySQL motoru kullanıyor.
  3. laravelmultidb veritabanı adı sqlsrv olan SQL Server Engine kullanıyor.

SQL Server'ınız yoksa, PostgreSQL veya Sqlite gibi başka bir veritabanı motorunu kullanabilirsiniz.

Yeni veritabanı bağlantısı yapılandırması oluşturmak için config / database.php adresine gidin. Bu durumda, bu benim kurulumum

'bağlantılar' => [

    'sqlite' => [
        'sürücü' => 'sqlite'
        'database' => env ('DB_DATABASE', database_path ('database.sqlite')),
        'önek' => ''
    ],

    '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', ''),
        'unix_socket' => env ('DB_SOCKET', ''),
        'charset' => 'utf8mb4'
        'harmanlama' => 'utf8mb4_unicode_ci'
        'önek' => ''
        'strict' => doğru,
        'motor' => boş
    ],

    'mysql2' => [
        'driver' => 'mysql'
        'host' => env ('DB_HOST', '127.0.0.1'),
        'port' => env ('DB_PORT', '3306'),
        'database' => env ('DB_DATABASE2', 'forge'),
        'username' => env ('DB_USERNAME', 'forge'),
        'password' => env ('DB_PASSWORD', ''),
        'unix_socket' => env ('DB_SOCKET', ''),
        'charset' => 'utf8mb4'
        'harmanlama' => 'utf8mb4_unicode_ci'
        'önek' => ''
        'strict' => doğru,
        'motor' => boş
    ],
    'sqlsrv' => [
        'sürücü' => 'sqlsrv'
        'host' => env ('DB_HOST_SQLSRV', 'localhost'),
        'port' => env ('DB_PORT_SQLSRV', '1433'),
        'database' => env ('DB_DATABASE_SQLSRV', 'forge'),
        'username' => env ('DB_USERNAME_SQLSRV', 'forge'),
        'password' => env ('DB_PASSWORD_SQLSRV', ''),
        'charset' => 'utf8'
        'önek' => ''
    ],

],

Mysql2 aynı veritabanı motorunu ve mysql ile aynı ana bilgisayarı kullandığından, farklı mysql konfigürasyonunun DB_DATABASE2 haricinde mysql bağlantısı ile aynı olmasına izin vereceğim çünkü farklı veritabanı adı kullandım.

Ardından sqlsrv yapılandırması için env parametrelerini yeni anahtar kullanarak ayarlamam gerekiyor, böylece daha sonra .env dosyamdaki SQL Server kimlik bilgilerimi doldurabilirim.

Veritabanı bağlantısı hazır, şimdi veritabanı bölümünde .env dosyasını değiştirin.

DB_CONNECTION = mysql
DB_HOST = 127.0.0.1
DB_PORT = 3306
DB_DATABASE = laramultidb
DB_USERNAME = kullaniciadiniz
DB_PASSWORD = sırrı

DB_DATABASE2 = laramultidb2

DB_HOST_SQLSRV = 127.0.0.1
DB_PORT_SQLSRV = 1433
DB_DATABASE_SQLSRV = laravelmultidb
DB_USERNAME_SQLSRV sa =
DB_PASSWORD_SQLSRV = sırrı

.Env dosyamda, DB_CONNECTION = mysql varsayılan bağlantıdır.

Göç ve Model

İstediğimiz bağlantıya dayanarak tam olarak nasıl geçiş oluştururuz? Basit, Şema üzerinde bağlantı adını tanımlayın. Varsayılan olmayan veritabanı bağlantısını kullanan geçişlerime bir göz atalım:

/ **
 * Göçleri çalıştırın.
 *
 * @return void
 * /
genel işlev up ()
{
    Şema :: bağlantı ('mysql2') -> create ('types', function (Blueprint $ tablosu) {
        $ Tablo-> artışlarla ( 'id');
        $ Tablo-> string ( 'kod') -> endeksi ();
        $ Tablo-> string ( 'name');
        $ Tablo-> damgaları ();
    });
}

/ **
 * Göçleri ters çevirin.
 *
 * @return void
 * /
genel işlev aşağı ()
{
    Şema :: bağlantısı ( 'mysql2') -> damla ( 'türleri');
}

Yukarıdaki durumda, geçişi çalıştırdığımızda, type tablosu laravmultidb2'yi veritabanı adı olarak kullanan mysql2 bağlantısına geçirilecektir. Belirtilen bağlantı adını tanımlamazsak, laravel varsayılan bağlantıyı kullanır.

Model olarak Eloquent'i nasıl? Varsayılan bağlantıyı geçersiz kılmak için basitçe Eloquent Modelinizde bağlantı adını tanımlayın.

İlişki Çoklu Veritabanları

Artık Eloquent modelinde bağlantıyı tanımlayabildiğimizi zaten biliyoruz. Eloquent'in büyüsü, farklı bağlantıya sahip model arasındaki ilişkileri yazabilmemizdir.

Farklı bağlantıya sahip üç model yazdım:

Tür (bağlantı: mysql2) birçok yazıya sahiptir (bağlantı: mysql)

Tür (bağlantı: mysql2) birçok postaya sahiptir (bağlantı: sqlsrv)

Lütfen dikkat, her model farklı bağlantı kullanıyor olsa da, yabancı anahtar sütundaki verilerinizin ana anahtar veya model ilişkisinin işe yaramayacağına eşit olduğundan emin olun.

Tip modelimize bir örnek:

 hasMany (Post :: sınıf, 'type_code', 'kod');
    }

    / **
     * Mail ile bir çok ilişki (sqlsrv bağlantısı)
     * @return \ Illuminate \ Database \ Eloquent \ Relations \ HasMany
     * /
    ortak işlev postaları ()
    {
        $ $ this-> hasMany döndürün (Mail :: class, 'type_code', 'code');
    }
}

O zaman bu Post modeliyle kod benzerliğine sahip Mail modelimiz:

 belongsTo (Type :: class, 'type_code', 'kod');
    }
}

Şimdi, zaten verilerimizi tablolara sığdırdığımızdan beri, ilişkimizi Tinker kullanarak test edebiliriz.

Tinker kullanarak çoklu bağlantı ilişkisini kontrol et

Şimdi mysql2 bağlantısına bağlanan Tip modelini görüyoruz, mysql ile bağlanan, sqlsrv ile bağlanan Mail ile ilişki kurabiliyoruz.

Aynı kural aidiyet ilişkisine ait olduğu zaman da birden fazla bağlantı ile çalışıyor.

aitleşme yöntemini kullanarak çoklu bağlantı

Operasyona Katılın

Birleştirme sorgusu da birden fazla veritabanı bağlantısını desteklemektedir, ancak diğer tablolar için veritabanı adını tanımlamamız gerekir. Tinker'i açın ve Post andType'tan katılan Eloquent modelini kullanarak sorguyu çalıştırmayı deneyin.

sorguyu birleştir ile birleştir

Ancak, tür tablosu için veritabanı adı belirtmezsek, hata oluştu:

hata tablosu bulunamadı

Eloquent Modelini kullanmak yerine, Query Builder ayrıca join işlemini de çalıştırabilir.

sorgu oluşturucuyu kullanarak katıl

Veya sorgu oluşturucudan bağlantıyı belirleyebiliriz:

sorgu oluşturucu belirtilen bağlantı adıyla birleştir

Daha sonra birleştirme sorgusunu sqlsrv bağlantısı olan (SQL Server) ve mysql2 bağlantısı olan (MySQL) olan Mail adresinden kontrol etmek istiyoruz.

Hata! Farklı bir veritabanı motorunda birleştirme sorgusunu çalıştıramıyoruz gibi görünüyor. Veritabanını hala aynı motorda barındırıldığından tablo yazmak için birleştirme tablosundan join çalıştırabiliriz. Temelde aynı bağlantıya sahipler ancak sadece veritabanı adlarında farklılar.

Sonuç

  1. Laravel, farklı veritabanı motorlarında bile çoklu veritabanı bağlantısında çalışabiliyor.
  2. Daha önce yaptığımız bağlantıya dayanarak göç oluşturabiliriz.
  3. İkili ORM, farklı bağlantılarla ilişki yürütme yeteneğine sahiptir, ancak hangi bağlantının model tarafından kullanıldığını tanımlamak için bağlantı özelliğini geçersiz kılmamız gerekir.
  4. Sorgu Oluşturucu, farklı bir bağlantıda birleştirme sorgusudur, ancak aynı ana bilgisayar / veritabanı motoruyla sınırlıdır. Henüz farklı bir veritabanı motoruna nasıl katılacağımı bulamadım.
  5. Gerçek durumda, Eloquent'in farklı veritabanı motoruyla ilişkisini desteklemesine rağmen, sorunun ortaya çıkabileceğini düşünüyorum, çünkü veritabanı altyapısı arasında sorgu çalıştırırken bazı farklı yaklaşımlar var.
  6. Bu konuyu github'daki basit bir proje ile tamamladım. İhtiyacınız olanı klonlamak veya değiştirmek için çekinmeyin.

Referanslar

Mutlu kodlama millet :)