Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да се свържа с различни бази данни по време на изпълнение?

Попаднах на този въпрос и имаше моя отговор.

Направих клас, наречен 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;
        }
}

Така че, когато съм в контролер, който манипулира таблици на подбаза данни, просто вървя по този начин:

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

Допълнителен бонус :

Използването на статичен атрибут $instances в моята DatabaseConnection се свежда до извличане на най-новата ми връзка с база данни за по-лесно използване.

Например, ако някога съм искал да го извлека, той ще бъде обвит във функция като

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

Бележки :

Ако срещнете грешки като Unknown class 'Container' или Capsule или нещо от този вид, уверете се, че сте проверили връзката към въпроса, която предоставих, и използвайте use изявления правилно.

Относно предстоящите отговори :

Струва ми се, че тази връзка към базата данни живее в скобите на действието на контролера, така че когато продължа към друго действие, което не посочва връзка, тя се връща автоматично към централната база данни.

Което ме накара да се замисля, че трябва да има начин да настроя връзката към базата данни към подбазата по „глобален“ начин към цялата функция, като междинен софтуер или нещо подобно.

Бих искал да видя отговор, внедряване на такова нещо.

Актуализиране :

Измислих по-чист начин да го направя.

Предполагам, че сте на същото основание като мен, като искате да промените базите данни условно в съответствие с всеки контролер... да речем, всеки от вашите контролери изисква различна база данни, само в името на аргумента.

Това, което ще използваме, за да решим това, е `Middlewares.

Първо, да обясним какво ще правим...

Ще проверим за името на контролера (и дори действието) и след това ще зададем правилната база данни, която искаме да зададем.

  1. Отидете на командния ред, въведете:

    php artisan make:middleware SetDatabaseConnectionMiddleware

За да създадете междинен софтуер с готов шаблон.

Или, ако ви харесва по трудния начин, отидете на вашето app_name/app/Http/Middleware и създайте ръчно.

  1. Отидете до вашия файл с помощни методи (ако вече имате такъв, ако не, пич, направете такъв!)

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

Това ще ви върне масив както с името на действието, така и с името на контролера, ако искате да върнете ограничено само името на контролера, не се колебайте да премахнете 'action' => $action от кода.

  1. Вътре във вашия междинен софтуер той ще изглежда по следния начин:

    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.Сега, след като сте създали правилно своя междинен софтуер, нека кажем на приложението ви къде да го намери и под какво име.

  1. Отидете на вашето app_name/app/Http/Kernel.php
  2. Във вашия $routeMiddleware променлива, добавете този ред

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

По този начин знаем как да го наречем.

  1. И накрая, настройването му.

    1. Отидете на вашия Controller.php (Абстрактният клас, от който наследяват всичките ви контролери)

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

И това трябва да го направи вместо вас.

Ако имате допълнителни въпроси, моля не се колебайте да коментирате.

// Ресурси :

1.Име на контролер и действие

2.Документация за междинен софтуер

3.Допълнителна документация за междинен софтуер Бележки :Бих оценявал някое издание относно стила и отстъпа на кода, тъй като изглежда, че се мъчих да стилизирам правилно кода си тук, но напразно, отстъпите, които използвах, нямаха ефект.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ScaleGrid DBaaS разширява MySQL хостинг услугите чрез AWS Cloud

  2. MySQL:Задаване на sql_mode за постоянно

  3. Как да проверите съществуването на данни от две колони в две различни таблици? MySQL

  4. Как да накарам категорията от първо ниво да се показва само веднъж?

  5. Проблем с MySQL за Visual Studio / Visual Studio 2017 Datasource Wizard. Препратка към обект не е зададена на екземпляр на обект