ORM OM NOM NOM или тайны ORM в 1С-Битрикс

Алексей Шкарупа
Анатолий Ерофеев
Подписаться
cookie monster

О чем и для кого эта статья

Эта статья – одна из самых популярных страниц нашего сайта. Несколько сотен человек каждый день читают ее. Мы опубликовали важнейшую для мира Битрикс-разработки справочную информацию за полгода до появления официальной документации.

Статья будет вам интересна, если Вы уже видели и слышали что-то про ORM в 1С-Битрикс: Управление сайтом, и даже пробовали разрабатывать сайты на 1С-Битрикс с собственными ORM-классами. Статья состоит из трех частей:
  • Краткое напоминание о базовых возможностях ORM в БУС;
  • Генератор ORM-классов;
  • Подробно про работу ORM c БД. Реальный случай из практики: использование ORM для подключения из linux’а к MSSQL БД и выбора данных из хранимых процедур вместо таблиц.

Базовые возможности ORM в 1С-Битрикс: Управление сайтом

Согласно SRP, каждый класс в программе должен иметь только одну обязанность. Например: работа с форматом валют, работа с языковым пакетом, работа с настройками приложения.

В такой серьезной системе, как 1С-Битрикс: Управление сайтом классов и обязанностей должно быть немало. Моя IDE подсказывает, что в Интернет-магазине версии 16.0.1 объявлено 2759 классов. Я точно уверен, что самая многочисленная “группа” — классы для работы с таблицами в БД. CIBlockElement для работы с таблицей b_iblock_element (элементы инфоблоков), CSaleOrder для таблицы b_sale_order (заказы), CUser для работы с b_user (пользователи) и т.д. В БД сейчас 413 таблиц. Выходит, должно быть 413 классов для работы с каждой из них.

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

Более того, несмотря на общее название, эти методы вполне могли работать по-разному. вспомните 3 метода, имеющих одинаковое название:
Пожалуй, только опытный программист сможет сходу назвать особенности их применения без подглядывания в справку. А ведь есть еще такие острые вопросы, как добавление в БД, обработка ошибок и т.п. И, зачастую, каждый класс решает “сам за себя”.

Но сейчас ситуация меняется. Появилось новое ядро D7, с новыми идеями, механизмами и концепциями. Поговорим об одной из них, краеугольной - ORM (Object Relation Model). Об ORM подробно рассказывают в блоге разработчиков и есть отличное руководство в документации. Постараюсь не повторяться и буду считать, что вы уже написали пару ORM-классов, ориентируясь на эти статьи.

Я выделю только основное. Если класс отвечает за доступ к таблице БД, он должен быть наследником класса Bitrix\Main\Entity\DataManager и должен переопределять только два метода:
  1. getTableName для получения имени таблицы;
  2. getMap для получения массива колонок таблицы — объектов Bitrix\Main\Entity\Field
Метод getFilePath, который упоминается в блоге, больше не является обязательным!
объекты Bitrix\Main\Entity Хочется похвалить разработчиков за ORM. Это не просто слова и планы на будущее. На момент написания этого текста (декабрь 2015) переведено на “новые рельсы” 215 классов. То есть, больше половины всех классов для работы с БД уже имеют D7-аналоги и используются.

Выводы по базовым возможностям ORM в 1С-Битрикс: УС. У нас появился очень мощный API для работы с БД с правильной современной архитектурой. Стоит незамедлительно переводить все свои старые классы на “ORM-рельсы”. Руководство по разработке этих классов достаточно подробное и отвечает на главные вопросы.

Автоматическая генерация ORM-классов

Первое, о чем хочется рассказать в этой статье об ORM — генератор ORM классов. По неизвестной мне причине он тщательно скрыт в недрах панели управления сайтом. Когда пользуешься им, возникает ощущение, что прикасаешься к чему-то запретному :) Хотя в среде разработчиков о нем часто говорят: и на сайте идей, и в блогах.

Чтобы его использовать, нужно открыть страницу Настройки > Производительность > Таблицы и добавить GET-параметр orm=y. Адрес будет выглядеть так: /bitrix/admin/perfmon_tables.php?lang=ru&orm=y

После этого для любой таблицы в БД сайта можно автоматически создавать ORM-класс. Для примера выберем штатную таблицу шаблонов сайта b_site_template.
Автоматическое создание ORM-классов После перезагрузки страницы имеем следующий код: код в Gist. Результат после небольших преобразований может быть сведен к настоящему классу для работы с шаблонами, расположенному по пути /bitrix/modules/main/lib/sitetemplate.php.

Важная особенность генератора: поля описываются не объектами-потомками Bitrix\Main\Entity\Field, а ассоциативными массивами. Этот формат считается устаревшим, хотя поддерживается и используется во многих системных классах.

Отличное подспорье для создателей модулей: генератор позволит поставить производство классов на поток.

Работа с удаленными БД

Помимо очевидного, есть под капотом ORM и куда более интересные возможности. Например, работа с разными БД (вертикальный шардинг)! Теперь, заканчивая работу по созданию класса никто не мешает сказать “ах да, эта таблица лежит в другой БД с другим логином и паролем”.

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

Чтобы указать, в какой БД требуется искать таблицу, в ORM-классе требуется переопределить метод getConnectionName. Здесь указывается псевдоним подключения (по умолчанию “default” — главное подключение, та же БД, в которую установлены штатные таблицы).
метод getConnectionName Само подключение должно быть вручную прописано в настройках ядра D7 (файл /bitrix/.settings.php), узел connections > value > имя подключения. узел connections > value > Если с host, database, login, password вопросов, в принципе, нет, то первый параметр className заслуживает отдельного внимания. Для этого потребуется сделать небольшое отступление и рассказать об организации работы с БД в новом ядре.

Нюансы работы с разными типами БД

В новом ядре изменилась так же работа с БД. “Главными” по этому вопросу стали классы в пространстве имен Bitrix\Main\DB. Конкретно за подключение к БД и выполнение всех запросов отвечают классы семейства Bitrix\Main\DB\Connection, а именно:
Наверное, для 95% сайтов хватает этого набора (а для 90% только Bitrix\Main\DB\MysqliConnection). А что же делать, если подключение к БД очень экзотическое?

Например, у заказчика чрезвычайно устаревшая (или наоборот, слишком свежая) версия СУБД и невозможно использовать встроенный драйвер для PHP. В таких случаях на помощь спешат, конечно же, программисты.

Чтобы добавить в 1С-Битрикс: Управление сайтом поддержку нового типа БД, необходимо следовать простой инструкции:
  1. Создать класс подключения (наследник Bitrix\Main\DB\Connection). В нем определить все “базовые” операции с БД: подключение, отключение, выполнение произвольного запроса, работу с транзакциями;
  2. Создать класс SQL-хелпер (наследник Bitrix\Main\DB\SqlHelper) и возвращать его экземпляр в методе createSqlHelper. Класс предназначен для самой низкоуровневой работы с БД - он добавляет экранирование, работает с датами, предоставляет доступ к базовым SQL-функциям и т.п.;
  3. Создать класс для результата выборки (наследник Bitrix\Main\DB\Result). В нем требуется определить методы-обертки над традиционными функциями работы с результатом выборки.
Bitrix\Main\DB Теперь вы знаете, какие className можно указывать в /bitrix/.settings.php и как создавать собственные подключения к БД.

Реальный пример: использование ORM для подключения из PHP к MSSQL в Linux

Как уже было отмечено выше, класс Bitrix\Main\DB\MssqlConnection основан на расширении sqlsrv, которое доступно только на windows-сервере. В одном из наших проектов возникла необходимость подключиться к MSSQL с linux-сервера, то есть решение от 1C-Битрикс нам не подходило (а компиляция драйвера в linux ничем хорошим не закончилась). Помогла природная смекалка и знание ООП.

На сервер было установлено расширение mssql (http: php.net/manual/ru/book.mssql.php) и была разработана следующая архитектура: Bitrix\Main\DB\MssqlConnection Был разработан собственный набор MSSQL-классов, многие методы были унаследованы от стандартных Bitrix\Main\DB\Mssql*. Пришлось буквально в паре десятков мест произвести замены вроде sqlsrv_query => mssql_query. К этому пакету (и способу его получения) вернемся в завершении статьи.

Выбор данных из хранимых процедур вместо таблиц

ORM подходит даже для таких экзотических запросов, как выборка данных не из таблицы, а из хранимых процедур. Такие процедуры могут быть созданы в MSSQL-базе данных. Что ж, попробуем “обмануть” ORM и подсунуть ей процедуру вместо имени таблицы.

Укажем название функции в методе getTableName.
метод getTableName Однако, сразу такой код работать не будет. Дело в том, что при использовании подключения Bitrix\Main\DB\MssqlConnection все вхождения имен таблиц проходят через экранирование. Попытка сразу выполнить такой запрос приведет к выбрасыванию исключения:

MS Sql query error: Invalid object name 'foo_table_procedure()'. (400)

SELECT

[base].[bar] AS [BAR],

[base].[baz] AS [BAZ],

FROM [foo_table_procedure()] [base]


Увы, не получилось. На самом деле, мы в одном шаге от успеха, помешали только знаки “[“ и “]”, которыми MssqlSqlHelper защитил имя используемой “таблицы”. Проблема решается “в лоб” созданием собственного подключения (Connection) и SqlHelper’а.

На сервер было установлено расширение mssql (http: php.net/manual/ru/book.mssql.php) и была разработана следующая архитектура:
Расширение mssql Где self::isKnownFunctionCall — метод проверки, который возвращает true, если в $identifier находится “foo_table_procedure()”.

Выводы

Новое ядро D7 уже здесь. Каждый месяц появляются все новые и новые классы, они постепенно заменяют старые. Если в Ваших проектах или модулях есть классы, чья ответственность — предоставление доступа к 1 таблице в БД (локальной или сторонней) — требуется его переписать, поставить “на рельсы" одной из ключевых фич в новом 1С-Битрикс: Управлении сайтом.

Что касается пакета классов для подключения с linux-сервера к MSSQL БД. Если Вы хотите получить этот пакет (3 класса: MssqlConnection, MssqlSqlHelper, MsssqlResult), поделитесь статьей в социальных сетях и заполните форму в конце страницы. Ссылка для скачивания файлов придёт вам на почту.
Оцените статью
21.01.2016
Понравилась статья?
Поделитесь ссылкой с друзьями и коллегами!

Статьи по теме

23.06.2022
Увеличение скорости обновления информации в 100 раз за счет миграции данных из самописного хранилища на базе СУБД PostgreSQL Ранее мы уже описывали архитектуру мультиязычного сайта с большим количеством иностранных дилеров для компании Levenhuk. В этой статье рассказываем, как реш...
23.05.2022
Как увеличить конверсию интернет-магазина обуви до 3.9% Вступление Начну с конца. Вот таких показателей мы достигли: начинали с таких: Если интрига сработала, и вопрос “Как увеличить конверсию интернет-...
18.05.2022
Обмен контрагентами между 1С и сайтом с сохранением структуры Партнеров, Контрагентов, Юридических лиц и Контактов O чем речь? Мы сделали B2B-Платформу для предприятий с партнерами-оптовиками и задачами автоматизации торговли. Некоторые Пользовательские сц...
18.05.2022
Чат-бот Программы Лояльности в TelegramЛояльность клиентов — важный показатель в деятельности любой организации. Чтобы покупатель оставался доволен продукцией, важно внимание и забота со стороны комп...
13.05.2022
Кейс: Личный кабинет партнера крупнейшего поставщика медицинских изделий В 2019 году к нам обратилась крупная компания, занимающаяся поставкой медицинских изделий. Причина обращения была типична для бизнеса, работающего с крупно...
06.05.2022
Топ-7 платформ автоматизации оптовой торговли - Выбор лучшейЭта статья будет полезна владельцам бизнеса, коммерческим директорам, а также руководителям отделов по оптовой торговле оборудованием, материалам и продукцией ...

Мы работаем по одному из двух форматов:

  • аренда команды (от 2 человек, не менее 3 месяцев);
  • итерации с фиксированной ценой (1-3 месяца длительностью).

ИНТЕРВОЛГА предоставляет:

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

Для доработок и развития мы предлагаем формат 100 часов в месяц. Что можно сделать за это время:

  • новые нетиповые страницы или раздел;
  • 2 отчета с индивидуальными настройками;
  • 3-5 веб-сервисов интеграции;
  • замудренный калькулятор и т.п.

Поддержка «чтобы все работало как часы» стоит 45 тысяч рублей в месяц и описана тут.

Хочешь получать лучшие статьи от INTERVOLGA раз в месяц?
Подпишись на рассылку — спамить не будем