A free and open-source book on ZF3 for beginners


12.7. О менеджере сущностей

Менеджер сущностей - это основная точка доступа к функциональности ORM.

EntityManager - это класс Doctrine, который "живет" в пространстве имен Doctrine\ORM и используется для извлечения сущностей из их репозиториев с помощью критериев поиска, а также для их сохранения в базу данных.

EntityManager зарегистрирован в качестве сервиса в менеджере сервисов Zend Framework 3. Он извлекается из менеджера сервисов в классе фабрики следующим образом (если вам нужно другое соединение, просто замените orm_default именем необходимого соединения):

// Получаем менеджер сущностей Doctrine
$entityManager = $container->get('doctrine.entitymanager.orm_default');   

Наиболее часто используемые методы класса EntityManager перечислены в таблице 12.4 ниже.

Таблица 12.4. Методы EntityManager
Метод Описание
persist($entity) Помещает новую сущность в менеджер сущностей (делает ее управляемой).
remove($entity) Удаляет сущность из базы данных.
flush() Сбрасывает все изменения объектов в очереди в базу.
createQuery($dql) Создает новый объект Query.
getRepository($entityName) Получает репозиторий класса сущности.

Давайте рассмотрим методы из таблицы 12.4.

Чтобы добавить недавно созданную сущность в менеджер сущностей (чтобы сделать ее "управляемой"), используйте метод менеджера сущностей persist(). Чтобы удалить сущность из базы данных, воспользуйтесь методом remove().

Когда вы вызываете методы persist() или remove(), EntityManager запоминает ваши изменения в памяти, но не применяет их к базе данных автоматически (из соображений производительности). Чтобы применить все изменения к БД разом, используйте метод flush().

Пример кода ниже, показывает, как создать экземпляр сущности Post и сохранить его в базе данных:

// Создаем новую сущность Post.
$post = new Post();
$post->setTitle('Top 10+ Books about Zend Framework 3');
$post->setContent('Post body goes here');
$post->setStatus(Post::STATUS_PUBLISHED);
$currentDate = date('Y-m-d H:i:s');
$post->setDateCreated($currentDate);        

// Добавляем сущность в менеджер сущностей.
$entityManager->persist($post);

// Применяем изменения к БД.
$entityManager->flush();

Метод менеджера сущностей createQuery() предназначен для создания запроса из DQL-строки. Он возвращает объект Query. Затем вы можете выполнить запрос и получить результаты (массив сущностей, соответствующих условиям поиска).

Метод getRepository() предназначен для получения репозитория по имени класса сущности. Ниже вы можете увидеть пример, где мы получаем репозиторий для нашей сущности Post:

$repository = $entityManager->getRepository(Post::class);

12.7.1. Репозитории сущностей

Теоретически, у каждого класса сущности есть свой репозиторий. Репозиторий предоставляет методы для извлечения сущностей из базы данных. Репозиторий можно считать коллекцией всех доступных сущностей определенного класса. Например, существуют репозитории для созданных нами сущностей Post, Comment, и Tag.

Для того, чтобы загрузить данные из БД, нужно извлечь сущность из ее репозитория. Когда вы запрашиваете у репозитория сущность, он загружает данные из таблицы, сопоставляемой с этой сущностью, и присваивает данные полям сущности.

Класс Doctrine\ORM\EntityRepository реализует репозиторий по умолчанию. При необходимости, расширив EntityRepository, вы можете создать свой собственный репозиторий для определенного класса сущности. Позже мы покажем, как это сделать.

Наиболее часто используемые методы класса EntityRepository перечислены в таблице 12.5.

Таблица 12.5. Методы EntityRepository
Метод Описание
findAll() Находит все сущности в репозитории.
find($id) Находит сущность по ее идентификатору.
findBy($criteria, $orderBy, $limit, $offset) Находит сущности по набору критериев.
findOneBy($criteria, $orderBy) Находит одну сущность по набору критериев.
createQueryBuilder($alias) Создает новый экземпляр QueryBuilder, предзаполненный для этого имени сущности.

Метод findAll() получает все сущности из репозитория. Простой пример его использования показан ниже:

// Находит все посты в репозитории.
$posts = $entityManager->getRepository(Post::class)->findAll();

Метод find() - самый простой метод для поиска сущности. Он извлекает сущность по ее ID (первичному ключу).

В примере ниже мы выбираем пост с ID = 1.

// Находим пост по первичному ключу (ID).
$post = $entityManager->getRepository(Post::class)->find(1);

findBy() принимает критерии поиска (и, опционально, порядок сортировки и границы) и возвращает коллекцию сущностей, соответствующих критериям. Метод findOneBy() очень похож на findBy(), однако он возвращает первую соответствующую критериям сущность.

В следующем примере кода мы используем метод findBy() для выбора 50 последних опубликованных постов:

In the code example below, we use the findBy() method for selecting 50 most recent published posts:

// Находим 50 последних опубликованных постов
$posts = $entityManager->getRepository(Post::class)->findBy(
           ['status'=>Post::STATUS_PUBLISHED], 
           ['dateCreated'=>'DESC'], 50);

Для удобства, класс EntityRepository также предоставляет магические методы, позволяющие запрашивать сущности по имени атрибута с помощью методов findByX and findOneByX, следующим способом (просто замените плейсхолдер X именем атрибута):

// Запрашивает один пост по его атрибуту ID
$post = $entityManager->getRepository(Post::class)->findOneById(1);

// Запрашивает посты по атрибуту статуса
$posts = $entityManager->getRepository(Post::class)
        ->findByStatus(Post::STATUS_PUBLISHED);

И наконец, наиболее сложный метод поиска - метод createQueryBuilder(). Он позволяет создавать сложные DQL-запросы.

Если стандартных методов поиска недостаточно (или у вас сложные критерии поиска и DQL-запросы), вы можете создать свой собственный репозиторий, расширив стандартный класс EntityRepository и инкапсулировав в него алгоритм поиска. Мы покажем, как это сделать, позже, при реализации облака тегов для нашего приложения Blog.


Top