> Symfony中文手册 > 如何处理多个实体管理器和连接

如何处理多个实体管理器和连接

你可以在一个symfony程序中使用多个Doctrine Entity Manager(实体管理器)和连接。 这是有必要的,如果你使用了不同的数据库,又或在vendors中使用了完全不同的entity的话。换句话说,一个连接到某个数据库的entity manager要处理一些entity,同时另外一个连接到其他数据库的entity manager会去处理其他的(entity)。

使用多个entity manager是非常容易的,但它很高级并且通常你不需要它。在添加这个复杂的层之前,你要确保真正需要多个entity manager。

以下配置代码展示了如何配置两个entity manager:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
            customer:
                driver:   pdo_mysql
                host:     "%database_host2%"
                port:     "%database_port2%"
                dbname:   "%database_name2%"
                user:     "%database_user2%"
                password: "%database_password2%"
                charset:  UTF8

    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                    AppBundle:  ~
                    AcmeStoreBundle: ~
            customer:
                connection: customer
                mappings:
                    AcmeCustomerBundle: ~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="Http://symfony.com/schema/dic/doctrine"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
                        http://symfony.com/schema/dic/doctrine http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">
 
    <config>
        <dbal default-connection="default">
            <connection name="default"
                driver="pdo_mysql"
                host="%database_host%"
                port="%database_port%"
                dbname="%database_name%"
                user="%database_user%"
                password="%database_password%"
                charset="UTF8"
            />
 
            <connection name="customer"
                driver="pdo_mysql"
                host="%database_host2%"
                port="%database_port2%"
                dbname="%database_name2%"
                user="%database_user2%"
                password="%database_password2%"
                charset="UTF8"
            />
        </dbal>
 
        <orm default-entity-manager="default">
            <entity-manager name="default" connection="default">
                <mapping name="AppBundle" />
                <mapping name="AcmeStoreBundle" />
            </entity-manager>
 
            <entity-manager name="customer" connection="customer">
                <mapping name="AcmeCustomerBundle" />
            </entity-manager>
        </orm>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$container->loadFromExtension('doctrine', array(
    'dbal' => array(
        'default_connection' => 'default',
        'connections' => array(
            'default' => array(
                'driver'   => 'pdo_mysql',
                'host'     => "%database_host%",
                'port'     => "%database_port%",
                'dbname'   => "%database_name%",
                'user'     => "%database_user%",
                'password' => "%database_password%",
                'charset'  => 'UTF8',
            ),
            'customer' => array(
                'driver'   => 'pdo_mysql',
                'host'     => "%database_host2%",
                'port'     => "%database_port2%",
                'dbname'   => "%database_name2%",
                'user'     => "%database_user2%",
                'password' => "%database_password2%",
                'charset'  => 'UTF8',
            ),
        ),
    ),
 
    'orm' => array(
        'default_entity_manager' => 'default',
        'entity_managers' => array(
            'default' => array(
                'connection' => 'default',
                'mappings'   => array(
                    'AppBundle'  => null,
                    'AcmeStoreBundle' => null,
                ),
            ),
            'customer' => array(
                'connection' => 'customer',
                'mappings'   => array(
                    'AcmeCustomerBundle' => null,
                ),
            ),
        ),
    ),
));

在这个例子中,你已经定义了两个entity manager,分别是 defaultcustomerdefault entity manager管理的是AppBundle 和 AcmeStoreBundle 中的实体,customer entity manager管理着 AcmeCustomerBundle 中的实体。你还定义了两个连接,每个entity manager都需要一个。

在使用多个连接和entity manager时,你应该清楚你想要的配置。如果你确实忽略了连接或entity manager的名称,默认的(即default)会被使用。

当使用多个连接来创建你的数据库时:

1
2
3
4
5
# Play only with "default" connection / 只操作default连接
$  php bin/console doctrine:database:create
 
# Play only with "customer" connection
$  php bin/console doctrine:database:create --connection=customer

当使用多个entity manager来更新的(数据表)schema时:

1
2
3
4
5
# Play only with "default" mappings / 只操作default映射
$  php bin/console doctrine:schema:update --force
 
# Play only with "customer" mappings / 只操custom映射
$  php bin/console doctrine:schema:update --force --em=customer

在请求它时,如果你 确实 省略了entity manager的名称,则会返回默认的entity manager(即default):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class UserController extends Controller
{
    public function indexAction()
    {
        // All three return the "default" entity manager
        // 全部三种都返回 "default" entity manager
        $em = $this->get('doctrine')->getManager();
        $em = $this->get('doctrine')->getManager('default');
        $em = $this->get('doctrine.orm.default_entity_manager');
 
        // Both of these return the "customer" entity manager
        // 两种都返回 "customer" entity manager
        $customerEm = $this->get('doctrine')->getManager('customer');
        $customerEm = $this->get('doctrine.orm.customer_entity_manager');
    }
}

现在你可以像往常那样使用 Doctrine 了 - 使用defaultentity manager来持久化和取出它所管理的实体,而 customer entity manager 也持久化和获取自己的实体。

同样适用于repository的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class UserController extends Controller
{
    public function indexAction()
    {
        // Retrieves a repository managed by the "default" em
        // 取出  "default" em 中的某个宝库
        $products = $this->get('doctrine')
            ->getRepository('AcmeStoreBundle:Product')
            ->findAll()
        ;
 
        // Explicit way to deal with the "default" em
        // 以显式的方式来处理 "default" em
        $products = $this->get('doctrine')
            ->getRepository('AcmeStoreBundle:Product', 'default')
            ->findAll()
        ;
 
        // Retrieves a repository managed by the "customer" em
        // 取出  "customer" em 中的某个宝库
        $customers = $this->get('doctrine')
            ->getRepository('AcmeCustomerBundle:Customer', 'customer')
            ->findAll()
        ;
    }
}