ORM (Object-Relational Mapping) в Битрикс D7 — это слой для работы с базой данных без написания SQL. Вместо raw-запросов вы описываете структуру таблиц в классах и работаете через типизированный API.
Создание ORM-класса
namespace MyModule;
use Bitrix\Main\ORM\Data\DataManager;
use Bitrix\Main\ORM\Fields;
class OrderLogTable extends DataManager
{
public static function getTableName(): string
{
return 'b_my_order_log';
}
public static function getMap(): array
{
return [
new Fields\IntegerField('ID', [
'primary' => true,
'autocomplete'=> true,
]),
new Fields\IntegerField('ORDER_ID', [
'required' => true,
]),
new Fields\StringField('ACTION', [
'required' => true,
'validation'=> function() {
return [new Fields\Validators\LengthValidator(1, 255)];
},
]),
new Fields\DatetimeField('DATE_CREATE', [
'default_value' => function() {
return new \Bitrix\Main\Type\DateTime();
},
]),
new Fields\TextField('COMMENT'),
];
}
}
Создание таблицы
// При установке модуля создаём таблицу
$connection = \Bitrix\Main\Application::getInstance()->getConnection();
if (!$connection->isTableExists(OrderLogTable::getTableName())) {
OrderLogTable::getEntity()->createDbTable();
}
CRUD через ORM
// Добавление
$result = OrderLogTable::add([
'ORDER_ID' => 42,
'ACTION' => 'status_changed',
'COMMENT' => 'Статус изменён на "Доставлен"',
]);
// Выборка с фильтром
$rows = OrderLogTable::getList([
'select' => ['ID', 'ORDER_ID', 'ACTION', 'DATE_CREATE'],
'filter' => [
'=ORDER_ID' => 42,
'>=DATE_CREATE' => (new \Bitrix\Main\Type\DateTime())->add('T-24H'),
],
'order' => ['DATE_CREATE' => 'DESC'],
'limit' => 50,
])->fetchAll();
// Обновление
OrderLogTable::update(15, ['COMMENT' => 'Обновлённый комментарий']);
// Удаление
OrderLogTable::delete(15);
Связи между таблицами
// В getMap() добавляем Reference
new Fields\Relations\Reference(
'ORDER',
\Bitrix\Sale\Internals\OrderTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.ORDER_ID', 'ref.ID')
),
// Теперь можно выбирать данные заказа вместе с логом
$rows = OrderLogTable::getList([
'select' => ['ID', 'ACTION', 'ORDER__ACCOUNT_NUMBER', 'ORDER__DATE_INSERT'],
'filter' => ['=ORDER.STATUS_ID' => 'N'],
])->fetchAll();
Query Builder для сложных запросов
use Bitrix\Main\ORM\Query\Query;
$query = OrderLogTable::query()
->setSelect(['ORDER_ID', new Fields\ExpressionField('CNT', 'COUNT(%s)', 'ID')])
->setFilter(['>=DATE_CREATE' => (new \Bitrix\Main\Type\DateTime())->add('T-7D')])
->setGroup(['ORDER_ID'])
->setOrder(['CNT' => 'DESC'])
->setLimit(10);
$result = $query->exec()->fetchAll();
// [['ORDER_ID' => 42, 'CNT' => 15], ...]
Транзакции
$connection = \Bitrix\Main\Application::getInstance()->getConnection();
$connection->startTransaction();
try {
OrderLogTable::add(['ORDER_ID' => 1, 'ACTION' => 'created']);
// другие операции
$connection->commitTransaction();
} catch (\Exception $e) {
$connection->rollbackTransaction();
throw $e;
}
Итог
ORM Битрикс D7 — мощный инструмент когда нужна типизация и связи. Для простых CRUD операций он удобнее raw SQL. Для очень сложных аналитических запросов лучше писать SQL напрямую через $connection->query().
