如何动态地使用多个数据库在CakePHP的一个模型(How to use multiple data

2019-06-18 19:49发布

好吧,我的第一个问题是修改了很多次,我选择将其删除,并重新制定我的问题。 我做了不同的型号,名称的小测试案例的项目找到我的问题妥善解决。

警告 :不要将数据库混合起来

动机 :我分开用户数据转化为法律和性能问题多个数据库

目前我的工作具有多个一CakePHP的项目User的每个User都有它自己的多个数据库 cars是一个 )。 现在,我需要先解释一下:

每个User都有自己的数据库 (不是表, 数据库 ),所以数据库名称如下。

  • [数据库] app (这是应用程序的主数据库)
    • [表格] users
    • [表格] permissions对这个问题不相关
  • [数据库] app_user1User.id 1拥有此整个数据库
    • [表格] cars (由完全拥有的 User.id 1)
  • [数据库] app_user2User.id 2拥有此整个数据库
    • [表格] cars (由完全拥有的 User.id 2)
  • 等等...

我做了一个小图画可能阐明数据库 / -定义和他们的模特的关系:

问题!!!

我不知道要连接的数据库 ,直到User登录时, User的和他们的数据库是动态创建的,所以我不能使用app/Config/database.php

所以,我目前正在写的一个扩展ModelConnectionManager类绕过CakePHP的基本数据库的行为。 因此, Car模型,知道使用哪个数据库 。 但我一直可以这样做更容易的感觉!

所以我想这一切都归结为一个问题:

是否有这样做的一个简单的方法?

由于任何人将采取谁的阅读和理解我的问题的时间和精力!

Answer 1:

这位先生 ( 奥利弗 )有同样的问题! (前一年), 他写了一个小的调整对于Controller小号! 这是非常小,事实证明,它工作在1.32.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的社区。



Answer 2:

我不喜欢写下来的代码数据库的实际名称的想法。 对于多个数据库,你有database.php中文件,其中,因为你需要,你可以设置多个数据库。

如果你想在飞行一个特定的模式来“开关”一个数据库,使用的setDataSource方法。 (见这里 )

例如,如果你有两个数据库,你可以在database.php中文件作为“默认”和“沙箱”中定义它们,作为一个例子。

然后,在你的代码:

$this->Car->setDataSource('sandbox');

沙箱是配置的名称,以及数据库的实际名称是在database.php中文件写入一次。



Answer 3:

您可以使用完整的符号在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);


Answer 4:

在您为database.php

public $mongo = array(
    'datasource' => 'Mongodb.MongodbSource',
    'database' => 'database_name_mongo',
    'host' => 'localhost',
    'port' => 27017,
);

在你的控制器,你可以使用

$this->Organisation->setDataSource('mongo');

然后应用查询像

this->Organisation->find('all');


Answer 5:

这是公认的答案的人。 这将防止错误,如果新的数据源已经存在:

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;
}


文章来源: How to use multiple databases dynamically for one model in CakePHP