orm что это такое

Что такое ORM

orm что это такое. Смотреть фото orm что это такое. Смотреть картинку orm что это такое. Картинка про orm что это такое. Фото orm что это такое

Любой, кто имеет опыт разработки web приложений или использования какого-либо PHP фреймворка, безусловно, сталкивался с реляционными базами данных, такими как MySQL или PostgreSQL. Работа с SQL напрямую, может быть достаточно сложной, особенно при работе с данными сразу из нескольких таблиц и при применении различных фильтров. А это как раз та сфера, где на сцену выходит ORM.

Так, что же такое ORM?

ORM фреймворк может быть написан на каком-либо объектно-ориентированном языке ( PHP, Python, Ruby ) и представлять обертку над некой реляционной базой данных. Классы будут соответствовать таблицам в базе, а экземпляры этих классов – конкретным строкам таблицы.

Далее обсудим преимущества концепции ORM. Стоит также отметить, что не все библиотеки, реализующие данную концепцию, обладают всеми рассмотренными здесь преимуществами.

Независимость от вида базы данных

Это, пожалуй, главнейшая особенность и преимущество использования ORM в приложении. Так как нет необходимости писать специфический код под конкретный вид базы данных. Поэтому, вы можете начать проект с использования SQLite, затем можете поменять ее на MySQL или PostgreSQL. И все это делается редактированием пары строчек кода в настройках адаптера базы данных.

Моделирование предметной области

При использовании ORM для построения приложения, бизнес-логика приложения работает с объектами языка, а не с самой структурой базы данных. Это возможно благодаря соответствию между бизнес-моделью и самой базой данных.

Меньше кода и больше эффективности

ORM добавляет дополнительный слой абстракции, который позволяет разработчикам сконцентрироваться на их бизнес-логике, не отвлекаясь на создание сложных запросов к базе данных. Это приводит к сокращению количества необходимого для написания кода и увеличивает продуктивность разработчика.

Развитый интерфейс запросов к базе

В ORM предусмотрен богатый интерфейс, освобождающий разработчика от сложной семантики SQL.

ORM предоставляет свободное управление зависимостями в базе данных. Связанные объекты загружаются автоматически, когда вызов методов преобразуется в соответствующий SQL запрос.

Параллелизм, кэширование и транзакции

ORM поддерживает возможность параллельной работы, позволяя нескольким пользователям одновременно изменять один и тот же объект.

Другая особенность – объекты могут быть сохранены в кэше, сокращая нагрузку на базу и вцелом увеличивая скорость работы приложения.

Изменения, вносимые в объект могут быть ограничены в рамках данной транзакции, которая может быть сохранена или возвращена обратно в первоначальное состояние. В каждый момент времени могут быть активными множество транзакций, но все эти транзакции изолированы друг от друга.

ORM фреймворк добавляет слой абстракции, ускоряющий процесс разработки и снижающий сложность создания конечного продукта. Однако, ничто не проходит даром – приложение начинает потреблять больше памяти и нагрузка на процессор также увеличивается.

Применение ORM в PHP приложении предполагает, что у разработчика есть опыт работы с каким либо PHP фреймворком. И поэтому здесь без дополнительных знаний будет обойтись нелегко. Хотя вы можете значительно сократить время изучения ORM в PHP, если воспользуетесь моим курсом Фреймворк Yii 2.0 с нуля. Пример создания сайта. Там, в уроке номер 3 “Создание моделей”, я как раз рассказываю о создании объектов базы данных с помощью шаблона проектирования ActiveRecord.

Некоторые операции, такие как массовая вставка, обновление, удаление и т.д., медленнее, когда выполняются посредством ORM. Поэтому, в таких случаях лучше использовать чистый SQL.

Поверхностное знание SQL

Несмотря на то, что ORM облегчает жизнь, это часто приводит к тому, что разработчики не очень стремятся учить SQL или разбираются в нем слабо.

На сегодня все. Всего доброго!

orm что это такое. Смотреть фото orm что это такое. Смотреть картинку orm что это такое. Картинка про orm что это такое. Фото orm что это такое

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Комментарии ( 0 ):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

Copyright © 2010-2021 Русаков Михаил Юрьевич. Все права защищены.

