在 Doctrine2 中以编程方式修改表的模式名称? [英] Programmatically modify table's schema name in Doctrine2?

查看:14
本文介绍了在 Doctrine2 中以编程方式修改表的模式名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在运行时修改表的架构/数据库名称 对于表名是可能的,但是 ClassMetadataInfo 类似乎没有公开获取/设置此属性的接口.

I'd like to modify a table's schema/DB name at runtime as is possible with the table name, but the ClassMetadataInfo class does not appear to expose an interface to get/set this property.

如果绝对必要,我可以在运行时修改表名,但由于我们必须在单个架构/数据库中存储大量表,因此这不是理想的解决方案.

I can make do with modifying table names at runtime if absolutely necessary, but it is not an ideal solution due to the amount of tables we would then have to store in a single schema/DB.

有没有办法实现我想做的事?提前致谢.

Is there a way to achieve what I'd like to do? Thanks in advance.

注意:我需要能够在基于注释的实体映射中使用模式占位符提供完全限定的表名(例如 __schema_placeholder__.table_name,用于跨数据库连接).在运行时,我想从 __schema_placeholder__.table_name => real_schema_name.table_name 动态重新映射实体.

Note: I need to be able to provide a fully qualified table name using a schema placeholder in my annotation-based entity mapping (like __schema_placeholder__.table_name, for cross-database joins). At runtime I would then like to dynamically remap the entity from __schema_placeholder__.table_name => real_schema_name.table_name.

推荐答案

您可以通过挂接到 教义事件系统与听众/订阅者.

You can dynamically adjust the table names ( and mappings ) by hooking into the doctrine event-system with listeners/subscribers.

即"loadClassMetadata" 是 doctrine 的事件之一您可以按照食谱文章如何注册事件监听器和订阅者.

i.e. "loadClassMetadata" is one of doctrine's events you can create a listener/subscriber for as described in the cookbook article How to Register Event Listeners and Subscribers.

config.yml

services:
    mapping.listener:
        class: AcmeYourBundleEventListenerMappingListener
        tags:
            - { name: doctrine.event_listener, event: loadClassMetadata }

映射监听器

use DoctrineORMEventLoadClassMetadataEventArgs;

class MappingListener
{
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $classMetadata = $eventArgs->getClassMetadata();
        $table = $classMetadata->table;

        $oldName = $table['name'];      // ... or $classMetaData->getTableName()

        // your logic here ...

        $table['name'] = 'new_table_name';

        $classMetadata->setPrimaryTable($table);

        // ... or add a field-mapping like this

        $fieldMapping = array(
          'fieldName' => 'about',
          'type' => 'string',
           'length' => 255
        );
        $classMetadata->mapField($fieldMapping);

ClassMetadata 扩展了 ClassMetadataInfo 并提供一个公共变量 "table"(包含您的注解或 yml 提供的映射信息),您可以修改!

ClassMetadata extends ClassMetadataInfo and provides a public variable "table" ( containing the mapping information provided by your annotations or yml ) which you can modify !

公共表变量是一个包含以下条目的数组:

The public table variable is an array with the following entries:

  • 名称 =>
  • 架构 =>
  • 索引 => 数组
  • uniqueConstraints => 数组

您可以在保存/更新之前在控制器中动态注册事件监听器/订阅者.

You can dynamically register event-listeners/subscribers in your controller prior to saving/updating.

$mappingListener = new MappingListener();

// ... maybe even modify the listener using reflection

$evm = $this->get('doctrine')->getManager()->->getEventManager();
$evm->addEventListener('loadClassMetadata', $mappingListener);

<小时>

此外,您可以引入多个数据库连接/名称并在您的应用程序中访问它们.


Furthermore you can introduce multiple database connections/names and access them in your application.

app/config/config.yml

doctrine:
    dbal:
        default_connection:   default
        connections:
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            customer:
                driver:   "%database_driver2%"
                host:     "%database_host2%"
                port:     "%database_port2%"
                dbname:   "%database_name2%"
                user:     "%database_user2%"
                password: "%database_password2%"
                charset:  UTF8

然后使用...获取不同的实体管理器

Then get different entity managers using ...

  $em = $this->get('doctrine')->getManager('default');
  $em2 = $this->get('doctrine')->getManager('customer');

或存储库

$customers = $this->get('doctrine')
    ->getRepository('AcmeCustomerBundle:Customer', 'customer')
    ->findAll()
;

... 或 动态添加连接>

... or add connections dynamically

$this->get('doctrine')
  ->connection('mysql://username:password@localhost/test', 'dynamic_connection');

在说明书章节中阅读有关该主题的更多信息如何使用多个实体管理器和连接.

Read more about the topic in the cookbook chapter How to work with Multiple Entity Managers and Connections.

这篇关于在 Doctrine2 中以编程方式修改表的模式名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