民间,
我现在已经尝试克服这个问题超过10个小时了,我决定在疯狂之前寻求帮助。
我想要实现的是某种多租户,我为每个客户提供专用数据库,并根据请求的发布者加载具体数据库。例如。如果客户A发送请求,则加载数据库A,如果B发送请求,则加载数据库B.我们有数千个客户,因此在databse.php文件中预定义的所有配置都不是一个选项。
在一些特殊情况下,无论发行人是谁,都应加载相同的数据库。例如。如果请求是X,则始终加载数据库C.
我有以下架构: BaseModel扩展了Eloquent模型。 扩展BaseModel的应用程序模型。 一些与应用程序模型对话的库。
由于我的所有数据库请求都通过BaseModel,我认为最好的解决方案是在BaseModel的构造函数中插入切换到正确数据库的代码。 E.g:
class BaseModel extends \Eloquent {
public function __construct(array $attributes = array()) {
$currentConfigs = \Config::get('database.connections.customers');
$currentConfigs['database'] = 'db_A'; //this varies depending on the request
$currentConfigs['prefix'] = 'custName'; //this varies depending on the request
\Config::set('database.connections.customers', $currentConfigs);
parent::__construct($attributes);
}
我面临的问题是我似乎只能设置一次配置。换句话说,如果我在请求的整个生命周期中只需要数据库A或B,那么一切正常。但是,如果我需要切换到数据库C,这不起作用。 BaseModel继续在A或B中查找所需的表,即使我尝试显式加载C.看起来db设置是不可变的或类似的东西。
那就是说,我有几个问题:
动态加载不同数据库运行时的最佳方法是什么,记住一个请求可能需要查询多个数据库而不只是一个。
如何卸载或重置数据库连接,以便我设置一个新的?
Laravel中的哪种方法可以为我提供有关当前数据库连接的信息?我需要调试方法,但我完全不知道可能的方法。
任何帮助/提示都将不胜感激。
答案 0 :(得分:5)
问题是,Laravel使用配置建立连接,然后将其保存在内存中。如果要通过设置新的连接变量来执行此操作,则必须在进行更改后重新连接。 (另请注意,您可以使用令人敬畏的点符号直接设置配置)
\Config::set('database.connections.customers.database', 'db_A');
DB::reconnect('customers');
然而,在我看来,更好的方法是使用SQL来切换数据库
DB::unprepared('USE db_A');
要获取当前数据库名称,您也可以使用SQL
DB::select('SELECT DATABASE()')[0]->{"DATABASE()"} // DATABASE() might be something else if you're not using MySQL
使表前缀动态化的简单方法是在BaseModel构造函数中添加它
$this->setTable('custName'.$this->getTable());