如何在CakePHP中为一个模型dynamic使用多个数据库
好的,我的第一个问题被修改了很多次,我select删除它并重新expression我的问题。 我用不同的模型名称做了一个小型的testing用例项目,为我的问题find了一个合适的解决scheme。
警告 :不要将数据库与表格混合在一起
动机 :我将用户数据分成多个数据库,以查找法律和性能问题。
目前,我正在开发一个拥有多个User
的CakePHP项目,每个User
都有自己的带有多个表的数据库 ( cars
是其中的一个表 )。 现在,我需要先解释一下:
每个User
有他自己的数据库 (不是一个表,一个数据库 ),所以数据库名称如下。
- [DATABASE]
app
(这是应用程序的主数据库)- [TABLE]
users
- [TABLE]
permissions
( 与此问题无关 )
- [TABLE]
- [DATABASE]
app_user1
(User.id
1拥有整个数据库 )- [TABLE]
cars
(一个由User.id
1完全拥有的表 )
- [TABLE]
- [DATABASE]
app_user2
(User.id
2拥有整个数据库 )- [TABLE]
cars
(一个由User.id
2完全拥有的表 )
- [TABLE]
- 等等…
我做了一个小图,可以澄清数据库 / 表的定义及其与模型的关系:
问题!!!
直到User
login,我不知道要连接哪个数据库 。 User
和他们的数据库是dynamic创build的,所以我不能使用app/Config/database.php
。
所以我目前正在编写Model
和ConnectionManager
类的扩展来绕过CakePHP的基本数据库行为。 所以Car
模型知道使用哪个数据库 。 但我只是有一种感觉,这可以做得更容易!
所以我想这一切都归结为一个问题:
有没有更简单的方法来做到这一点?
感谢任何会花时间和精力阅读和理解我的问题!
这位先生 ( 奥利维尔 )也有同样的问题! (一年前) 他为Controller
写了一个小改编! 这是相当小的,事实certificate,它在1.3和2.x工作 。
无论如何,这是我最后的解决scheme,我把它放在app/Model/AppModel.php
:
class AppModel extends Model { /** * Connects to specified database * * @param String name of different database to connect with. * @param String name of existing datasource * @return boolean true on success, false on failure * @access public */ public function setDatabase($database, $datasource = 'default') { $nds = $datasource . '_' . $database; $db = &ConnectionManager::getDataSource($datasource); $db->setConfig(array( 'name' => $nds, 'database' => $database, 'persistent' => false )); if ( $ds = ConnectionManager::create($nds, $db->config) ) { $this->useDbConfig = $nds; $this->cacheQueries = false; return true; } return false; } }
下面是我在app/Controller/CarsController.php
:
class CarsController extends AppController { public function index() { $this->Car->setDatabase('cake_sandbox_client3'); $cars = $this->Car->find('all'); $this->set('cars', $cars); } }
我打赌,我不是这个问题的第一个或最后一个。 所以我真的希望这些信息能够find人们和CakePHP社区。
我不喜欢在代码中写下数据库的实际名称的想法。 对于多个数据库,您有database.php文件,您可以根据需要设置多个数据库。
如果你想在一个特定的模型上 “切换”数据库,使用setDataSource方法。 (见这里 )
例如,如果您有两个数据库,那么可以在database.php文件中将它们定义为“default”和“sandbox”作为示例。
然后,在你的代码中:
$this->Car->setDataSource('sandbox');
沙盒是configuration的名称,数据库的实际名称只在database.php文件中写入一次。
您可以随时在MySQL中使用完整符号来查询任何数据库。 F.ex:
SELECT * FROM my_schema_name.table_name;
蛋糕方式:
$db = $this->getDataSource(); $query = array( 'fields' => array('*'), 'table' => 'my_schema_name.table_name' ); $stmt = $db->buildStatement($query, $this); $result = $db->execute($stmt);
在你的database.php
public $mongo = array( 'datasource' => 'Mongodb.MongodbSource', 'database' => 'database_name_mongo', 'host' => 'localhost', 'port' => 27017, );
在你的控制器中,你可以使用
$this->Organisation->setDataSource('mongo');
然后应用查询
this->Organisation->find('all');