ORM OM NOM NOM или тайны ORM в 1С-Битрикс
- О чем и для кого эта статья
- Базовые возможности ORM в 1С-Битрикс: Управление сайтом
- Автоматическая генерация ORM-классов
- Работа с удаленными БД
- Нюансы работы с разными типами БД
- Реальный пример: использование ORM для подключения из PHP к MSSQL в Linux
- Выбор данных из хранимых процедур вместо таблиц
- Выводы
О чем и для кого эта статья
Эта статья – одна из самых популярных страниц нашего сайта. Несколько сотен человек каждый день читают ее. Мы опубликовали важнейшую для мира Битрикс-разработки справочную информацию за полгода до появления официальной документации.Статья будет вам интересна, если Вы уже видели и слышали что-то про 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 и должен переопределять только два метода:
- getTableName для получения имени таблицы;
- getMap для получения массива колонок таблицы — объектов Bitrix\Main\Entity\Field
Хочется похвалить разработчиков за 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.
После перезагрузки страницы имеем следующий код: код в Gist. Результат после небольших преобразований может быть сведен к настоящему классу для работы с шаблонами, расположенному по пути /bitrix/modules/main/lib/sitetemplate.php.
Важная особенность генератора: поля описываются не объектами-потомками Bitrix\Main\Entity\Field, а ассоциативными массивами. Этот формат считается устаревшим, хотя поддерживается и используется во многих системных классах.
Отличное подспорье для создателей модулей: генератор позволит поставить производство классов на поток.
Работа с удаленными БД
Помимо очевидного, есть под капотом ORM и куда более интересные возможности. Например, работа с разными БД (вертикальный шардинг)! Теперь, заканчивая работу по созданию класса никто не мешает сказать “ах да, эта таблица лежит в другой БД с другим логином и паролем”.Никаких ограничений по сравнению с “локальными” таблицами нет. По таблицам внешней БД можно точно так же делать выборки, изменять записи, группировать и т.п. Нельзя только пытаться сделать JOIN таблиц в разных БД.
Чтобы указать, в какой БД требуется искать таблицу, в ORM-классе требуется переопределить метод getConnectionName. Здесь указывается псевдоним подключения (по умолчанию “default” — главное подключение, та же БД, в которую установлены штатные таблицы).
Само подключение должно быть вручную прописано в настройках ядра D7 (файл /bitrix/.settings.php), узел connections > value > имя подключения. Если с host, database, login, password вопросов, в принципе, нет, то первый параметр className заслуживает отдельного внимания. Для этого потребуется сделать небольшое отступление и рассказать об организации работы с БД в новом ядре.
Нюансы работы с разными типами БД
В новом ядре изменилась так же работа с БД. “Главными” по этому вопросу стали классы в пространстве имен Bitrix\Main\DB. Конкретно за подключение к БД и выполнение всех запросов отвечают классы семейства Bitrix\Main\DB\Connection, а именно:- Bitrix\Main\DB\OracleConnection — подключение к Oracle-БД с использованием http://php.net/manual/en/book.oci8.php;
- Bitrix\Main\DB\MssqlConnection — подключение к Microsoft SQL-БД с использованием http://php.net/manual/en/book.sqlsrv.php (расширение доступно только в Windows-версии PHP);
- Bitrix\Main\DB\MysqliConnection — подключение к MySQL через http://php.net/manual/en/book.mysqli.php;
- Bitrix\Main\DB\MysqlConnection — подключение к MySQL через http://php.net/manual/en/book.mysql.php (расширение запрещено с PHP 5.5).
Например, у заказчика чрезвычайно устаревшая (или наоборот, слишком свежая) версия СУБД и невозможно использовать встроенный драйвер для PHP. В таких случаях на помощь спешат, конечно же, программисты.
Чтобы добавить в 1С-Битрикс: Управление сайтом поддержку нового типа БД, необходимо следовать простой инструкции:
- Создать класс подключения (наследник Bitrix\Main\DB\Connection). В нем определить все “базовые” операции с БД: подключение, отключение, выполнение произвольного запроса, работу с транзакциями;
- Создать класс SQL-хелпер (наследник Bitrix\Main\DB\SqlHelper) и возвращать его экземпляр в методе createSqlHelper. Класс предназначен для самой низкоуровневой работы с БД - он добавляет экранирование, работает с датами, предоставляет доступ к базовым SQL-функциям и т.п.;
- Создать класс для результата выборки (наследник Bitrix\Main\DB\Result). В нем требуется определить методы-обертки над традиционными функциями работы с результатом выборки.
Реальный пример: использование ORM для подключения из PHP к MSSQL в Linux
Как уже было отмечено выше, класс Bitrix\Main\DB\MssqlConnection основан на расширении sqlsrv, которое доступно только на windows-сервере. В одном из наших проектов возникла необходимость подключиться к MSSQL с linux-сервера, то есть решение от 1C-Битрикс нам не подходило (а компиляция драйвера в linux ничем хорошим не закончилась). Помогла природная смекалка и знание ООП.На сервер было установлено расширение mssql (http: php.net/manual/ru/book.mssql.php) и была разработана следующая архитектура: Был разработан собственный набор MSSQL-классов, многие методы были унаследованы от стандартных Bitrix\Main\DB\Mssql*. Пришлось буквально в паре десятков мест произвести замены вроде sqlsrv_query => mssql_query. К этому пакету (и способу его получения) вернемся в завершении статьи.
Выбор данных из хранимых процедур вместо таблиц
ORM подходит даже для таких экзотических запросов, как выборка данных не из таблицы, а из хранимых процедур. Такие процедуры могут быть созданы в MSSQL-базе данных. Что ж, попробуем “обмануть” ORM и подсунуть ей процедуру вместо имени таблицы.Укажем название функции в методе 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) и была разработана следующая архитектура:
Где self::isKnownFunctionCall — метод проверки, который возвращает true, если в $identifier находится “foo_table_procedure()”.
Выводы
Новое ядро D7 уже здесь. Каждый месяц появляются все новые и новые классы, они постепенно заменяют старые. Если в Ваших проектах или модулях есть классы, чья ответственность — предоставление доступа к 1 таблице в БД (локальной или сторонней) — требуется его переписать, поставить “на рельсы" одной из ключевых фич в новом 1С-Битрикс: Управлении сайтом.Что касается пакета классов для подключения с linux-сервера к MSSQL БД. Если Вы хотите получить этот пакет (3 класса: MssqlConnection, MssqlSqlHelper, MsssqlResult), поделитесь статьей в социальных сетях и заполните форму в конце страницы. Ссылка для скачивания файлов придёт вам на почту.
Оцените статью
21.01.2016
Понравилась статья?
Поделитесь ссылкой с друзьями и коллегами!
Статьи по теме
Мы работаем по одному из двух форматов:
- аренда команды (от 2 человек, не менее 3 месяцев);
- итерации с фиксированной ценой (1-3 месяца длительностью).
ИНТЕРВОЛГА предоставляет:
- регулярные онлайн-планерки с заказчиком;
- квалифицированных специалистов;
- организованную команду (находятся в одном помещении, что упрощает решение рабочих вопросов);
- полную прозрачность и регулярность отчетов о результатах.
Ключевые услуги:
- нагруженный интернет-магазин;
- личный кабинет;
- оптовые продажи — B2B-платформа;
- маркетплейс;
- технический аудит сайта;
- Битрикс24 — корпоративные HR-порталы;
- Битрикс24 — построение CRM-системы;
- Битрикс24 — личные кабинеты сотрудников;
- Битрикс24 — аудит портала;
- 1С — интеграция с другими системами;
- 1С — доработка системы;
- маркетинг — комплексное интернет-продвижение;
- маркетинг — продвижение для B2B.
Хотите получать лучшие статьи от INTERVOLGA раз в месяц?
Подпишитесь на рассылку — спамить не будем