Источник

SQL vs ORM

Друзья, вновь пришло время авторской колонки корпоративного блога PG Day’17. Предлагаем вашему вниманию сравнительный анализ работы с PostgreSQL из популярных ORM от varanio.

orm что это такое. Смотреть фото orm что это такое. Смотреть картинку orm что это такое. Картинка про orm что это такое. Фото orm что это такоеORM (Object-Relational Mapping), по идее, должен избавить нас от написания SQL запросов и, в идеале, вообще абстрагировать от базы данных (от способа хранения данных), чтобы мы могли работать с классами, в той или иной степени выражающими объекты бизнес-логики, не задаваясь вопросом, в каких таблицах всё это по факту лежит.

Посмотрим, насколько это удается современным библиотекам на PHP. Давайте рассмотрим несколько типичных кейсов и сравним ORM с голым SQL, написанным вручную.

Для примера возьмем две таблицы: книги и авторы книг, отношение многие-ко-многим (у книг может быть много авторов, у авторов может быть много книг). Т.е. в базе это будут books, authors и связующая таблица author_book:

Рассмотрим несколько кейсов использования.

Кейс 1. Создание записей

Добавим авторов и книг.

Голый SQL

Ну, тут всё просто и прямолинейно:

Laravel (Eloquent SQL)

В Laravel используется ORM под названием Eloquent. Eloquent — это, по сути, ActiveRecord, т.е. отображение таблиц на некие соответствующие им классы («модели»), причем модель сама умеет себя сохранять.

Как видно, мы запросто описали отношение many-to-many буквально парой строк кода. Создание записей в базе и связь между ними делается достаточно просто:

Так, конечно, поприятнее, чем возиться с SQL, и даже запись в связочную таблицу делается очень легко.

Symfony (Doctrine ORM)

В доктрине используется подход DataMapper. По уверениям документации, объекты бизнес-логики отделены от способа сохранения. Здесь объекты получаются из Репозитория (Repository), т.е. сущность не знает как себя получить, это знает только Repository, а для сохранения потребуется EntityManager.

Сгенерировать классы из существующих таблиц можно одним движением:

Первая команда создаст yml-файлы для сущностей, описывающие типы полей в базе, взаимосвязь объектов (например, many-to-many) и т.д. Вторая команда создаст классы сущностей.

Прямо скажем, yml получились немаленькие, и они набиты подробностями о структуре таблиц и их связях. Вообще, можно обойтись и без yml, всё делая в аннотациях классов. Но когда классы сущностей совершенно отделены от базы, это больше соответствует концепции DDD.

Зато сами классы-сущности у нас получились совершенно простые, т.е. POJO (plain old php object):

Создаем объекты и сохраняем. Примерно так:

Вывод

В целом, использование ORM для простых случаев создания записей в таблицах является более предпочтительным способом, чем чистый SQL. Методы setName и т.д. в коде читаются лучше, чем SQL-запрос. Нет жесткой зависимости от БД.

Кейс 2. Обновление названия книги

Голый SQL

Laravel (Eloquent)

Symfony

Вывод

Обновление какого-то поля в целом тоже вполне можно делать через ORM, не вдаваясь в детали SQL.

Кейс 3. Получить список названий книг с авторами

Для тестов создадим такие записи в таблице:

Голый SQL

Laravel

Сделаем сначала втупую из мануалов а-ля «Getting Started»:

Для маленького ненагруженного сайта сойдет и так. Но если сайт нагружен и таблицы содержат много строк и данных, то это провал.

Стало немного получше, но всё равно далеко от идеала:

Тут две проблемы: authors идут всё равно со звездочкой. Кроме того, появился оператор in() с перечислением всех id, который нормально работает при маленьком количестве книг, но для большого списка это будет работать очень медленно, по крайней мере в PostgreSQL. Хотя, конечно, быстрее, чем по запросу на каждый. И с этим уже, похоже, ничего не сделать, по крайней мере я ничего не нашел.

Точнее, помимо ORM есть еще Query Builder:

Но это, повторяю, не ORM. Это тот же SQL, только вместо пробелов стрелочки и куча методов, которые надо знать дополнительно.

Symfony

Для начала тоже попробуем по-простому:

Код первой попытки почти такой же как в Laravel. SQL-запросы, в общем, тоже:

Т.е. перечислены все поля, и по запросу на каждую книгу с перечислением, опять же, всех полей.

У стандартных методов типа findAll и т.д., похоже, нет способа указать, что мне надо только такие-то поля и сразу приджойнить такие-то таблицы. Но, зато в Доктрине есть SQL-подобный синтаксис DQL, абстрагированный от конкретной СУБД, которым можно воспользоваться. Он оперирует не таблицами, а сущностями.

Ну да, получилось типа того, что надо, один запрос, с одним полем:

Выводы

На мой взгляд, простой SQL выглядит проще и стандартнее. Кроме того, в ORM-подходах мы не смогли полностью сферически абстрагироваться от базы данных, нам пришлось подстроиться под реальный мир.

DQL в принципе сойдет на замену SQL, и он не особо привязан к СУБД, но это еще один странноватый синтаксис, который надо учить отдельно.

Кейс 4. Чуть более сложный UPDATE

Допустим, стоит задача обновить двум последним авторам имя на «Жорж».

голый SQL

Тут всё просто, запрос с подзапросом.

Laravel

Сначала я попробовал сделать так:

Это было бы здорово и красиво, однако не сработало. Точнее сработало, но заменило записи всем авторам, а не только двум.

Тогда, покурив мануал и SO, удалось родить такую конструкцию:

Это работает хорошо, хоть и не особо читабельно. Да и query builder опять какой-то подъехал.

Symfony

Сразу скажу, что выразить через DQL мне этот запрос вообще не удалось, с вложенными подзапросами там всё плохо.

Есть, конечно, query builder, но получалось что-то совсем зубодробительное, и я бросил эту затею. ORM должен помогать экономить время, а не наоборот. Надеюсь, опытные симфонисты в коментах подскажут какой-нибудь легкий и изящный способ сделать update с подзапросом.

Вывод

Несмотря на привлекательную идею использовать классы бизнес-логики и не вдаваться в детали реализации хранения данных, сделать это удается далеко не всегда.

Как всегда обычно и бывает, истина где-то посередине. Для простых CRUD-операций ORM вполне может сэкономить время разработки и улучшить читабельность кода. Однако шаг вправо, шаг влево — и гораздо удобнее пользоваться нативным SQL. Например, сложные выборки/обновления (особенно, аналитические отчеты с оконными функциями и рекурсивными CTE). Компромиссным вариантом является маппинг результатов нативных запросов на объекты, Доктрина это позволяет.

В споре ORM vs SQL не победил никто.

Тем временем, всех кто намучался с ORM, тормозящими запросами и плохой производительностью в рабочих ситуациях, приглашаем на PG Day’17. У нас подготовлено для вас множество различных докладов и мастер-классов для самых разных баз данных!

Источник

Управление репутацией (SERM, ORM, HM)

В последнее время все больше предпринимателей и маркетологов обращаются к услуге по управлению репутацией: растущая популярность соцсетей делает ее востребованной в Интернете; с ее помощью можно не только сформировать репутационный фон бренда, но и повлиять на результаты поисковой выдачи.

Существует две ситуации, когда для брендов становятся актуальными услуги по управлению репутаций:

Для наилучшего результата необходимо начинать заниматься управлением репутацией бренда в Интернете ещё до его появления на рынке. Такой подход позволит компании с самого начала создать собственный положительный образ и выстроить успешный диалог с клиентом, позволяющий решать отдельные проблемы по мере их появления.

Так сложилось, что большинство клиентов и агентств неверно понимают суть управления репутацией. К примеру, распространена ситуация, когда компании предлагают SERM (управление репутацией в поисковой выдаче), на деле же сотрудники агентства, которое предоставляет услугу, всего лишь мониторят упоминания о бренде и публикуют положительные отзывы.

Проблема в том, что мало кто из игроков рынка и клиентов разбирается в разнице между скрытым маркетингом (Hidden Marketing), управлением репутацией в Сети (ORM) и управлением репутацией в поисковой выдаче. В итоге клиенты получают не те услуги, в которых нуждаются.

Рассмотрим подробнее значение упоминаемых аббревиатур и их прямое назначение.

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

Отличие агентов влияния от лидеров мнений значительное: вторым может быть любая популярная личность аудитория которого совпадает с целевой — от Юрия Дудя до Тутты Ларсен. В этом случае товар или услуга напрямую рекламируется знаменитостью.

Для примера возьмем стратегию продвижения мебельной фабрики. На форуме для дизайнеров интерьеров агент влияния интересуется, где купить диван с двумя противоположными спинками. К вопросу подключается другой заинтересованный пользователь, третий участник беседы информирует, что известные фабрики не производят таких моделей. Четвёртый агент влияния упоминает компанию, которая делает диваны с двумя спинками. Итого: на форуме работают четыре пользователя, продвигающие фабрику руками сотрудников агентства.

Другой вариант: использовать популярный форум о ремонте или с советами по дизайну для создания ветки обсуждения. Вначале появляется вопрос от агента влияния, где лучше приобрести диван «Атланта» (востребованная модель, которая имеется в наличии у большинства производителей). Второй пользователь комментирует, мол пытался купить диван в двух магазинах, но один из них не смог вовремя доставить мебель. В результате, такой диалог стимулирует аудиторию к выбору нужной компании.

Для скрытого маркетинга важны площадки, на которых размещены упоминания о бренде, но не их количество. Поэтому эффективные агентства подходят к продвижению бренда стратегически, к примеру, оперируют инструментами поисковой оптимизации.

Перед тем, как советовать конкретные форумы для мебельной фабрики, агентства делают анализ результатов поисковой выдачи по запросу «какая компания быстрее всех делает кухонную мебель». Человек, изучающий советы на профильных площадках, будет регулярно видеть имя бренда.

Повышение узнаваемости бренда.

Рост заинтересованности целевой аудитории товарами или услугами, т.к. рекомендации исходят от обычных пользователей (агентов влияния) и знаменитостей, к мнению которых прислушивается аудитория.

Низкая цена на продвижение через агентов влияния в сравнении с привычной рекламой.

Трудности в оценке эффективности. К примеру, отдачу от прямой рекламы у блогера можно анализировать по количеству переходов на сайт или по числу активированных промокодов, предлагаемых подписчикам.

Маркетинг под прикрытием не предполагает ссылок или показателей, которые бы позволяли отследить его эффективность. В отдельных случаях об успехе продвижения может сигнализировать рост трафика или увеличение продаж. С другой стороны, всплеск пользовательской активности можно отнести на счёт скрытого маркетинга, при условии, что параллельно не запущены другие рекламные кампании.

Работа только с позитивными отзывами. Используя исключительно скрытый маркетинг, компания не будет знать о негативных публикациях, которые отрицательно повлияют на поведение потенциальных покупателей.

Только что появившимся брендам или продуктам, выходящим на рынок B2C. Успешно работает для бизнеса любой тематики, особенно для недвижимости и фармацевтики.

Такие сервисы, как YouScan, IQBuzz или Brand Analytics позволяют агентству регулярно мониторить упоминания о бренде. Буквально через каждые 10–20 минут сервисы сканируют собственные базы сайтов и сигнализируют о появлении новых отзывов.

Далее вся полученная информация обрабатывается и анализируется. Отзывы сегментируются: решение проблем клиентов, ответы на вопросы по товарам или услугам и благодарность за положительные отзывы.

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

Проанализируем ситуацию, в которой сервис мониторинга уведомляет о появлении негативного отзыва о прачечной: потребитель недоволен качеством чистки пальто.

Специалист агентства, ведущий коммуникацию от имени бренда, запрашивает у пользователя номер заказа, выясняет у прачечной причину возникшей проблемы и сообщает готовое решение клиенту — предлагает повторную чистку. После этого посетителя прачечной просят удалить негативный отзыв, поскольку проблема решена.

Email-рассылки агентства будут эффективны в работе с позитивными отзывами. Если потребитель обращается к услугам конкретной прачечной больше одного раза, скорее всего, он остался доволен качеством услуг. При таком раскладе пользователю высылают письмо с просьбой разместить отзыв на сайте прачечной или на известном отзовике.

