Зачем использовать Doctrine

Автор: Aport Суббота, Январь 31st, 2015 Нет комментариев

Рубрика: Язык PHP

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

Для начала я процитирую Википедию, потому что это базовые знания, без них никак.

Doctrine — объектно-реляционный проектор (ORM) для PHP 5.3.0+, который базируется на слое абстракции доступа к БД (DBAL). Одной из ключевых возможностей Doctrine является запись запросов к БД на собственном объектно-ориентированном диалекте SQL, называемый DQL (Doctrine Query Language) и базирующийся на идеях HQL (Hibernate Query Language).

А теперь, поговорим о преимуществах

Существует несколько мнений (с некоторыми я не согласен), почему ORM значительно упрощает поддержку БД, например:

  1. удобно дебажить, когда переименовали или удалили поле «name» из таблицы — придется каким-то хитрым образом найти во всем проекте все места в коде, в которых запросы могут использовать это поле. В случае работы через ORM мы сможем сразу узнать, какой скрипт попытался выполнить неправильный запрос (не согласен);
  2. удобно переименовать поля в коде — при использовании ORM можем воспользоваться всеми возможностями таких штук как Resharper (но не для PHP), и автоматом переименовывать там где надо (согласен, если имеется ввиду гетеры и сетеры, ведь действительно с помощью IDE удобно искать места где они могут быть использованы);
  3. можно переходить на другие БД — например можно перенести часть таблиц на NoSQL, и сделать это так, что ни один программист не заметит этого. По сути позволяет абстрагироваться от способа хранения объектов вообще, с лёгкостью переходя от SQL к NoSQL, memcache, файлам или REST/RPC API на удалённом сервере, оперируя на уровне модели (согласен, но резко сокращаются возможности БД с которой мы будем работать);
  4. можно кэшировать — не самая высокая оптимальность запросов через ORM, частично компенсируется возможностью кэширования объектов, а так же возможностью выполнения части запросов (с учетом легкой масштабируемости последнего). Однако, нельзя забывать, что СУБД отлично умеют кешируют данные и не нужно реализовывать лишнее кэширование (все так, но этим нужно еще уметь пользоваться и не всегда правильно кэшировать все подряд);
  5. ORM это инструмент облегчения разделения труда разработчиков: кто хорошо шарит в SQL вообще и особенностях конкретного движка в частности — работает по «ту сторону» ORM, оптимизирует его как хочет, может нормализовывать и денормализовывать, а тот, кому дали определенную задачу создания интерфейса в программе или сайте, может вообще ничего не знать об SQL, ему лишь нужно знать, что он всегда может получить объект или коллекцию объектов, обратившись к методам вроде findById() или findAll() и сохранить результат работы методом save() или flush();
  6. можно реализовывать что-то вроде транзакций — когда Вы пишите несколько запросов, и в самом конце выполняете их;
  7. автоматическая валидация значений с помощью анотаций к полям в описании сущностей, например @Assert\Range (согласен, очень удобно);
  8. возможность мультиязычного указания ошибки валидации, например @Assert\Type(type=»integer», message=»divisionKindId.integer») (действительно удобно);
  9. а еще удобно писать сложные запросы — как пример выборка товаров с помощю ORM:


$select = $db->select()->from(‘goods’);
$select->join(‘pages’, ‘pages.idPage = goods.idPage’);
if ($route) {
$select->join(‘routing’, ‘pages.idRoute = routing.idRoute’);
}
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());
}
if ($photo) {
$select->join(‘photos’, ‘goods.idPhoto = photos.idPhoto’);
}
$select->where(‘pages.pageType = ?’, self::TYPE_GOOD);
if ($idCatalog) {
$select->where(‘goods.idCatalog = ?’,$idCatalog);
}
if ($idCategory) {
$select->where(‘goods.idCategory = ?’,$idCategory);
}
if ($idCity) {
$select->where(‘goods.idCity = ?’,$idCity);
}

И давайте на чистоту — пока вы создаете что-то мелкое — у вас нет никаких проблем с «ручным» кодом. Даже если вы завтра решите поменять тип БД, добавить еще кое-какие поля в пару таблиц, немного поменять логику — вы легко измените ваши 38 написанных ручками запросов. Проблемы начинаются тогда, когда у вас в проекте полсотни-сотня таблиц со своими связями. И вдруг вам понадобится например сменить БД с MySQL на PostgreSQL. Ну или например добавить еще пару таблиц, связи их с другими, изменить кое-где поля. Что вы сделаете в случае 462 «ручных» запросов? Правильно, вы запасетесь свободной неделькой, прошерстите все запросы, добавите/измените нужные, также поменяете обработчики данных для валидации, покопаетесь в формах, полезете в базу и добавите там все необходимое. Как следствие вы допустите массу ошибок и опечаток и еще неделю после будете отлавливать баги, из которых минимум пять все равно останутся незамеченными и всплывут уже в рабочем проекте в самое неподходящее время.

Что вы сделаете в случае с ОРМ — Вы залезете в описание схемы, добавите нужные модели/свойства, перегенерируете все, получите на выходе измененные формы, модели и структуру БД, допишете немного кода, поправите отображение форм и пойдете пить пиво с друзьями.
Вы все еще пишете запросы ручками? Тогда мы идем к вам Про скорость читайте ниже.

Где НЕ нужно ОРМ

1. когда вы работаете с огромным количеством запросов только на чтение, при этом запросы из-за частого изменения данных нет смысла кешировать — вот тогда милости просим, делаете прямой запрос через PDO и радуетесь небольшому приросту скорости выборки и уменьшению расхода RAM.

2. когда у Вас в проекте много аналитики, и нужно писать сложные SQL-запросы

 

Источник: yapro.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты