Первое, что делает мудрый человек, это спрашивает себя - зачем мне это нужно, вот и я решил поступить таким же образом, при знакомстве с ORM Doctrine (по факту реализующую спецификацию JPA).
Для начала я процитирую Википедию, потому что это базовые знания, без них никак.
Doctrine — объектно-реляционный проектор (ORM) для PHP, который базируется на слое абстракции доступа к БД (DBAL). Одной из ключевых возможностей Doctrine является запись запросов к БД на собственном объектно-ориентированном диалекте SQL, называемый DQL (Doctrine Query Language) и базирующийся на идеях HQL (Hibernate Query Language).
Существует несколько мнений, почему ORM значительно упрощает поддержку БД, например:
$query = $em ->createQuery("SELECT s FROM ASBillingBundle:Subscription s")->setFetchMode(
"ASBillingBundle:Subscription",
"user",
DoctrineORMMappingClassMetadata::FETCH_EAGER
);
$select = $db->select()->from('goods');
$select->join('pages', 'pages.idPage = goods.idPage');
if ($content) {
$select->join('content', 'content.idContentPack = pages.idContentPack');
$select->where('content.idLang = ?', Kernel_Locale::getCurrent()->getId());
if ($search) {
$select->where('content.contentName = ?', $search);
}
}
if (!$expired) {
$select->where('goods.goodExpirationDate > ?', time());
}
И давайте на чистоту - если Вы завтра решите добавить еще кое-какие поля в пару таблиц, немного поменять логику - вы легко измените ваши 38 написанных ручками запросов. Проблемы начинаются тогда, когда у вас в проекте полсотни-сотня таблиц со своими связями. Что вы сделаете в случае 462 "ручных" запросов? Правильно, вы запасетесь свободной неделькой, прошерстите все запросы, добавите/измените нужные, также поменяете обработчики данных для валидации, покопаетесь в формах, полезете в базу и добавите там все необходимое. Как следствие вы допустите массу ошибок и опечаток и еще неделю после будете отлавливать баги, из которых минимум пять все равно останутся незамеченными и всплывут уже в рабочем проекте в самое неподходящее время.
Что вы сделаете в случае с ОРМ — Вы залезете в описание схемы, добавите нужные модели/свойства, перегенерируете все, получите на выходе измененные формы, модели и структуру БД, допишете немного кода, поправите отображение форм и пойдете пить пиво с друзьями.
Закешируем какой-нибудь запрос
$query = $em->createQuery($dql);
$query->useResultCache(true);
Очистим кэш без рестарта приложения, в котором хранится кэш:
php app/console doctrine:cache:clear-metadata
php app/console doctrine:cache:clear-query
php app/console doctrine:cache:clear-result
Недостатков фактически нет, но есть рекомендации, когда не стоит использовать ORM:
Коротко, паттерны из которых состоит:
| Data Mapper | таблица базы данных может быть представлена как PHP-класс сущности, а строка из таблицы как экземпляр объекта класса |
| Identity Map | если ты повторно выбираешь ту же самую сущность из базы, тебе возвращается ссылка на существующую сущность. Доктрина следит чтобы каждая сущность существовала ровно в одном экземпляре, и это помогает избежать противоречий, когда есть несколько экземпляров одного объекта и непонятно в каком из них актуальные данные. Мартин Фаулер дает такое описание: Identity Map - гарантирует, что каждый объект будет загружен из базы данных только один раз, сохраняя загруженный объект в специальной коллекции. При получении запроса просматривает коллекцию в поисках нужного объекта. |
| Unit of Work | хранит в себе сведения обо всех объектах, извлеченных, обновленных, созданных и удаленных на протяжении текущего сеанса. Задача Unit of Work следить за всеми действиями приложения, которые могут изменить БД в рамках одной бизнес-транзакции. Когда бизнес-транзакция завершается, Unit of Work выявляет все изменения и вносит их в БД, параллельно оптимизируя этот процесс. |
| EntityManager | это классическая реализация паттерна Facade. Через его легкий API мы работаем с рядом подсистем: Unit Of Work, Query language и Repository API. Управление сущностями выполняется исключительно через API EntityManager-а. Например, когда ты делаешь изменения в сущностях, они не сохраняются автоматически, ты должен явно вызвать метод flush() и тогда произойдет следующее $this->unitOfWork->commit(); Таким образом Unit Of Work найдет все изменившиеся, новые и удаленные сущности и соответственно обновит/вставит/удалит записи в базе одной транзакцией. |
Для работы с разного типа базами данных используется Metadata Drivers
Компоненты для работы с реляционными базами данных:

Голубые блоки обозначают PHP-движок и расширения PHP, на основе которых построена Doctrine.
Doctrine\Common. Общая библиотека для проектов Doctrine. Этот компонент предоставляет широко используемый набор функций.
Doctrine\Annotations. Парсер многострочных комментариев.
Doctrine\Inflector. Манипуляции со строками, касающиеся изменения регистра и единственного/множественного числа.
Doctrine\Lexer. Базовая библиотека для лексического анализатора, который может использоваться в нисходящем синтаксическом анализе и методе рекурсивного спуска.
Doctrine\Cache. Библиотека для кэширования, предлагающая объектно-ориентированный API для многих бэкендов кеша.
Doctrine\DBAL. Абстрактный уровень БД. This is a lightweight and thin runtime layer around a PDO-like API and a lot of additional, horizontal features like database schema introspection and manipulation through an object oriented API.
Doctrine\Collections. Библиотека для абстракции коллекций.
Doctrine\ORM. Компонент для объектно-реляционного отображения. Позволяет работать с моделями сущностей объектно-ориентированным методом вместо запросов на чистом SQL.
Doctrine\Migrations. Миграции схем БД с использованием Doctrine DBAL. Предоставляет последовательный способ управления схемой БД и ее обновления.
Doctrine\DataFixtures. Данные предварительной настройки для всех менеджеров объектов Doctrine. Предоставляет фреймворк для создания данных предварительной настройки.
Компоненты для работы с NoSQL-БД:

Doctrine\MongoDB - уровень абстракции Dotrine MongoDB.
Doctrine\MongodbODM (Object Document Mapper) предоставляет возможность устанавливать соответствие между документами NoSQL и моделями сущностей PHP.
Doctrine\MongoODMModule - модуль Zend Framework 3, обеспечивающий функциональность Doctrine MongoDB ODM.
Doctrine\CouchDB - компонент, предоставляющий API, который является оберткой для API CouchDB для доступа по HTTP.
Doctrine\CouchDB - компонент CouchDB Document Object Mapper. Аналогично Doctrine ORM он предоставляет возможность доступа к БД объектно-ориентированным методом.
Doctrine\OrientdbODM - набор библиотек PHP для использования OrientDB.
Doctrine\PhpcrODM - это Object Document Mapper для PHPCR.
Коротко, можно описать жизнь объекта так:

Источники: 1 - 2 - 3 - 5 - 6 - 7 - 8 - 9 - 10 - 11