Jak korzystać z wielu baz danych w Laravel


224

Chcę połączyć wiele baz danych w moim systemie. W większości przypadków bazą danych jest MySQL; ale może się to różnić w przyszłości, np. Administrator może generować takie raporty, które są źródłem heterogenicznego systemu baz danych.

Więc moje pytanie brzmi, czy Laravel zapewnia jakąkolwiek fasadę, aby poradzić sobie w takich sytuacjach? Czy jakikolwiek inny framework ma bardziej odpowiednie możliwości rozwiązywania problemów?

Odpowiedzi:


469

Używanie .env> = 5.0 (testowane na 5.5)

W .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database1
DB_USERNAME=root
DB_PASSWORD=secret

DB_CONNECTION_SECOND=mysql
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=database2
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=secret

W config/database.php

'mysql' => [
    'driver'    => env('DB_CONNECTION'),
    'host'      => env('DB_HOST'),
    'port'      => env('DB_PORT'),
    'database'  => env('DB_DATABASE'),
    'username'  => env('DB_USERNAME'),
    'password'  => env('DB_PASSWORD'),
],

'mysql2' => [
    'driver'    => env('DB_CONNECTION_SECOND'),
    'host'      => env('DB_HOST_SECOND'),
    'port'      => env('DB_PORT_SECOND'),
    'database'  => env('DB_DATABASE_SECOND'),
    'username'  => env('DB_USERNAME_SECOND'),
    'password'  => env('DB_PASSWORD_SECOND'),
],

Uwaga: W mysql2przypadku, gdy DB_username i DB_password są takie same, możesz użyć, env('DB_USERNAME')które jest wymienione w .envpierwszych kilku wierszach.

Bez .env<5,0

Zdefiniuj połączenia

app/config/database.php

