Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak połączyć się z różnymi bazami danych w czasie wykonywania?

Natknąłem się na to pytanie i miał moją odpowiedź.

Utworzyłem klasę o nazwie DatabaseConnection :

class DatabaseConnection extends Model
{

        static $instances=array();

        protected $database;

        protected $connection;

        public function __construct($options = null)
        {
            // Set the database
            $database = $options['database'];
            $this->database = $database;

            // Figure out the driver and get the default configuration for the driver
            $driver  = isset($options['driver']) ? $options['driver'] : Config::get("database.default");
            $default = Config::get("database.connections.$driver");

            // Loop through our default array and update options if we have non-defaults
            foreach($default as $item => $value)
            {
                $default[$item] = isset($options[$item]) ? $options[$item] : $default[$item];
            }

            $capsule = new Capsule;
            $capsule->addConnection($default);
            $capsule->setEventDispatcher(new Dispatcher(new Container));
            $capsule->setAsGlobal();
            $capsule->bootEloquent();

            // Create the connection
            $this->connection = $capsule->getConnection();

            DatabaseConnection::$instances[] = $capsule;
            return $this->connection;
        }
}

Tak więc, ilekroć jestem w kontrolerze, który manipuluje tabelami podbazy danych, po prostu idę w ten sposób:

public function RandomActionInMyController()
{
      $db_connection = new DatabaseConnection(['database' => 'name_of_db']);
       $someModel = new Model/Model::find()..// Basically anything
        return myreturnstuff;
}

Dodatkowy bonus :

Użycie statycznego atrybutu $instances w moim DatabaseConnection sprowadza się do odzyskania mojego najnowszego połączenia z bazą danych w celu ułatwienia użytkowania.

Na przykład, gdybym kiedykolwiek chciał go pobrać, zostałby opakowany w funkcję taką jak

function CurrentOrLatestDbConnection()
{
    if( !empty(DatabaseConnection::$instances) )
    {
        return end(DatabaseConnection::$instances)->getConnection()->getDatabaseName();
    }
}

Notatki :

Jeśli napotkasz błędy, takie jak Unknown class 'Container' lub Capsule lub cokolwiek w tym rodzaju, sprawdź podany przeze mnie link do pytania i użyj use oświadczenia prawidłowo.

Dotyczące nadchodzących odpowiedzi :

Wydaje mi się, że to połączenie z bazą danych znajduje się w nawiasach akcji kontrolera, więc kiedy przechodzę do innej akcji, która nie określa żadnego połączenia, automatycznie powraca ono do centralnej bazy danych.

Co sprawiło, że pomyślałem, że musi istnieć sposób na ustawienie połączenia bazy danych z podbazą danych w sposób „globalny” dla całej funkcji, takiej jak oprogramowanie pośredniczące lub coś takiego.

Chciałbym zobaczyć odpowiedź, wdrażając takie rzeczy.

Aktualizacja :

Wymyśliłem ładniejszy sposób na zrobienie tego.

Zakładam, że jesteś na tym samym gruncie co ja, chcąc zmienić bazy danych warunkowo zgodnie z każdym kontrolerem... powiedzmy, każdy z twoich kontrolerów wymaga innej bazy danych, tylko ze względu na argument.

To, czego użyjemy do rozwiązania tego problemu, to oprogramowanie pośrednie.

Po pierwsze, aby wyjaśnić, co zamierzamy zrobić...

Sprawdzimy nazwę kontrolera (a nawet akcję), a następnie ustawimy odpowiednią bazę danych, którą chcemy ustawić.

  1. Przejdź do wiersza poleceń , wpisz:

    php artisan make:middleware SetDatabaseConnectionMiddleware

Aby stworzyć oprogramowanie pośrednie z gotowym boilerplate’em.

Lub, jeśli podoba Ci się to w trudny sposób, przejdź do swojej app_name/app/Http/Middleware i utwórz je ręcznie.

  1. Przejdź do pliku metod pomocniczych (jeśli już masz, jeśli nie, zrób to!)

    Funkcja
     function getControllerAndActionName()
    {
    
    $action = app('request')->route()->getAction();
    
    $controller = class_basename($action['controller']);
    
    list($controller, $action) = explode('@', $controller);
    
    return ['action' => $action, 'controller' => $controller];
    }
    

Spowoduje to zwrócenie tablicy z nazwą akcji i nazwą kontrolera, jeśli chcesz zwracać tylko nazwę kontrolera, możesz usunąć 'action' => $action z kodu.

  1. Wewnątrz oprogramowania pośredniczącego będzie to wyglądać tak:

Przestrzeń nazw
    namespace App\Http\Middleware;

    use Closure;
    use DatabaseConnection;

    class SetProperDatabase
    {
    /**
    * Handle an incoming request.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @return mixed
    */
    public function handle($request, Closure $next)
    {
         $database_name = '';
         $controllerAndActionName = getControllerAndActionName();
         $controller_name = $controllerAndActionName['controller'];
         $action_name = $controllerAndActionName['action'];
         if($controller_name == 'my_controller_nameController')
         {

         $database_name = 'your_proper_database_name';
         }
         else
         {
          $database_name = 'other_db';
         }

         $database_connection = new DatabaseConnection(['database' => $database_name']);

          return $next($request);
    }
    }

4. Teraz, gdy poprawnie utworzyłeś oprogramowanie pośredniczące, pozwól nam powiedzieć Twojej aplikacji, gdzie je znaleźć i pod jaką nazwą.

  1. Przejdź do aplikacji nazwa_aplikacji/app/Http/Kernel.php
  2. W swoim $routeMiddleware zmienna, dodaj tę linię

    'set_proper_database' => \App\Http\Middleware\SetProperDatabase::class,

W ten sposób wiemy, jak to nazwać.

  1. Na koniec konfiguracja.

    1. Przejdź do swojego Controller.php (klasa Abstract, z której dziedziczą wszystkie kontrolery)

    public function __construct() { $this->middleware('set_proper_database'); }

I to powinno zrobić to za ciebie.

Jeśli masz dodatkowe pytania, możesz je skomentować.

// Zasoby :

1.Nazwa kontrolera i akcji

2.Dokumentacja oprogramowania pośredniego

3.Dalsza dokumentacja oprogramowania pośredniego Notatki :Byłbym wdzięczny za wydanie niektórych zmian dotyczących mojego stylu i wcięć kodu, ponieważ wygląda na to, że miałem problemy z właściwym stylem kodu tutaj, ale na próżno, wcięcia, których użyłem, nie zadziałały.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. zaktualizuj unikalną indeksowaną kolumnę w mysql

  2. Wiele możliwości dla LINII ZAKOŃCZONYCH PRZEZ i PÓL ZAKOŃCZONYCH PRZEZ - MySQL

  3. Zapytanie MySQL Update — czy warunek „gdzie” będzie przestrzegany w przypadku wyścigu i blokowania wierszy? (php, PDO, MySQL, InnoDB)

  4. Zamówienie i limit LEFT JOIN

  5. Jeden element quizu na stronę (program quizu php/mysql)