好的,我的第一个问题被修改了很多次,我选择删除它并重新构建我的问题。我已经创建了一个具有不同模型名称的小型测试用例项目,以便为我的问题找到合适的解决方案。
警告:请勿将数据库与表格混合
动机:我将用户数据分为多个数据库以用于法律和表现问题。
目前我正在开发一个 CakePHP 项目,该项目有多个User
,每个User
都有自己的数据库,其中有多个< strong>表格(cars
是表格之一)。现在,我需要先解释一下:
每个User
都有自己的数据库(不是表格,数据库),因此数据库名称如下所示。
app
(这是应用的主数据库)
users
permissions
(与此问题无关)app_user1
(User.id
1拥有整个数据库)
cars
(表完全归User.id
所有)1)app_user2
(User.id
2拥有整个数据库)
cars
(表完全归User.id
所有} 2)我做了一个小图,可能会澄清数据库 / 表 - 定义及其与模型的关系:
问题!!!
我不知道连接到哪个数据库,直到User
登录。User
并且他们的数据库是动态创建的,所以我不能使用app/Config/database.php
。
所以我正在编写Model
和ConnectionManager
类的扩展,以绕过CakePHP的基本数据库行为。因此Car
模型知道要使用哪个数据库。但我只是觉得这可以更轻松!
所以我猜这一切归结为一个问题:
有更简单的方法吗?
感谢任何愿意花时间和精力阅读和理解我的问题的人!
答案 0 :(得分:37)
This gentleman(Olivier)遇到了同样的问题! (一年前)He wrote Controller
的一个小改编!它非常小,事实证明,它适用于 1.3 和 2.x 。
无论如何,这是我的最终解决方案,我放入了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);
}
}
我打赌,我不是第一个或最后一个有这个问题的人。所以我真的希望这些信息会找到人和他人。 CakePHP社区。 p>
答案 1 :(得分:9)
我不喜欢在代码中写下数据库的实际名称。 对于多个数据库,您有database.php文件,您可以根据需要设置任意数量的数据库。
如果要“动态”“切换”特定型号的数据库,请使用 setDataSource 方法。 (见here)
例如,如果您有两个数据库,则可以在database.php文件中将它们定义为“default”和“sandbox”,作为示例。
然后,在您的代码中:
$this->Car->setDataSource('sandbox');
沙箱是配置的名称,数据库的实际名称只在database.php文件中写入一次。
答案 2 :(得分:1)
您始终可以使用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);
答案 3 :(得分:1)
在您的database.php
中public $mongo = array(
'datasource' => 'Mongodb.MongodbSource',
'database' => 'database_name_mongo',
'host' => 'localhost',
'port' => 27017,
);
在您的控制器中,您可以使用
$this->Organisation->setDataSource('mongo');
然后应用像
这样的查询this->Organisation->find('all');
答案 4 :(得分:0)
这是一个被接受的答案的人。如果新数据源已经存在,这将防止错误:
public function setDatabase($database, $datasource = 'default')
{
$newDatasource = $datasource . '_' . $database;
try {
// return the new datasource if it's already existed
$db = ConnectionManager::getDataSource($newDatasource);
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
} catch (Exception $e) {
// debug($e->getMessage());
}
$db = ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $newDatasource,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($newDatasource, $db->config) ) {
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
}
return false;
}