Есть бренды, которые, что называется, не заморачиваются над написанием разных отзывов и размещают очень похожие хвалебные публикации на различных ресурсах. Администраторы сайтов с рекомендациями довольно быстро распознают фейковые отзывы по IP-адресам или местоположению и часто блокируют аккаунты подобных компаний.

Так, популярная площадка с отзывами регулярно обновляет антирейтинг брендов, которые часто грешат ненастоящими отзывами. Для того, чтобы не попасть в подобный рейтинг, нужно улучшить качество отзывов и использовать сервисы, позволяющие менять IP-адреса и местоположение юзера.

Еще один ресурс для повышения уровня клиентского сервиса и коммуникации с аудиторией.

Поиск и нейтрализация негативных отзывов.

Увеличение количества позитивных публикаций.

Конкретизация проблем по качеству товаров, услуг или обслуживании при системном использовании инструмента.

Автоматизация мониторинга отзывных ресурсов не идентифицирует публикации, сделанные без упоминания бренда. На отдельных сайтах, где отзывы размещаются на страницах компаний, пользователь может просто написать: «Они меня кинули». Такой комментарий сервисы не заметят. Подобная проблема решается только ручным мониторингом.

Число площадок, которые могут просканировать программы, ограничено. В основном, это соцсети и популярные форумы, составляющие всего 5% Рунета.

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

Всем, кто уже представлен на рынке и имеет собственный пул клиентов. Качественный ORM будет эффективен для любого бизнеса в сегменте B2C, особенные успехи прогнозируются в области медицины и автобизнесе. Для B2B-компаний также могут быть актуальны подобные услуги, не считая узкоспециализированных рынков с небольшим числом игроков и потребителей.

Если вы захотите опубликовать отзыв о товаре или услуге, наверняка первым делом вы откроете поисковик, наберете «бренд + отзывы» и зайдёте на первые сайты главной страницы выдачи. Такая модель поведения объясняет, почему основная задача SERM — вывод на первые страницы выдачи управляемые сайты, на которых можно работать с негативом.

Давайте посмотрим как работает SERM на примере сети медицинских клиник. Сотрудники агентства проводят регулярный мониторинг поисковой выдачи по запросу «клиники [название] + отзывы». Проверять каждый сайт на наличие отзывов и комментариев довольно долго, гораздо целесообразнее использовать для работы автоматические программы. К примеру, сервис SERMometer ежедневно анализирует поисковую выдачу и формирует тепловую карту репутационного окружения бренда.

Параллельно представители агентства следят за тем, чтобы негативные публикации относительно уже решенной проблемы были удалены. Репутация сети клиник в Интернете становится положительной.

Ресурсы с наибольшим количеством позитивных отзывов агентство повышает в выдаче поисковых систем с помощью SEO-инструментов. Также агентство инициирует создание управляемых веток на популярных форумах.

Конечно, не стоит забывать про раздел отзывов на официальном сайте компании, поскольку при грамотной работе он будет высоко ранжироваться по основным популярным запросам, связанным с брендом.

SERM эффективен ещё и потому, что работает с пользователями, находящимися на последнем этапе воронки продаж. Именно поэтому так важно управлять репутацией, чтобы мотивировать потенциальных клиентов стать реальными.

Чтобы нивелировать негатив в отзывах, компании перекрывают их количеством нейтральных и положительных публикаций. В итоге в ТОП поисковиков попадают ресурсы, которыми невозможно управлять.

Гораздо эффективнее работать со всеми задействованными сайтами и размещать позитивные отзывы на управляемых площадках, продвигая их в поисковиках.

Создание положительного образа бренда в поисковой выдаче.

Коммуникация с пользователями, готовыми совершить покупку или заказать услугу.

Возможность влияния на принятие решения потребителем.

Поиск и нейтрализация отрицательных отзывов.

Определение проблем качества товаров или услуг, а также клиентского сервиса.

Работа по управлению репутацией в поисковой выдаче без использования ORM недостаточно результативна. Повышение регулируемых площадок в ТОПе выдачи без реакции на негативные публикации и мотивации клиентов на самостоятельные отзывы — всего лишь полумера. Эффективные агентства, как правило, совмещают оба этих инструмента.

