Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

laravel - Forcing Eloquent models to re resolve database connection

Is there any way to force Eloquent models to re resolve the connection they were instantiated with?

Right now I have a method that changes the database connection in a loop :

foreach ($array as $key => $value) {

   Config::set('database.connections.mysql.database', $key . '_' . $database);

   $productRepo = new ProductRepository();    

   $products = $productRepo->all();

}

Inside the product repository, i'm calling the Eloquent methods all() to get all the products in the database.

What i discover was that the connection was changed to the first value in the array but it does not change on further executions of the loop.

Is there anything I can do to force Eloquent to resolve the connection parameters at runtime?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Each database is really a separate connection, so I would setup all the connections to the database in the config/database.php file, and then you can use the setConnection() method on the model to switch between them.

database.php:

return [
    'default' => 'mysql-key1',
    'connections' => [
        'mysql-key1' => [
            'driver'    => 'mysql',
            'database'  => 'key1_dbname,
            // etc
        ],
        'mysql-key2' => [
            'driver'    => 'mysql',
            'database'  => 'key2_dbname',
            // etc
        ]
    ]
];

ProductRepository.php:

public function setConnection($name) {
    // assumes $this->product is your Product model
    $this->product->setConnection($name);
}

Code:

$productRepo = new ProductRepository();
foreach ($array as $key => $value) {
   $productRepo->setConnection($key . '_' . $database);
   $products = $productRepo->all();
}

Edit

additional information based on comments

Laravel is only going to instantiate a connection to the database the first time it is needed. Once the connection has been created, it is going to reuse it. It would be a huge performance issue if you had to reconnect to the database for every single query.

That being said, if you really want to do this the way you originally designed it, all you would need to do is call the DB::reconnect() method after updating the config.

foreach ($array as $key => $value) {
    Config::set('database.connections.mysql.database', $key . '_' . $database);
    DB::reconnect();

    $productRepo = new ProductRepository();
    $products = $productRepo->all();
}

However, I would strongly urge you to consider the originally described option so that you're not making a ton of unnecessary connections.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...