Как работать с множеством менеджеров сущностей и соединениями

Вы можете использовать множество менеджеров сущностей Doctrine или соединений в приложении Symfony. Это необходимо, если вы используете разные базы данных, или даже поставщиков с абсолютно разными наборами сущностей. Другими словами, один менеджер сущностей, который соединяется с одной базой данных, будет управлять некоторыми сущностями, в то время как другой менеджер сущностей, который соединяется с другой базой данных, может управлять всеми остальными.

Note

Использовать множество менеджеров сушностей достаточно просто, но это более продвинутый уровень, и обычно не требуется. Убедитесь в том, что вам на самм деле нужно множество менеджеров сушностей перед тем, как добавлять этот уровень сложности.

Caution

Сущности не могут определять ассоциации по разным менеджерам сущностей. Если вам нужно это, существует несколько альтернатив, которые требуют особенной установки.

Следующий код конфигурации показывает, как вы можете сконфигурироваь два менеджера сущностей:

... configuration-block:

  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
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
.. code-block:: yaml

    # config/packages/doctrine.yaml
    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:
                        Main:
                            is_bundle: false
                            type: annotation
                            dir: '%kernel.project_dir%/src/Entity/Main'
                            prefix: 'App\Entity\Main'
                            alias: Main
                customer:
                    connection: customer
                    mappings:
                        Customer:
                            is_bundle: false
                            type: annotation
                            dir: '%kernel.project_dir%/src/Entity/Customer'
                            prefix: 'App\Entity\Customer'
                            alias: Customer

.. code-block:: xml

    <!-- config/packages/doctrine.xml -->
    <?xml version="1.0" encoding="UTF-8"?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:doctrine="http://symfony.com/schema/dic/doctrine"
        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">

        <doctrine:config>
            <doctrine:dbal default-connection="default">
                <doctrine:connection name="default"
                    driver="pdo_mysql"
                    host="%database_host%"
                    port="%database_port%"
                    dbname="%database_name%"
                    user="%database_user%"
                    password="%database_password%"
                    charset="UTF8"
                />

                <doctrine:connection name="customer"
                    driver="pdo_mysql"
                    host="%database_host2%"
                    port="%database_port2%"
                    dbname="%database_name2%"
                    user="%database_user2%"
                    password="%database_password2%"
                    charset="UTF8"
                />
            </doctrine:dbal>

            <doctrine:orm default-entity-manager="default">
                <doctrine:entity-manager name="default" connection="default">
                    <doctrine:mapping
                        name="Main"
                        is_bundle="false"
                        type="annotation"
                        dir="%kernel.project_dir%/src/Entity/Main"
                        prefix="App\Entity\Main"
                        alias="Main"
                    />
                </doctrine:entity-manager>

                <doctrine:entity-manager name="customer" connection="customer">
                    <doctrine:mapping
                        name="Customer"
                        is_bundle="false"
                        type="annotation"
                        dir="%kernel.project_dir%/src/Entity/Customer"
                        prefix="App\Entity\Customer"
                        alias="Customer"
                    />
                </doctrine:entity-manager>
            </doctrine:orm>
        </doctrine:config>
    </container>

.. code-block:: php

    // config/packages/doctrine.php
    $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(
                        'Main'  => array(
                            is_bundle => false,
                            type => 'annotation',
                            dir => '%kernel.project_dir%/src/Entity/Main',
                            prefix => 'App\Entity\Main',
                            alias => 'Main',
                        )
                    ),
                ),
                'customer' => array(
                    'connection' => 'customer',
                    'mappings'   => array(
                        'Customer'  => array(
                            is_bundle => false,
                            type => 'annotation',
                            dir => '%kernel.project_dir%/src/Entity/Customer',
                            prefix => 'App\Entity\Customer',
                            alias => 'Customer',
                        )
                    ),
                ),
            ),
        ),
    ));

В этом случае, вы определили два менеджера сущностей и назвали их default и customer. Менеджер сущностей default управляет сущностями в каталоге src/Entity/Main, а менеджер сущностей customer - в src/Entity/Customer. Вы также определили два соединения, по одному для каждого менеджера.

Note

При работе со множественными соединениями и несколькими менеджерами сущностей, вы должны явно указывать, какую конфигурацию вы хотите. Если вы упустите имя соединения или менеджера сущностей, будет использовано имя по умолчанию (т.е. default).

При работе с множеством соединений, для создания ваших БД:

1
2
3
4
5
# Играть только с соединением "default"
$ php bin/console doctrine:database:create

# Играть только с соединением "customer"
$ php bin/console doctrine:database:create --connection=customer

При работе с множеством менеджеров сущностей для генерирования миграций.

1
2
3
4
5
6
7
# Играть только с отображениями "default"
$ php bin/console doctrine:migrations:diff
$ php bin/console doctrine:migrations:migrate

# Играть только с отображениями "customer"
$ php bin/console doctrine:migrations:diff --em=customer
$ php bin/console doctrine:migrations:migrate --em=customer

Если вы упустите имя менеджера сущностей при его запросе, будет возвращён менеджер сущностей по умолчанию (т.е. default):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// ...

use Doctrine\ORM\EntityManagerInterface;

class UserController extends Controller
{
    public function indexAction(EntityManagerInterface $em)
    {
        // Эти методы также возвращают менеджер сушностей по умолчанию, но предпочтительнее
        // получать его, внедряя EntityManagerInterface в метод раздела
        $em = $this->getDoctrine()->getManager();
        $em = $this->getDoctrine()->getManager('default');
        $em = $this->get('doctrine.orm.default_entity_manager');

        // Оба возвращают менеджер сущностей "customer"
        $customerEm = $this->getDoctrine()->getManager('customer');
        $customerEm = $this->get('doctrine.orm.customer_entity_manager');
    }
}

Теперь вы можете использовать Doctrine так же, как и раньше - путём использования менеджера сущностей default для сохранения и возврата сущностей, которыми он управляет, и менеджера сущностей customer для сохранения и возврате его сущностей.

То же самое применяется к вызовам хранилиша:

 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
use AcmeStoreBundle\Entity\Customer;
use AcmeStoreBundle\Entity\Product;
// ...

class UserController extends Controller
{
    public function indexAction()
    {
        // Извлекает хранилище, управляемое менеджером сущностей "default"
        $products = $this->getDoctrine()
            ->getRepository(Product::class)
            ->findAll()
        ;

        // Ясный способ разобраться с менеджером сущностей "default"
        $products = $this->getDoctrine()
            ->getRepository(Product::class, 'default')
            ->findAll()
        ;

        // Извлекает хранилище, управляемое менеджером сущностей "customer"
        $customers = $this->getDoctrine()
            ->getRepository(Customer::class, 'customer')
            ->findAll()
        ;
    }
}

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.