Любому бизнесу и знаменитостям. SERM отлично работает в области мебели и финансов.

Один из вами же перечисленных сервисов мониторинга собирает сообщения со страниц бренда без его упоминания в тексте на всех без исключения сайтах отзывов и некоторых топовых форумах. Не дезориентируйте читателей. Важность экспертной/агентской работы с данными я при этом нисколько не принижаю.

Илья, смею предположить, что речь о Brand Analytics? Ну раз вы там работаете.

Формулировка «всех без исключения сайтах отзывов» обязывает ко многому. Ну и чтобы никого не обижать я просто скажу, что это не так.

Кстати да, подобного рода компании часто посредники по найму фрилансеров.

И мне кажется, доверять стоит _сотрудникам_, способным отслеживать в _ручном_ режиме, в рамках других обязанностей по работе в PR/рекламе. При необходимости привлекать по трудовым договорам более-менее реальных (проверенных) людей, желательно из того же города/региона, где главный офис компании.

Фабрика троллей, ничем не хуже и не лучше «индийского outsource», использовавшегося в _крупнейших_ американских корпорациях, пока они не поняли, что скорее разрушают свой имидж и лояльность клиентов, чем просто «экономят на второстепенных рутинных функциях».

А не просто: «Благодарим за внимание к продуктам и услугам нашей компании».

Источник

Выборка данных с ORM — это просто! Или нет?

orm что это такое. Смотреть фото orm что это такое. Смотреть картинку orm что это такое. Картинка про orm что это такое. Фото orm что это такое

Введение

Практически любая информационная система так или иначе взаимодействует с внешними хранилищами данных. В большинстве случаев это реляционная база данных, и, зачастую, для работы с данными используется какой-либо ORM фреймворк. ORM устраняет большую часть рутинных операций, взамен предлагая небольшой набор дополнительных абстракций для работы с данными.

Мартин Фаулер опубликовал интересную статью, одна из ключевых мыслей там: “ORM’ы помогают нам решать большое количество задач в энтерпрайз приложениях… Этот инструмент нельзя назвать симпатичным, но и проблемы, с которыми он имеет дело, тоже не милашки. Я думаю, что ORM заслуживают больше уважения и больше понимания”

Мы очень интенсивно используем ORM во фреймворке CUBA, так что не понаслышке знаем о проблемах и ограничениях этой технологии, поскольку CUBA используется в различных проектах по всему миру. Есть много тем, которые можно обсудить в связи с ORM, но мы сосредоточимся на одной из них: выбор между “ленивым” (lazy) и “жадным” (eager) способами выборки данных. Поговорим о разных подходах к решению этой проблемы с иллюстрациями из JPA API и Spring, а также расскажем, как (и почему именно так) ORM используется в CUBA и какие работы мы ведем, чтобы улучшить работу с данными в нашем фреймворке.

Выборка данных: ленивая или нет?

Чтобы вытащить экземпляр этой сущности из БД, нам нужно всего лишь вызвать один метод объекта EntityManager :

Все становится немного интереснее, когда появляется отношение “один-ко-многим”:

Если нам нужно извлечь из БД экземпляр пользователя, возникает вопрос: “А адреса тоже выбираем?”. И “правильный” ответ здесь: “Зависит от. ” В некоторых случаях нам адреса будут нужны, в некоторых — нет. Обычно ORM предоставляет два способа выборки зависимых записей: ленивый и жадный. По умолчанию в большинстве ORM используется ленивый способ. Но, если мы напишем такой код:

Так, а если попробовать другой тип выборки?

Ну… нельзя сказать, что это сильно поможет. Да, избавимся от ненавистного LazyInit и не надо проверять, прикреплена сущность к сессии или нет. Но теперь у нас могут возникнуть проблемы с производительностью, потому что адреса нам нужны не всегда, а мы все равно выбираем эти объекты в память сервера.
Ещё идеи?

Spring JDBC

Некоторые разработчики настолько устают от ORM, что переключаются на альтернативные фреймворки. Например, на Spring JDBC, который предоставляет возможность преобразования реляционных данных в объектные в “полуавтоматическом” режиме. Разработчик пишет запросы для каждого случая, где нужен тот или иной набор атрибутов (или один и тот же код повторно используется для случаев, где нужны одинаковые структуры данных).

