【问题标题】:Symfony 3 connection to multiple databasesSymfony 3 连接到多个数据库
【发布时间】:2018-04-29 01:22:21
【问题描述】:
dynamic:
driver:   %database_driver%
host:     %database_host%
port:     %database_port%
dbname:   %database name%
user:     %database_user%
password: %database_password%
charset:  UTF8

大家好

我想动态连接到多个数据库。我阅读了本教程http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html,它按照说明工作。

但我唯一的问题是直接从我的控制器更改 dbname 的值以连接到我的所有数据库。

我将在 24 小时内解决这个问题。如果你有想法我真的需要它

【问题讨论】:

  • 可以肯定的是,您有单独的数据库服务器,对吧?不仅仅是同一台服务器上的不同架构?
  • 我有一个主数据库,列出了公司的数据库,公司可以选择使用模型 A 或模型 B,数据库保存在本地
  • 与@Don'tPanic 相同,如果您可以发布完整的数据库.configuration
  • 我还没有实现,所以才求助
  • 主数据库中的数据库变量或始终相同?

标签: php database symfony doctrine


【解决方案1】:

您的代码示例仅显示一个连接。您必须定义数据库连接,例如 the documentation 中的示例:

简单的破解:不要使用实体管理器,而只是连接。

如果您想要一个简单的方法,请不要使用 EntityManager。如果您只想获取有关数据库的一些信息并且不想存储信息或使用实体,这可能是矫枉过正。然后,只需创建一个自定义连接并使用“vanilla”SQL:

$this->get('doctrine.dbal.connection_factory')->createConnection($params);

您的问题并未说明您期望有多少数据库。所以让我们描述两种可能性:少量(固定)数据库或动态连接。

多连接,简单方法

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_mysql
                host:     '%database_host%'
                port:     '%database_port%'
                dbname:   '%database_name%'
                user:     '%database_user%'
                password: '%database_password%'
                charset:  UTF8
            model_a:
                driver:   pdo_mysql
                host:     '%database_hosta%'
                port:     '%database_porta%'
                dbname:   '%database_namea%'
                user:     '%database_usera%'
                password: '%database_passworda%'
                charset:  UTF8
            model_b:
                driver:   pdo_mysql
                host:     '%database_hostb%'
                port:     '%database_portb%'
                dbname:   '%database_nameb%'
                user:     '%database_userb%'
                password: '%database_passwordb%'
                charset:  UTF8
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
            model_a:
                connection: model_a
            model_b:
                connection: model_b

默认情况下,将使用连接default。在您的控制器中,您可以切换到另一个连接:

$customerEm = $this->getDoctrine()->getManager('model_a');

当然,您可以动态选择您的经理:

//just an example, I don't know how you choose which database to use.
$managerName = $company->getModelName();
$em = $this->getDoctrine()->getManager($managerName);

动态创建EntityManager

DoctrineBundle 不支持动态值(除了第一个示例中的配置值)。你可以create your own EntityManager,如果你不想(或不能)定义多个连接,因为动态表名。

创建工厂并将其定义为服务:

class EntityManagerFactory
{
    public function createManager($dbname)
    {
        $isDevMode = false;
        $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
        // or if you prefer yaml or XML
        //$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
        //$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);

        $conn = [
            'driver' => 'pdo_mysql',
            'username' => 'foo',
            'password' => 'foo',
            'dbname' => $dbname
        ];

        // obtaining the entity manager
        return EntityManager::create($conn, $config);
    }
}

并在您的控制器中使用它:

public function controllerAction()
{
    $em = $this->get(EntityManagerFactory::class)->getManager('model-name');
}

【讨论】:

  • Stephane 谢谢,所以我使用第二种方案,如果我想使用为模型b提供的实体,用我刚刚创建的管理器,可以吗?
  • 我不确定我是否理解您的问题。第二种解决方案是什么意思?动态创建EntityManager?
  • 是的,我使用动态创建EntityManager。我想使用实体
  • 请提供一些关于您的系统的背景信息。你所说的“实体”是什么意思?您是否有 1 个具有多个数据库的模型(表结构相同,只有数据不同)?还是基于 A 或 B 的两个模型(A 和 B)和我的数据库?
【解决方案2】:
/*
$connectionParams = array(
    'dbname' => 'mydb',
    'user' => 'user',
    'password' => 'secret',
    'host' => 'localhost',
    'driver' => 'pdo_mysql',
    );
*/
             
$connectionParams = array(
    'url' => 'mysql://user:secret@localhost/mydb',
    );
            
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多