return array(

    'default' => 'mysql',

    'connections' => array(

        # Primary/Default database connection
        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => '127.0.0.1',
            'database'  => 'database1',
            'username'  => 'root',
            'password'  => 'secret'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

        # Secondary database connection
        'mysql2' => array(
            'driver'    => 'mysql',
            'host'      => '127.0.0.1',
            'database'  => 'database2',
            'username'  => 'root',
            'password'  => 'secret'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),
);

Schemat

Aby określić, którego połączenia użyć, po prostu uruchom connection()metodę

Schema::connection('mysql2')->create('some_table', function($table)
{
    $table->increments('id'):
});

Kreator zapytań

$users = DB::connection('mysql2')->select(...);

Wymowny

Ustaw $connectionzmienną w swoim modelu

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

Możesz także zdefiniować połączenie w czasie wykonywania za pomocą setConnectionmetody lub onmetody statycznej:

class SomeController extends BaseController {

    public function someMethod()
    {
        $someModel = new SomeModel;

        $someModel->setConnection('mysql2'); // non-static method

        $something = $someModel->find(1);

        $something = SomeModel::on('mysql2')->find(1); // static method

        return $something;
    }

}

Uwaga Uważaj na próby zbudowania relacji z tabelami w różnych bazach danych! Jest to możliwe, ale może zawierać pewne zastrzeżenia i zależy od posiadanej bazy danych i / lub ustawień bazy danych.


Od Laravel Docs

Korzystanie z wielu połączeń z bazą danych

Korzystając z wielu połączeń, możesz uzyskać do nich dostęp connectionza pomocą metody połączenia na DBelewacji. namePrzekazany do connectionmetody powinny odpowiadać jednej z połączeń wymienionych w config/database.phppliku konfiguracyjnym:

$users = DB::connection('foo')->select(...);

Możesz również uzyskać dostęp do pierwotnej, podstawowej instancji PDO, używając metody getPdo w instancji połączenia:

$pdo = DB::connection()->getPdo();

Przydatne linki

  1. Połączenie wielu baz danych Laravel 5 z laracasts.com
  2. Połącz wiele baz danych w laravel FROM tutsnare.com
  3. Wiele połączeń DB w Laravel FROM fideloper.com

1
Możesz użyć, class SomeModel extends Model { a także upewnić się, że usunąłeś wartości get z pliku env, tak jak env('DB_DATABASE', 'name')podczas tworzenia nowej tablicy konfiguracji DB w pliku database.php, jak wspomniała
@sba

1
Hej, używam Lumen, a do konfiguracji bazy danych mam tylko plik „.env”. Nie database.php. Jak mogę to naprawić?
Chanaka De Silva

1
@ChanakaDeSilva Wystarczy utworzyć folder config i plik database.php dla Lumen. Najwyraźniej Lumen stale sprawdza, czy plik istnieje, i użyje go, jeśli tak się stanie.
Ecksters,

1
Dzięki bracie, myślę, że teraz biorę tę pracę; p
binar

1
@AbdullaNilam some1 przyszedł do mnie, aby najpierw zrobić aplikację multidb. Nie wiem, czy to możliwe, teraz wiem, że to proste; p
binar

12

W Laravel 5.1 określasz połączenie:

$users = DB::connection('foo')->select(...);

Domyślnie Laravel używa domyślnego połączenia. To proste, prawda?

Przeczytaj więcej tutaj: http://laravel.com/docs/5.1/database#accessing-connections


w Laravel 5.1, a co z Eloquentem?
simo

1
@simo, zobacz odpowiedź Abdulli.
schellingerht,

Napisałem pełny artykuł dla Sama, który możesz sprawdzić na <a href=" stackcoder.in/posts/… 7.x Wiele połączeń z bazą danych, migracje, relacje i
zapytania</a>

6

Właściwie to DB::connection('name')->select(..)nie działa dla mnie, ponieważ „nazwa” musi być w podwójnym cudzysłowie: „nazwa”

Mimo to wybrane zapytanie jest wykonywane na moim domyślnym połączeniu. Wciąż próbuję dowiedzieć się, jak przekonać Laravela, aby działał zgodnie z przeznaczeniem: zmień połączenie.

Edycja: Zrozumiałem. Po debugowaniu menedżera bazy danych Laravels okazało się, że moja baza danych.php (plik konfiguracyjny) (wewnątrz $ this-> app) była błędna. W sekcji „połączenia” miałem takie rzeczy jak „baza danych” z wartościami tego, z którego je skopiowałem. Mówiąc wprost, zamiast

env('DB_DATABASE', 'name')

Musiałem umieścić coś takiego

'myNewName'

ponieważ wszystkie połączenia zostały wymienione z tymi samymi wartościami dla bazy danych, nazwy użytkownika, hasła itp., co oczywiście nie ma sensu, jeśli chcę uzyskać dostęp do co najmniej innej nazwy bazy danych

Dlatego za każdym razem, gdy chciałem wybrać coś z innej bazy danych, zawsze kończyłem w mojej domyślnej bazie danych


1
Dziękuję Ci! Uratowałeś moje zdrowie psychiczne. Próbowałem dowiedzieć się, dlaczego wszystkie moje zapytania dotyczyły domyślnej bazy danych. Potem przeczytałem twój post i zdałem sobie sprawę, że env zawsze zwraca wartości .env, a drugi parametr był tylko rezerwą, której Laravel nie użył.
Moha

Off-topic: byłoby wspaniale, gdyby administratorzy nie manipulowali moimi postami. Lub przynajmniej napisz do mnie prywatną wiadomość, co i dlaczego chcą zmienić. Nie wymyśliłem, jak wysyłać prywatne wiadomości.
sba

Miałem podobny problem, zmieniłem wartość, ale nie klucz. Działa to tak: 'database' => env ('DB_NEW_DATABASE', 'myNewDatabase'). Zrozumiano!
Fellipe Sanches

0

Laravel ma wbudowaną obsługę wielu systemów baz danych, musisz podać szczegóły połączenia w pliku config / database.php

return [
    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [
        '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', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
'mysqlOne' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST_ONE', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_ONE', 'forge'),
            'username' => env('DB_USERNAME_ONE', 'forge'),
            'password' => env('DB_PASSWORD_ONE', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
];

Gdy to zrobisz, możesz utworzyć dwie klasy modelu podstawowego dla każdego połączenia i zdefiniować nazwę połączenia w tych modelach

//BaseModel.php
protected $connection = 'mysql';

//BaseModelOne.php
protected $connection = 'mysqlOne';

Możesz rozszerzyć te modele, aby utworzyć więcej modeli dla tabel w każdym DB.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.