Открыть сервис

ORM Bitrix Framework

ORM Bitrix Framework — это объектно-реляционное отображение (ORM), встроенное в систему управления веб-контентом «1С-Битрикс: Управление сайтом». Оно предоставляет разработчикам унифицированный интерфейс для взаимодействия с таблицами базы данных через объекты и классы, абстрагируя прямые SQL-запросы. ORM Bitrix является частью ядра продукта и доступно для использования начиная с версии главного модуля 14.0.0 (выпуск 2014 года).

История и предпосылки создания

До внедрения ORM работа с данными в «1С-Битрикс» велась преимущественно через устаревшие функции API, такие как CModule::IncludeModule(), CIBlockElement::GetList(), CUser::GetList() и другие. Эти функции возвращали массивы данных, а для фильтрации, сортировки и выборки использовались ассоциативные массивы параметров (например, ['filter' => ['=ID' => 1], 'select' => ['ID', 'NAME']]). Такой подход был функциональным, но имел ряд недостатков:

  • Отсутствие строгой типизации и автодополнения в IDE.
  • Сложность построения сложных запросов с JOIN, подзапросами и агрегатными функциями.
  • Трудности с тестированием и рефакторингом кода.
  • Разрозненность API для разных модулей (инфоблоки, пользователи, заказы и т.д.).

В 2014 году компания «1С-Битрикс» анонсировала и выпустил новую архитектуру ядра — D7 (название происходит от папки bitrix/modules/main/lib/). В рамках этой архитектуры и был реализован ORM, который стал частью модуля main. Основной целью было создание единого, современного, типобезопасного и расширяемого способа работы с данными, соответствующего стандартам PHP 5.4+ и принципам SOLID.

Архитектура и основные компоненты

ORM Bitrix построен на основе паттерна Data Mapper. Он разделяет бизнес-логику (сущности) и логику работы с базой данных (мапперы). Ключевыми компонентами являются:

Сущность (Entity)

Сущность — это класс, описывающий структуру таблицы базы данных. Он определяет поля, их типы, связи с другими сущностями, а также методы для выборки данных. Все сущности наследуются от класса \Bitrix\Main\ORM\Data\DataManager или его потомков (Entity\DataManager). Для каждой таблицы обычно создаётся свой класс сущности.

Поля (Fields)

Поля представляют собой колонки таблицы. Каждое поле описывается объектом класса, реализующего интерфейс \Bitrix\Main\ORM\Fields\Field. Типы полей включают:

  • IntegerField — целое число.
  • StringField — строка.
  • TextField — текст (большой объём).
  • FloatField — число с плавающей точкой.
  • BooleanField — логическое значение (true/false).
  • DatetimeField — дата и время.
  • DateField — дата.
  • EnumField — перечисление (список допустимых значений).
  • ReferenceField — поле для связи с другой сущностью (аналог внешнего ключа).

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

Таблица (Table)

Класс сущности содержит статический метод getTableName(), который возвращает имя таблицы в базе данных. ORM автоматически генерирует SQL-запросы на основе имени таблицы и определённых полей.

Класс Query

Основной инструмент для построения запросов. Он предоставляет цепочку методов (fluent interface) для формирования условий выборки, сортировки, группировки, ограничения количества записей и связывания таблиц. Примеры методов:

  • setSelect(array $fields) — какие поля выбрать.
  • setFilter(array $filter) — условия фильтрации.
  • setOrder(array $order)сортировка.
  • setGroup(array $group) — группировка.
  • setLimit(int $limit) — количество записей.
  • setOffset(int $offset) — смещение.
  • registerRuntimeField() — добавление вычисляемых полей.
  • addSelect() — добавление поля в выборку.

Результат запроса (Result)

Результатом выполнения запроса является объект класса \Bitrix\Main\ORM\Query\Result (или его наследников). Он предоставляет методы для итерации по записям (fetch(), fetchAll()), получения количества записей (getSelectedRowsCount()), а также для доступа к объектам сущностей.

Основные операции

Создание (Add)

Для добавления новой записи используется статический метод add() класса сущности. Он принимает массив данных, ключи которого соответствуют названиям полей, и возвращает объект \Bitrix\Main\ORM\Data\AddResult, содержащий идентификатор новой записи и возможные ошибки валидации.

``php $result = \Bitrix\Main\GroupTable::add([ 'NAME' => 'Новая группа', 'DESCRIPTION' => 'Описание группы' ]); if ($result->isSuccess()) { $groupId = $result->getId(); } ``

Обновление (Update)

Для обновления записи используется метод update(), который принимает первичный ключ (обычно ID) и массив обновляемых данных. Возвращает объект \Bitrix\Main\ORM\Data\UpdateResult.

``php \Bitrix\Main\GroupTable::update($groupId, [ 'NAME' => 'Изменённое название' ]); ``

Удаление (Delete)

Удаление записи выполняется методом delete() с указанием первичного ключа. Возвращает объект \Bitrix\Main\ORM\Data\DeleteResult.

``php \Bitrix\Main\GroupTable::delete($groupId); ``

Выборка (GetList)

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

```php // Через массив параметров $result = \Bitrix\Main\GroupTable::getList([ 'select' => ['ID', 'NAME', 'TIMESTAMP_X'], 'filter' => ['=ID' => 1], 'order' => ['ID' => 'ASC'] ]);

// Через объект Query $query = new \Bitrix\Main\ORM\Query\Query(\Bitrix\Main\GroupTable::getEntity()); $query->setSelect(['ID', 'NAME']); $query->setFilter(['=ID' => 1]); $result = $query->exec();

while ($row = $result->fetch()) { echo $row['NAME']; } ```

Связи между сущностями

ORM Bitrix поддерживает несколько типов связей, реализуемых через поле ReferenceField:

Один к одному (One-to-One)

Связь, при которой одна запись в таблице A соответствует одной записи в таблице B. Реализуется через ReferenceField с указанием условия join.

Один ко многим (One-to-Many)

Связь, при которой одна запись в таблице A соответствует нескольким записям в таблице B. В ORM Bitrix это реализуется через ReferenceField с указанием обратной связи, либо через отдельный метод getRefClass().

Многие ко многим (Many-to-Many)

Связь, при которой несколько записей в таблице A могут соответствовать нескольким записям в таблице B. Для этого используется промежуточная таблица (связка). В ORM Bitrix такая связь реализуется через два ReferenceField — один на основную таблицу, другой на связующую.

Преимущества и недостатки

Преимущества

  • Типобезопасность: IDE предоставляет автодополнение для полей сущностей, что снижает количество ошибок.
  • Унификация: единый интерфейс для всех модулей системы.
  • Гибкость: возможность построения сложных запросов с JOIN, подзапросами, агрегатными функциями и вычисляемыми полями.
  • Расширяемость: разработчики могут создавать собственные сущности, наследуясь от DataManager.
  • Поддержка событий: ORM генерирует события (OnBeforeAdd, OnAfterUpdate и т.д.), что позволяет внедрять дополнительную логику.
  • Кэширование: встроенные механизмы кэширования результатов запросов.

Недостатки

  • Сложность: для простых запросов ORM может быть избыточным, требуя больше кода, чем устаревшие функции.
  • Производительность: при работе с большими объёмами данных ORM может генерировать неоптимальные SQL-запросы, особенно при использовании сложных связей.
  • Ограничения: не все возможности SQL (например, оконные функции, FULLTEXT-поиск) доступны через ORM без написания прямых запросов.
  • Зависимость от ядра: ORM является частью продукта «1С-Битрикс», поэтому его использование вне экосистемы невозможно.

Примеры использования

Создание собственной сущности

Для работы с произвольной таблицей необходимо создать класс, наследующий DataManager, и определить метод getMap().

```php namespace My\Module;

use Bitrix\Main\ORM\Data\DataManager; use Bitrix\Main\ORM\Fields\IntegerField; use Bitrix\Main\ORM\Fields\StringField; use Bitrix\Main\ORM\Fields\Validators\LengthValidator;

class MyTable extends DataManager { public static function getTableName() { return 'my_table'; }

public static function getMap() { return [ new IntegerField('ID', [ 'primary' => true, 'autocomplete' => true ]), new StringField('TITLE', [ 'required' => true, 'validation' => function() { return [new LengthValidator(1, 255)]; } ]), new StringField('DESCRIPTION') ]; } } ```

Сложный запрос с JOIN

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

```php use Bitrix\Main\GroupTable; use Bitrix\Main\UserTable;

$query = new \Bitrix\Main\ORM\Query\Query(UserTable::getEntity()); $query->setSelect([ 'ID', 'LOGIN', 'NAME', 'GROUP_NAME' => 'GROUP.NAME' // Связь через ReferenceField ]); $query->registerRuntimeField( new \Bitrix\Main\ORM\Fields\Relations\Reference( 'GROUP', GroupTable::getEntity(), ['=this.GROUP_ID' => 'ref.ID'] ) ); $result = $query->exec(); ```

Заключение

ORM Bitrix Framework является ключевым компонентом современной архитектуры «1С-Битрикс». Он предоставляет разработчикам мощный и гибкий инструмент для работы с данными, соответствующий современным стандартам веб-разработки. Несмотря на некоторые недостатки, связанные с производительностью и сложностью, ORM значительно упрощает разработку, поддержку и тестирование кода, особенно в крупных проектах. Его использование рекомендуется для всех новых модулей и компонентов, а также для рефакторинга устаревшего кода.

Источники

  1. Документация «1С-Битрикс: Управление сайтом» — раздел «ORM (D7)».
  2. Код ядра продукта «1С-Битрикс» (версия 14.0.0 и выше).
  3. Статья «Новое ядро D7 в 1С-Битрикс» на официальном сайте разработчиков.
  4. Книга «Разработка на 1С-Битрикс: от новичка до профессионала» (автор — Дмитрий Кузнецов).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →