- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在制作一个 Multi-Tenancy 多数据库应用程序,它有一个中央数据库和许多子数据库。
该应用程序在中央数据库中创建一个组织实例,并为每个组织创建一个包含不同表的子数据库。
为了实现这一点,我制作了一个类 Setup
所有这些都包含在构造函数中,因此在调用 Setup::create
时,所有这些都可以正常运行。
大部分数据库配置和连接都是从这个tutorial中得到启发的.
为了测试我的逻辑是否符合要求,我通过以下方式与我的应用程序交互:
令我惊讶的是,这两种情况下的结果都不同,而且就连接到另一个数据库而言从来都不是我们想要的。
与 tinker 的互动:
在调用我的 Setup::create
并且输出告诉我一切正常后,我尝试自己检查我现在使用的是哪个数据库使用:
DB::connection()->getDatabaseName()
它输出我们刚刚为组织创建并连接到的子数据库名称,这是合乎逻辑的,并且是相应的。
但是,我尝试通过为它创建一个新配置然后使用我提供的 DB
方法连接到它来连接到另一个数据库,它不起作用,我仍然在 sub -我所在的数据库。
与浏览器交互:
这一次,将我的 Setup::create
正确包装在我的 Controller 代码中,我尝试再次测试所有内容,我还在我的布局中制作了一行以输出当前数据库:
<?php echo DB::connection()->getDatabaseName() ?>
起初,当我还在中央数据库时,它的名字出现了,但是在调用 Setup::create
之后,它切换到子数据库 -这是预期的- 但是,刷新一次后,我又进入了中央数据库 -这完全出乎意料-
那么,这里发生了什么?以及如何在需要时以我希望的方式连接到所有不同的数据库?
额外:
Testing in tinker, I have went to the point where I have commented out the migration code, and left the creation of the database and also the connection to it. To my suprise, it does not connect to the database. so I started thinking that the migration code has something to do with connecting to the database, or maybe tinker has different behaviors I completely ingore.
重要:
Model::create
而不是 DB::connection()->....
技术细节:
我在 Ubuntu 机器上使用 Laravel 5 和 mysql-server。
最佳答案
我偶然发现了这个 question它有我的答案。
我创建了一个名为 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;
}
}
所以,每当我在一个 Controller 中操作一个子数据库的表时,我只需这样做:
public function RandomActionInMyController()
{
$db_connection = new DatabaseConnection(['database' => 'name_of_db']);
$someModel = new Model/Model::find()..// Basically anything
return myreturnstuff;
}
额外奖励:
在我的 DatabaseConnection
中使用静态属性 $instances
归结为检索我最新的数据库连接以便于使用。
例如,如果我想检索它,它将被包装在一个函数中,例如
function CurrentOrLatestDbConnection()
{
if( !empty(DatabaseConnection::$instances) )
{
return end(DatabaseConnection::$instances)->getConnection()->getDatabaseName();
}
}
注释:
如果您遇到诸如 Unknown class 'Container'
或 Capsule
之类的错误,请务必检查我提供的问题链接,并使用 正确使用
语句。
关于即将到来的答案:
在我看来,这个数据库连接存在于 Controller 操作的括号内,所以当我继续执行另一个指定没有连接的操作时,它会自动返回到中央数据库。
这让我想到,必须有一种方法可以以“全局”方式将数据库连接设置为整个功能的子数据库,例如中间件或其他东西。
我很想看到一个答案,实现这样的事情。
更新:
我想出了一个更简洁的方法。
我假设您和我站在同一个立场上,想要根据每个 Controller 有条件地更改数据库...比如说,您的每个 Controller 都需要一个不同的数据库,只是为了争论。
我们将使用“中间件”来解决这个问题。
首先,解释一下我们要做什么..
我们将检查 Controller 的名称(甚至操作),然后设置我们希望设置的正确数据库。
转到您的命令行,输入:
php artisan make:middleware SetDatabaseConnectionMiddleware
创建带有现成样板的中间件。
或者,如果您喜欢困难的方式,请转到您的 app_name/app/Http/Middleware 并手动创建一个。
转到你的辅助方法文件(如果你已经有一个,如果没有,老兄自己做一个!)
function getControllerAndActionName()
{
$action = app('request')->route()->getAction();
$controller = class_basename($action['controller']);
list($controller, $action) = explode('@', $controller);
return ['action' => $action, 'controller' => $controller];
}
这将返回一个包含 Action 名称和 Controller 名称的数组,如果您只想返回 Controller 的名称,请随意删除 'action' => $action
代码。
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.现在,您已经正确地创建了您的中间件,让我们告诉您的应用在哪里可以找到它以及以什么名称找到它。
在您的 $routeMiddleware
变量中,添加此行
'set_proper_database' =>\App\Http\Middleware\SetProperDatabase::class,
这样我们就知道怎么调用了。
最后,进行设置。
Controller.php
(您所有 Controller 的继承自的抽象类)公共(public)函数 __construct()
{
$this->middleware('set_proper_database');
}
这应该可以为您完成。
如果您有任何其他问题,请随时发表评论。
//资源:
3。 Further Middleware Documentation注意事项 :我会很感激关于我的样式和代码缩进的一些版本,因为我似乎在这里努力正确设置我的代码样式但徒劳无功,我使用的缩进没有效果。
关于php - 如何在运行时连接到不同的数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31281669/
我有 table 像这样 -------------------------------------------- id size title priority
我的应用在不同的 Activity (4 个 Activity )中仅包含横幅广告。所以我的疑问是, 我可以对所有横幅广告使用一个广告单元 ID 吗? 或者 每个 Activity 使用不同的广告单元
我有任意(但统一)数字列表的任意列表。 (它们是 n 空间中 bin 的边界坐标,我想绘制其角,但这并不重要。)我想生成所有可能组合的列表。所以:[[1,2], [3,4],[5,6]] 产生 [[1
我刚刚在学校开始学习 Java,正在尝试自定义控件和图形。我目前正在研究图案锁,一开始一切都很好,但突然间它绘制不正确。我确实更改了一些代码,但是当我看到错误时,我立即将其更改回来(撤消,ftw),但
在获取 Distinct 的 Count 时,我在使用 Group By With Rollup 时遇到了一个小问题。 问题是 Rollup 摘要只是所有分组中 Distinct 值的总数,而不是所有
这不起作用: select count(distinct colA, colB) from mytable 我知道我可以通过双选来简单地解决这个问题。 select count(*) from (
这个问题在这里已经有了答案: JavaScript regex whitespace characters (5 个回答) 2年前关闭。 你能解释一下为什么我会得到 false比较 text ===
这个问题已经有答案了: 奥 git _a (56 个回答) 已关闭 9 年前。 我被要求用 Javascript 编写一个函数 sortByFoo 来正确响应此测试: // Does not cras
所以,我不得不说,SQL 是迄今为止我作为开发人员最薄弱的一面。也许我想要完成的事情很简单。我有这样的东西(这不是真正的模型,但为了使其易于理解而不浪费太多时间解释它,我想出了一个完全模仿我必须使用的
这个问题在这里已经有了答案: How does the "this" keyword work? (22 个回答) 3年前关闭。 简而言之:为什么在使用 Objects 时,直接调用的函数和通过引用传
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicate: what is the difference between (.) dot operator and (-
我真的不明白这里发生了什么但是: 当我这样做时: colorIndex += len - stopPos; for(int m = 0; m < len - stopPos; m++) { c
思考 MySQL 中的 Group By 函数的最佳方式是什么? 我正在编写一个 MySQL 查询,通过 ODBC 连接在 Excel 的数据透视表中提取数据,以便用户可以轻松访问数据。 例如,我有:
我想要的SQL是这样的: SELECT week_no, type, SELECT count(distinct user_id) FROM group WHERE pts > 0 FROM bas
商店表: +--+-------+--------+ |id|name |date | +--+-------+--------+ |1 |x |Ma
对于 chrome 和 ff,当涉及到可怕的 ie 时,这个脚本工作完美。有问题 function getY(oElement) { var curtop = 0; if (oElem
我现在无法提供代码,因为我目前正在脑海中研究这个想法并在互联网上四处乱逛。 我了解了进程间通信和使用共享内存在进程之间共享数据(特别是结构)。 但是,在对保存在不同 .c 文件中的程序使用 fork(
我想在用户集合中使用不同的功能。在 mongo shell 中,我可以像下面这样使用: db.users.distinct("name"); 其中名称是用于区分的集合字段。 同样我想要,在 C
List nastava_izvjestaj = new List(); var data_context = new DataEvidencijaDataContext();
我的 Rails 应用程序中有 Ransack 搜索和 Foundation,本地 css 渲染正常,而生产中的同一个应用程序有一个怪癖: 应用程序中的其他内容完全相同。 我在 Chrome 和 Sa
我是一名优秀的程序员,十分优秀!