Doctrine2 实体的动态表名称

问题描述 投票:0回答:2

我正在尝试为我的一些实体添加动态表名称。

我读了这篇文章[学说2中的动态表/实体名称][1] [1]:Doctrine 2中的动态表/实体名称以及关于学说侦听器的[学说侦听器][2][2]:http://doctrine-orm.readthedocs.org/en/latest/reference/ events.html

所以这就是我尝试的方法:

我创建了一个表名中带有通配符的实体:

<?php

namespace DD\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * SiteElec
 *
 * @ORM\Table(name="site_x_elec")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\EntityListeners({"DD\MyBundle\Entity\Listener\SiteElecListener"})
 */
class SiteElec
{
    I skip properties with getters and setters

}

接下来我为这个实体做了一个监听器:

<?php

namespace DD\MyBundle\Entity\Listener;

use DD\UserBundle\Entit\User;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

/**
 * Listener pour l'entité siteElec.
 */
class SiteElecListener {


private $_tableName = null;
protected $token_storage;
protected $user;

public function getTableName() {
    return $this->_tableName;
}

public function setTableName($tableName) {
    $this->_tableName = $tableName;
    return $this;
}

public function __construct(TokenStorageInterface $token_storage) {

    $this->token_storage = $token_storage;

    if($token_storage->getToken() != null){

    }
}

/*
 * @ORM\LoadClassMetadata
 * @param LoadClassMetadataEventArgs $eventArgs
 */
public function loadClassMetadata(LoadClassMetadataEventArgs $args) {

    //$this->user = $this->token_storage->getToken();
    //var_dump($this->token_storage);

    $classMetadata = $args->getClassMetadata();
    $table = $classMetadata->table;
        var_dump($classMetadata);
//        $table['name'] = 'site_'.$this->user->getSite()->getId().'_elec';
//        $classMetadata->setPrimaryTable($table);
}

}

接下来我在配置文件中声明我的监听器:

    dd.entity_listener.site_elec:
    class:      DD\MyBundle\Entity\Listener\SiteElecListener
    arguments:  
        - "@security.token_storage"
    tags:
        - { name: doctrine.event_listener, event: loadClassMetadata }

如果我查看 $classMetadata var 我只有我的用户实体和关联实体,但没有我的 SiteElec 实体

我一定是在某个地方做错了,但我不知道在哪里。

有什么想法吗? 谢谢

php mysql symfony doctrine-orm
2个回答
12
投票

您可以通过这种方式为 Doctrine 2 中的某些实体使用动态表名称

1)在实体中设置Table(name =“NULL”)

<?php

namespace DD\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * SiteElec
 *
 * @Table(name="NULL")
 * @ORM\Entity
 */
class SiteElec { ... }

2)然后在使用实体之前设置表名

$EM
  ->getClassMetadata('DD\MyBundle\Entity\SiteElec')
  ->setTableName($DYNAMIC_TABLE_NAME);

3)照常使用具有动态表名的实体

$result = $EM
  ->getRepository('DD\MyBundle\Entity\SiteElec')
  ->findBy(['id' => $SOME_ID]);

0
投票

如果您使用 Symfony,请删除

config/packages/doctrine.yaml 中的键 
[email protected]_cache_driver
[email protected]_cache_pool

when@prod:
    doctrine:
        orm:
            auto_generate_proxy_classes: false
            proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
-            query_cache_driver:
-                type: pool
-                pool: doctrine.system_cache_pool
            result_cache_driver:
                type: pool
                pool: doctrine.result_cache_pool

    framework:
        cache:
            pools:
                doctrine.result_cache_pool:
                    adapter: cache.app
-                doctrine.system_cache_pool:
-                    adapter: cache.system

但这仍然允许它在 Symfony\Component\Cache\Adapter\ArrayAdapter

 环境下回退到 
dev
,即使它已经配置为 
null
:

php bin/console debug:config doctrine | grep -A 1 query
                query_cache_driver:
                    type: null

由于https://github.com/doctrine/orm/blob/e9f3ca2a45678e17f03cb46ab48dba0b59b4edac/src/ORMSetup.php#L100

所以我们仍然必须显式地将其缓存适配器设置为哑

Symfony/Component/Cache/Adapter/NullAdapter
如何在Symfony 5.2中禁用缓存?

        controller_resolver:
            auto_mapping: false
+        query_cache_driver:
+            type: service
+            id: cache.adapter.null
+
+services:
+    cache.adapter.null:
+        class: Symfony\Component\Cache\Adapter\NullAdapter
© www.soinside.com 2019 - 2024. All rights reserved.