Doctrine ORM и слой работы с базой данных в Symfony
Doctrine — это набор PHP-библиотек, ориентированных на хранение данных и объектно-реляционное отображение (ORM).
1. Паттерн Data Mapper
В отличие от Eloquent в Laravel (Active Record), Doctrine использует паттерн Data Mapper. Это означает, что ваши сущности (PHP-классы) — это обычные объекты (POPO), которые ничего не знают о том, как они сохраняются в базе данных. Логику персистентности берёт на себя EntityManager.
2. Основные компоненты
- EntityManager: Главный интерфейс для работы с Doctrine. Используется для сохранения, синхронизации, поиска и удаления сущностей.
- Unit of Work: Внутренний компонент, отслеживающий все объекты, которые в данный момент «управляются» EntityManager. При вызове
flush()он вычисляет различия и выполняет необходимые SQL-запросы. - Repositories: Классы, содержащие пользовательскую логику получения сущностей (например,
findByEmail).
3. Жизненный цикл сущности и со бытия
Doctrine позволяет встраиваться в различные этапы жизненного цикла сущности:
prePersist,postPersistpreUpdate,postUpdatepreRemove,postRemovepostLoad
Обработка возможна с помощью Lifecycle Callbacks (внутри сущности) или Event Listeners/Subscribers (отдельные классы).
4. DQL vs DBAL
- DQL (Doctrine Query Language): Объектно-ориентированный язык запросов, похожий на SQL, но работающий с PHP-классами и свойствами вместо имён таблиц и столбцов.
- DBAL (Database Abstraction Layer): Низкоуровневая библиотека, предоставляющая единый API для взаимодействия с различными СУБД (MySQL, PostgreSQL и др.) через «сырой» SQL.
5. Стратегии загрузки
- Lazy Loading: Связанные сущности загружаются из базы данных только при непосредственном обращении к ним (по умолчанию для коллекций).
- Eager Loading: Связанные сущности загружаются сразу в том же запросе (с использованием JOIN).
6. Частые вопросы на собеседованиях
flush()vspersist():persist()указывает Doctrine «управлять» объектом;flush()фактически выполняет SQL-команды для сохранения изменений в базе данных.- Наследование при маппинге: Doctrine поддерживает несколько способов отображения наследования классов на таблицы базы данных:
- Mapped Superclass: Таблицы создаются только для дочерних классов.
- Single Table Inheritance: Все классы иерархии хранятся в одной таблице с коло нкой-дискриминатором.
- Class Table Inheritance: У каждого класса своя таблица, связанная внешними ключами.