Это дает нам большую гибкость. Например, можно выбрать только один атрибут, не создавая соответствующий объект-сущность:

Или выбрать объект в привычном виде:

Также можно выбрать и список адресов для пользователя, нужно только написать чуть больше кода и правильно составить SQL запрос, чтобы избежать проблемы n+1 запроса.

Тааак, опять сложновато. Да, мы контролируем все запросы и то, как данные отображаются на объекты, но надо писать больше кода, учить SQL и знать, как запросы выполняются в базе данных. Лично я думаю, что знание SQL — это обязательный навык для прикладного программиста, но так думают не все, и я не собираюсь вступать в полемику. В конце концов, знание инструкций x86 ассемблера в наши дни тоже необязательно. Давайте лучше подумаем о том, как облегчить жизнь программистам.

JPA EntityGraph

А давайте сделаем шаг назад и подумаем, что нам вообще нужно? Похоже, что нам просто надо указывать, какие точно атрибуты нам нужны в каждом конкретном случае. Ну и давайте это делать! В JPA 2.1 появился новый API — EntityGraph (граф сущностей). Идея — очень простая: используем аннотации для того, чтобы описать то, что будем выбирать из базы. Вот пример:

Для данной сущности описано два графа: user-only-entity-graph не выбирает атрибут Addresses (помеченный как lazy), в то время, как второй граф указывает ORM выбирать этот атрибут. Если мы пометим Addresses как eager, то граф будет проигнорирован и адреса будут выбраны в любом случае.

Итак, в JPA 2.1 можно делать выборку данных вот так:

Этот подход сильно упрощает работу, не нужно отдельно думать про lazy атрибуты, и длину транзакций. Дополнительный бонус — граф применяется на уровне SQL запроса, таким образом “лишние” данные не выбираются в Java приложение. Но есть одна небольшая проблема: нельзя сказать, какие атрибуты были выбраны, а какие — нет. Для проверки есть API, это делается при помощи класса PersistenceUtil :

Но это довольно-таки уныло и не все готовы делать такие проверки. А можно ещё что-нибудь упростить и просто не показывать атрибуты, которые не были выбраны?

Проекции Spring

В Spring Framework есть отличная штука, которая называется “Проекции” (и это не то же самое, что проекции в Hibernate). Если нужно выбрать только некоторые атрибуты сущности, то создается интерфейс с нужными атрибутами, и Spring выбирает “экземпляры” этого интерфейса из БД. В качестве примера, рассмотрим следующий интерфейс:

Теперь можно определить Spring JPA репозиторий для выборки сущностей User следующим образом:

В этом случае, после вызова метода findByName, в полученном списке мы получим сущности, у которых доступ открыт только к атрибутам, которые определены в интерфейсе! По такому же принципу можно выбирать и зависимые сущности, т.е. выбираем сразу отношение “master-detail”. Более того, Spring генерирует “правильный” SQL в большинстве случаев, т.е. из БД выбираются только те атрибуты, которые описаны в проекции, это очень похоже на то, как работают графы сущностей.
Это очень мощный API, при определении интерфейсов можно использовать выражения SpEL, использовать классы с какой-то встроенной логикой вместо интерфейсов и ещё много чего, в документации все расписано очень подробно.
Единственная проблема с проекциями в том, что внутри они реализованы в виде пар “ключ — значение”, т.е. предназначены только для чтения. А это значит, что, даже если мы и определим setter метод для проекции, то изменения сохранить не сможем ни через CRUD репозитории, ни через EntityManager. Так что проекции — это такие DTO, которые можно преобразовать обратно в Entity и сохранять, только если написать свой собственный код для этого.

Как выбираются данные в CUBA

С самого начала разработки фреймворка CUBA мы старались оптимизировать часть кода, который работает с БД. В CUBA мы используем EclipseLink как основу для API доступа к данным. Что хорошо в EclipseLink — он с самого начала поддерживал частичную загрузку сущностей, и это стало решающим фактором в выборе между ним и Hibernate. В EclipseLink можно было указать атрибуты для загрузки задолго до того, как появился стандарт JPA 2.1. В CUBA существует собственный способ описания графа сущностей, называется CUBA Views (представления CUBA). Представления CUBA — довольно-таки развитый API, можно наследовать одни представления от других, комбинировать их, применяя как к master, так и к detail сущностям. Ещё одна мотивация для создания CUBA представлений — мы хотели использовать короткие транзакции, чтобы можно было работать с открепленными сущностями в пользовательском web-интерфейсе.
В CUBA представления описываются в XML файле, как в примере ниже:

Концепт — CUBA View Interfaces

А что, если все-таки попробовать совместить графы сущностей и проекции? Мы решили попробовать это сделать и разработали интерфейсы для представления сущностей (entity view interfaces), которые повторяют подход из проекций Spring. Эти интерфейсы транслируются в CUBA представления при старте приложения и могут быть использованы в DataManager. Идея проста: описываем интерфейс (или набор интерфейсов), который и представляет из себя граф сущностей.

Стоит отметить, что для каких-то конкретных случаев можно делать локальные интерфейсы, как в случае AddressStreetOnly из примера выше, чтобы не “загрязнять” публичный API своего приложения.

В процессе старта CUBA приложения (бОльшая часть которого — это инициализация контекста Spring), мы программно создаем CUBA представления и помещаем их во внутренний бин — репозиторий в контексте.
Теперь нужно немного изменить имплементацию класса DataManager, чтобы он принимал представления-интерфейсы, и можно делать выборку сущностей вот таким образом:

Под капотом генерируется прокси-объект, который реализует интерфейс и оборачивает экземпляр сущности, выбранный из БД (примерно так же, как это делается в Hibernate). И, когда разработчик обращается за значением атрибута, то прокси делегирует вызов метода “настоящему” экземпляру сущности.

Заметьте, что вычисляемые атрибуты можно вынести из модели классов сущностей и перенести в интерфейсы, применимые к конкретной бизнес логике.

Ещё одна интересная возможность — наследование интерфейсов. Можно сделать несколько представлений с разными наборами атрибутов, а затем их комбинировать. Например, можно создать интерфейс для сущности User с атрибутами name и email, и другой — с атрибутами name и addresses. Теперь, если нужно выбирать name, email и addresses, то не нужно копировать эти атрибуты в третий интерфейс, нужно просто унаследоваться от первых двух представлений. И да, экземпляры третьего интерфейса можно передавать в методы, которые принимают параметры с типом интерфейсов-родителей, правила ООП одинаковы для всех.

Также было реализовано преобразование между представлениями — в каждом интерфейсе есть метод reload(), в который можно передать класс представления в качестве параметра:

Представление UserFullView может содержать дополнительные атрибуты, так что сущность будет загружена заново из БД, если необходимо. И этот процесс — отложенный. Обращение к БД будет произведено только тогда, когда произойдет первое обращение к атрибутам сущности. Это немного замедлит первое обращение, но такой подход был выбран намеренно — если экземпляр сущности используется в модуле “web”, в котором находится UI и собственные REST контроллеры, то этот модуль может быть развернут на отдельном сервере. А это значит, что принудительная перегрузка сущности создаст дополнительный сетевой трафик — обращение к модулю core и затем к БД. Таким образом, откладывая перегрузку до того момента, когда это необходимо, мы экономим трафик и уменьшаем количество запросов к БД.

Концепт оформлен в виде модуля для CUBA, пример использования можно скачать с GitHub.

Заключение

Кажется, что в ближайшем будущем мы все ещё будем массово использовать ORM в энтерпрайз приложениях просто потому, что нам нужно что-то, что будет превращать реляционные данные в объекты. Конечно, для сложных, уникальных, сверхвысоконагруженных приложений будут разрабатываться какие-то специфичные решения, но, похоже, что ORM фреймворки будут жить столько же, сколько реляционные базы данных.
В CUBA мы стараемся упростить работу с ORM по максимуму, и в следующих версиях мы будем вводить новые возможности для работы с данными. Будут ли это интерфейсы-представления или что-то другое — сейчас сложно сказать, но я уверен в одном: мы будем продолжать упрощать работу с данными в следующих версиях фреймворка.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *