Как сгенерировать entities из существующей DB

Дата обновления перевода: 2022-01-09

Как сгенерировать entities из существующей DB

Когда вы начинаете работать над новым проектом, использующим базу данных, две разных ситуации всплывают естественным образом. В большинстве случаев, модель базы данных строится и планируется с нуля. Однако, иногда вы будете начинать с существующей и, вероятнее всего, не поддающейся изменениям, моделью DB. К счастью, Doctrine имеет массу инструментов, чтобы помочь сгенерировать классы модели из вашей существующей базы данных.

Note

Как гласит документация инструментов Doctrine, обратное проектирование (reverse engineering) - это единоразовый процесс, чтобы начать проект. Doctrine способен конвертировать приблизительно 70-80% необходимой информации отображения, основываясь на полях, индексах и ограничениях внешнего ключа. Doctrine не может обнаружить инверсные ассоциации, типы наследования, сушности с внешним ключом в качестве основного ключа или семантические операции над ассоциациями такие как cascade или события жизненного цикла. Некоторая дополнительная работа над созданными сущностями понадобится позже, чтобы подстроить каждую из них под спецификации вашей модели домена.

Этот туториал предполагает, что вы использете простое приложение-блог со следующими двумя таблицами: blog_post и blog_comment. Запись комментариев связана с записью постов блягодаря ограничению внешнего ключа.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `blog_post` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `content` longtext COLLATE utf8_unicode_ci NOT NULL,
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `blog_comment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `post_id` bigint(20) NOT NULL,
  `author` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `content` longtext COLLATE utf8_unicode_ci NOT NULL,
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `blog_comment_post_id_idx` (`post_id`),
  CONSTRAINT `blog_post_id` FOREIGN KEY (`post_id`) REFERENCES `blog_post` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Перед тем, как углубляться в инструкцию, убедитесь в том, что параметры соединения вашей DB правильно установлены в файле .env (или переопределяющем env.local).

Первым шагом на пути к построению классов entiry из существующей базы данных является попросить Doctrine вникнуть в DB и сгенерировать соответствующие файлы метаданных. Файлы метаданных описывают, какой класс сущности генерировать, основываясь на полях таблицы.

1
$ php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity

Этот инструмент командной строки просит Doctrine вникнуть в DB и сгенерировать новые PHP-классы с метаданными в аннотациях в папке src/Entity. Это создаст два файла: BlogPost.php и BlogComment.php.

Tip

Также возможно генерировать файлы метаданных в XML или YAML-формате:

1
$ php bin/console doctrine:mapping:import "App\Entity" xml --path=config/doctrine

В данном случае, убедитесь, что ваша конфигурация учитывает это:

1
2
3
4
5
6
7
8
9
10
11
12
# config/packages/doctrine.yaml
doctrine:
    # ...
    orm:
        # ...
        mappings:
            App:
                is_bundle: false
                type: xml # "yml" is marked as deprecated for doctrine v2.6+ and will be removed in v3
                dir: '%kernel.project_dir%/config/doctrine'
                prefix: 'App\Entity'
                alias: App

Генерация геттеров & сеттеров или PHP-классов

Сгенерированные PHP-классы теперь имеют свойства и метаданные в аннотациях, но в них нет getter/setter методов. Если вы генерировали метаданные в XML или YAML-фомате, у вас даже нет PHP-классов!

Для генерации недостающих getter/setter методов (или для создания классов, если необходимо), запустите:

1
2
3
4
5
// генерирует методы геттера/сеттера для всех Сущностей
$ php bin/console make:entity --regenerate App

// генерирует методы геттера/сеттера для одной конкретной Сущности
$ php bin/console make:entity --regenerate App\Entity\Country

Note

Если вы хотите иметь отношение OneToMany, то вам понадобится добавить его вручную в сущности (например, добавить свойство comments к BlogPost) или к сгенерированным файлами XML или YAML. Добавьте раздел по необходимым сущностям для отношений one-to-many, определив настройки inversedBy и mappedBy.

Сгенерированные сущности теперь готовы к использованию. Повеселитесь!