Битрикс ORM к своим таблицам

 <?php

 namespace Helper\Orm;

 use Bitrix\Main,
    Bitrix\Main\Localization\Loc;

 Loc::loadMessages(__FILE__);

 /**
  * Class SectionUfTable
  *
  * Fields:
  * <ul>
  * <li> ID int mandatory
  * <li> UF_NAME string optional
  * <li> UF_HREF string optional
  * </ul>
  *
  * @package Bitrix\SectionUfTable
  **/
 class SectionUfTable extends Main\Entity\DataManager
 {
    /**
     * Returns DB table name for entity.
     *
     * @return string
     */
    public static function getTableName()
    {
        return 'b_utm_iblock_7_section';
    }

    /**
     * Returns entity map definition.
     *
     * @return array
     */
    public static function getMap()
    {
        return [
            'ID' => [
                'data_type' => 'integer',
                'primary' => true,
                'autocomplete' => true,
                'title' => 'id',
            ],
            'VALUE_ID' => [
                'data_type' => 'integer',
                'title' => 'valueId',
            ],
            'FIELD_ID' => [
                'data_type' => 'integer',
                'title' => 'fieldId',
            ],
            'VALUE' => [
                'data_type' => 'text',
                'title' => 'valueText',
            ],
        ];
    }

 }

Для получения заготовки класса из админ. части Битрикс, нужно в Настройки > Настройки продукта > Настройки модулей > Монитор производительности на вкладке “Генератор таблетов“ установить галку “Разрешить генерацию таблетов для ORM

После этого в Настройки > Производительность > Таблицы будет доступен GET параметр orm=y

или


МОЖЕТ БЫТЬ ПОЛЕЗНО


Если класс отвечает за доступ к таблице БД, он должен быть наследником класса Bitrix\Main\Entity\DataManager и должен переопределять только два метода:

  1. getTableName для получения имени таблицы;

  2. getMap для получения массива колонок таблицы — объектов Bitrix\Main\Entity\Field

    Метод getFilePath, который упоминается в блоге, больше не является обязательным!


    БОЛЕЕ ПОДРОБНО


    Реализация ORM в ядре D7 призвана абстрагировать разработчика от механики работы с таблицами на уровне запросов к БД, введя понятие сущности и поля сущности.

    • Cущность в терминах битрикса, это таблица

    • Поля сущности столбцы или ссылки на другие сущности

    • Датаменеджер система управления данными

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

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

  4. Если в папочке bitrix не удалось найти класс, значит его нужно сгенерировать, как это сделать автоматически написано ниже в статье

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

  6. Пишем необходимые запросы используя API bitrix и обрабатываем их

    Из чего состоит класс

    В классе обязательно должны быть два метода:

    • getMap() перечисляются все поля таблицы

    • getTableName() указывается название базы данных

    Пример класса через который можно работать с таблицей b_iblock:

    /bitrix/modules/iblock/lib/element.php<?
    namespace Bitrix\Iblock;
    
    use Bitrix\Main\Localization\Loc,
    Bitrix\Main\ORM\Data\DataManager,
    Bitrix\Main\ORM\Fields,
    Bitrix\Main\Type;
    
    Loc::loadMessages(__FILE__);
    
    /**
    * Class IblockTable
    * 
    * Fields:
    * <ul>
    * <li> ID int mandatory
    * <li> TIMESTAMP_X datetime optional default current datetime
    * <li> IBLOCK_TYPE_ID string(50) mandatory
    * <li> LID string(2) mandatory
    * <li> CODE string(50) optional
    * <li> API_CODE string(50) optional
    * <li> REST_ON bool ('N', 'Y') optional default 'N'
    * <li> NAME string(255) mandatory
    * <li> ACTIVE bool ('N', 'Y') optional default 'Y'
    * <li> SORT int optional default 500
    * <li> LIST_PAGE_URL string(255) optional
    * <li> DETAIL_PAGE_URL string(255) optional
    * <li> SECTION_PAGE_URL string(255) optional
    * <li> CANONICAL_PAGE_URL string(255) optional
    * <li> PICTURE int optional
    * <li> DESCRIPTION text optional
    * <li> DESCRIPTION_TYPE enum ('text', 'html') optional default 'text'
    * <li> RSS_TTL int optional default 24
    * <li> RSS_ACTIVE bool ('N', 'Y') optional default 'Y'
    * <li> RSS_FILE_ACTIVE bool ('N', 'Y') optional default 'N'
    * <li> RSS_FILE_LIMIT int optional
    * <li> RSS_FILE_DAYS int optional
    * <li> RSS_YANDEX_ACTIVE bool ('N', 'Y') optional default 'N'
    * <li> XML_ID string(255) optional
    * <li> TMP_ID string(40) optional
    * <li> INDEX_ELEMENT bool ('N', 'Y') optional default 'Y'
    * <li> INDEX_SECTION bool ('N', 'Y') optional default 'N'
    * <li> WORKFLOW bool ('N', 'Y') optional default 'Y'
    * <li> BIZPROC bool ('N', 'Y') optional default 'N'
    * <li> SECTION_CHOOSER string(1) optional
    * <li> LIST_MODE string(1) optional
    * <li> RIGHTS_MODE string(1) optional
    * <li> SECTION_PROPERTY string(1) optional
    * <li> PROPERTY_INDEX string(1) optional
    * <li> VERSION int optional default 1
    * <li> LAST_CONV_ELEMENT int optional default 0
    * <li> SOCNET_GROUP_ID int optional
    * <li> EDIT_FILE_BEFORE string(255) optional
    * <li> EDIT_FILE_AFTER string(255) optional
    * <li> SECTIONS_NAME string(100) optional
    * <li> SECTION_NAME string(100) optional
    * <li> ELEMENTS_NAME string(100) optional
    * <li> ELEMENT_NAME string(100) optional
    * <li> PICTURE reference to {@link \Bitrix\File\FileTable}
    * <li> IBLOCK_TYPE_ID reference to {@link \Bitrix\Iblock\IblockTypeTable}
    * <li> LID reference to {@link \Bitrix\Lang\LangTable}
    * <li> SOCNET_GROUP_ID reference to {@link \Bitrix\Sonet\SonetGroupTable}
    * </ul>
    *
    * @package Bitrix\Iblock
    **/
    
    class IblockTable extends DataManager
    {
    /**
    * Returns DB table name for entity.
    *
    * @return string
    */
    public static function getTableName()
    {
    return 'b_iblock';
    }
    
    /**
    * Returns entity map definition.
    *
    * @return array
    */
    public static function getMap()
    {
    return [
      new Fields\IntegerField(
        'ID',
        [
          'primary' => true,
          'autocomplete' => true,
          'title' => Loc::getMessage('IBLOCK_ENTITY_ID_FIELD')
        ]
      ),
      new Fields\DatetimeField(
        'TIMESTAMP_X',
        [
          'default' => function()
          {
            return new Type\DateTime();
          },
          'title' => Loc::getMessage('IBLOCK_ENTITY_TIMESTAMP_X_FIELD')
        ]
      ),
      new Fields\StringField(
        'IBLOCK_TYPE_ID',
        [
          'required' => true,
          'validation' => [__CLASS__, 'validateIblockTypeId'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_IBLOCK_TYPE_ID_FIELD')
        ]
      ),
      new Fields\StringField(
        'LID',
        [
          'required' => true,
          'validation' => [__CLASS__, 'validateLid'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_LID_FIELD')
        ]
      ),
      new Fields\StringField(
        'CODE',
        [
          'validation' => [__CLASS__, 'validateCode'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_CODE_FIELD')
        ]
      ),
      new Fields\StringField(
        'API_CODE',
        [
          'validation' => [__CLASS__, 'validateApiCode'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_API_CODE_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'REST_ON',
        [
          'values' => array('N', 'Y'),
          'default' => 'N',
          'title' => Loc::getMessage('IBLOCK_ENTITY_REST_ON_FIELD')
        ]
      ),
      new Fields\StringField(
        'NAME',
        [
          'required' => true,
          'validation' => [__CLASS__, 'validateName'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_NAME_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'ACTIVE',
        [
          'values' => array('N', 'Y'),
          'default' => 'Y',
          'title' => Loc::getMessage('IBLOCK_ENTITY_ACTIVE_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'SORT',
        [
          'default' => 500,
          'title' => Loc::getMessage('IBLOCK_ENTITY_SORT_FIELD')
        ]
      ),
      new Fields\StringField(
        'LIST_PAGE_URL',
        [
          'validation' => [__CLASS__, 'validateListPageUrl'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_PAGE_URL_FIELD')
        ]
      ),
      new Fields\StringField(
        'DETAIL_PAGE_URL',
        [
          'validation' => [__CLASS__, 'validateDetailPageUrl'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_DETAIL_PAGE_URL_FIELD')
        ]
      ),
      new Fields\StringField(
        'SECTION_PAGE_URL',
        [
          'validation' => [__CLASS__, 'validateSectionPageUrl'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PAGE_URL_FIELD')
        ]
      ),
      new Fields\StringField(
        'CANONICAL_PAGE_URL',
        [
          'validation' => [__CLASS__, 'validateCanonicalPageUrl'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_CANONICAL_PAGE_URL_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'PICTURE',
        [
          'title' => Loc::getMessage('IBLOCK_ENTITY_PICTURE_FIELD')
        ]
      ),
      new Fields\TextField(
        'DESCRIPTION',
        [
          'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_FIELD')
        ]
      ),
      new Fields\StringField(
        'DESCRIPTION_TYPE',
        [
          'values' => array('text', 'html'),
          'default' => 'text',
          'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_TYPE_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'RSS_TTL',
        [
          'default' => 24,
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_TTL_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'RSS_ACTIVE',
        [
          'values' => array('N', 'Y'),
          'default' => 'Y',
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_ACTIVE_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'RSS_FILE_ACTIVE',
        [
          'values' => array('N', 'Y'),
          'default' => 'N',
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_ACTIVE_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'RSS_FILE_LIMIT',
        [
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_LIMIT_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'RSS_FILE_DAYS',
        [
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_DAYS_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'RSS_YANDEX_ACTIVE',
        [
          'values' => array('N', 'Y'),
          'default' => 'N',
          'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_YANDEX_ACTIVE_FIELD')
        ]
      ),
      new Fields\StringField(
        'XML_ID',
        [
          'validation' => [__CLASS__, 'validateXmlId'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_XML_ID_FIELD')
        ]
      ),
      new Fields\StringField(
        'TMP_ID',
        [
          'validation' => [__CLASS__, 'validateTmpId'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_TMP_ID_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'INDEX_ELEMENT',
        [
          'values' => array('N', 'Y'),
          'default' => 'Y',
          'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_ELEMENT_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'INDEX_SECTION',
        [
          'values' => array('N', 'Y'),
          'default' => 'N',
          'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_SECTION_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'WORKFLOW',
        [
          'values' => array('N', 'Y'),
          'default' => 'Y',
          'title' => Loc::getMessage('IBLOCK_ENTITY_WORKFLOW_FIELD')
        ]
      ),
      new Fields\BooleanField(
        'BIZPROC',
        [
          'values' => array('N', 'Y'),
          'default' => 'N',
          'title' => Loc::getMessage('IBLOCK_ENTITY_BIZPROC_FIELD')
        ]
      ),
      new Fields\StringField(
        'SECTION_CHOOSER',
        [
          'validation' => [__CLASS__, 'validateSectionChooser'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_CHOOSER_FIELD')
        ]
      ),
      new Fields\StringField(
        'LIST_MODE',
        [
          'validation' => [__CLASS__, 'validateListMode'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_MODE_FIELD')
        ]
      ),
      new Fields\StringField(
        'RIGHTS_MODE',
        [
          'validation' => [__CLASS__, 'validateRightsMode'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_RIGHTS_MODE_FIELD')
        ]
      ),
      new Fields\StringField(
        'SECTION_PROPERTY',
        [
          'validation' => [__CLASS__, 'validateSectionProperty'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PROPERTY_FIELD')
        ]
      ),
      new Fields\StringField(
        'PROPERTY_INDEX',
        [
          'validation' => [__CLASS__, 'validatePropertyIndex'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_PROPERTY_INDEX_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'VERSION',
        [
          'default' => 1,
          'title' => Loc::getMessage('IBLOCK_ENTITY_VERSION_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'LAST_CONV_ELEMENT',
        [
          'default' => 0,
          'title' => Loc::getMessage('IBLOCK_ENTITY_LAST_CONV_ELEMENT_FIELD')
        ]
      ),
      new Fields\IntegerField(
        'SOCNET_GROUP_ID',
        [
          'title' => Loc::getMessage('IBLOCK_ENTITY_SOCNET_GROUP_ID_FIELD')
        ]
      ),
      new Fields\StringField(
        'EDIT_FILE_BEFORE',
        [
          'validation' => [__CLASS__, 'validateEditFileBefore'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_BEFORE_FIELD')
        ]
      ),
      new Fields\StringField(
        'EDIT_FILE_AFTER',
        [
          'validation' => [__CLASS__, 'validateEditFileAfter'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_AFTER_FIELD')
        ]
      ),
      new Fields\StringField(
        'SECTIONS_NAME',
        [
          'validation' => [__CLASS__, 'validateSectionsName'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_SECTIONS_NAME_FIELD')
        ]
      ),
      new Fields\StringField(
        'SECTION_NAME',
        [
          'validation' => [__CLASS__, 'validateSectionName'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_NAME_FIELD')
        ]
      ),
      new Fields\StringField(
        'ELEMENTS_NAME',
        [
          'validation' => [__CLASS__, 'validateElementsName'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_ELEMENTS_NAME_FIELD')
        ]
      ),
      new Fields\StringField(
        'ELEMENT_NAME',
        [
          'validation' => [__CLASS__, 'validateElementName'],
          'title' => Loc::getMessage('IBLOCK_ENTITY_ELEMENT_NAME_FIELD')
        ]
      ),
      new Fields\Relations\Reference(
        'FILE',
        '\Bitrix\File\File',
        ['=this.PICTURE' => 'ref.ID'],
        ['join_type' => 'LEFT']
      ),
      new Fields\Relations\Reference(
        'IBLOCK_TYPE',
        '\Bitrix\Iblock\IblockType',
        ['=this.IBLOCK_TYPE_ID' => 'ref.ID'],
        ['join_type' => 'LEFT']
      ),
      new Fields\Relations\Reference(
        'LANG',
        '\Bitrix\Lang\Lang',
        ['=this.LID' => 'ref.LID'],
        ['join_type' => 'LEFT']
      ),
      new Fields\Relations\Reference(
        'SOCNET_GROUP',
        '\Bitrix\Sonet\SonetGroup',
        ['=this.SOCNET_GROUP_ID' => 'ref.ID'],
        ['join_type' => 'LEFT']
      ),
    ];
    }
    
    /**
    * Returns validators for IBLOCK_TYPE_ID field.
    *
    * @return array
    */
    public static function validateIblockTypeId()
    {
    return [
      new Fields\Validators\LengthValidator(null, 50),
    ];
    }
    
    /**
    * Returns validators for LID field.
    *
    * @return array
    */
    public static function validateLid()
    {
    return [
      new Fields\Validators\LengthValidator(null, 2),
    ];
    }
    
    /**
    * Returns validators for CODE field.
    *
    * @return array
    */
    public static function validateCode()
    {
    return [
      new Fields\Validators\LengthValidator(null, 50),
    ];
    }
    
    /**
    * Returns validators for API_CODE field.
    *
    * @return array
    */
    public static function validateApiCode()
    {
    return [
      new Fields\Validators\LengthValidator(null, 50),
    ];
    }
    
    /**
    * Returns validators for NAME field.
    *
    * @return array
    */
    public static function validateName()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for LIST_PAGE_URL field.
    *
    * @return array
    */
    public static function validateListPageUrl()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for DETAIL_PAGE_URL field.
    *
    * @return array
    */
    public static function validateDetailPageUrl()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for SECTION_PAGE_URL field.
    *
    * @return array
    */
    public static function validateSectionPageUrl()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for CANONICAL_PAGE_URL field.
    *
    * @return array
    */
    public static function validateCanonicalPageUrl()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for XML_ID field.
    *
    * @return array
    */
    public static function validateXmlId()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for TMP_ID field.
    *
    * @return array
    */
    public static function validateTmpId()
    {
    return [
      new Fields\Validators\LengthValidator(null, 40),
    ];
    }
    
    /**
    * Returns validators for SECTION_CHOOSER field.
    *
    * @return array
    */
    public static function validateSectionChooser()
    {
    return [
      new Fields\Validators\LengthValidator(null, 1),
    ];
    }
    
    /**
    * Returns validators for LIST_MODE field.
    *
    * @return array
    */
    public static function validateListMode()
    {
    return [
      new Fields\Validators\LengthValidator(null, 1),
    ];
    }
    
    /**
    * Returns validators for RIGHTS_MODE field.
    *
    * @return array
    */
    public static function validateRightsMode()
    {
    return [
      new Fields\Validators\LengthValidator(null, 1),
    ];
    }
    
    /**
    * Returns validators for SECTION_PROPERTY field.
    *
    * @return array
    */
    public static function validateSectionProperty()
    {
    return [
      new Fields\Validators\LengthValidator(null, 1),
    ];
    }
    
    /**
    * Returns validators for PROPERTY_INDEX field.
    *
    * @return array
    */
    public static function validatePropertyIndex()
    {
    return [
      new Fields\Validators\LengthValidator(null, 1),
    ];
    }
    
    /**
    * Returns validators for EDIT_FILE_BEFORE field.
    *
    * @return array
    */
    public static function validateEditFileBefore()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for EDIT_FILE_AFTER field.
    *
    * @return array
    */
    public static function validateEditFileAfter()
    {
    return [
      new Fields\Validators\LengthValidator(null, 255),
    ];
    }
    
    /**
    * Returns validators for SECTIONS_NAME field.
    *
    * @return array
    */
    public static function validateSectionsName()
    {
    return [
      new Fields\Validators\LengthValidator(null, 100),
    ];
    }
    
    /**
    * Returns validators for SECTION_NAME field.
    *
    * @return array
    */
    public static function validateSectionName()
    {
    return [
      new Fields\Validators\LengthValidator(null, 100),
    ];
    }
    
    /**
    * Returns validators for ELEMENTS_NAME field.
    *
    * @return array
    */
    public static function validateElementsName()
    {
    return [
      new Fields\Validators\LengthValidator(null, 100),
    ];
    }
    
    /**
    * Returns validators for ELEMENT_NAME field.
    *
    * @return array
    */
    public static function validateElementName()
    {
    return [
      new Fields\Validators\LengthValidator(null, 100),
    ];
    }
    }

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

    Для использования генератора ORM классов перейдите на страницу Настройки -> Настройки продукта -> Настройки модулей -> Монитор производительности модуль Монитор производительности должен быть установлен. На вкладке Генератор таблетов отметьте поле Разрешить генерацию таблетов для ORM.

    ![image.png](/bitrix/zame/orm/.files/image-3.png =x600)

    Автоматически сгенерировать класс с описанием любой таблицы можно на странице Настройки -> Производительность -> Таблицы, в меню действий доступен пункт ORM

    ![image.png](/bitrix/zame/orm/.files/image-4.png =x600)

    Операции с сущностями

    Для работы с таблицей стандартными методами D7 доступны следующие методы:

    • getList выполняет запрос и возвращает отобранные по параметрам запроса данные

    • add добавляет новый элемент

    • update обновляет строку в таблице

    • delete удаляет строку в таблице сущности по первичному ключу

    GetList

    Пример запроса:

    // подключаем модуль, через модуль подключается класс IblockTable
    \Bitrix\Main\Loader::IncludeModule("iblock");
    // делаем запрос на выборку данных getList
    $res = \Bitrix\Iblock\IblockTable::getList(array(
    'select' => array('ID')

    Операторы:

    IblockTable::getList(array(
    // имена полей, которые необходимо получить
    'select' => array('ISBN', 'TITLE', 'PUBLISH_DATE'), 
    // описание фильтра для WHERE и HAVING
    'filter' => array('=ID' => 1), 
    // явное указание полей, по которым нужно группировать результат
    'group' => array('PUBLISH_DATE'), 
    // параметры сортировки
    'order' => array('PUBLISH_DATE' => 'DESC', 'TITLE' => 'ASC'), 
    // количество записей
    'limit' => 10, 
    // смещение для limit
    'offset' => 80, 
    // динамически определенные поля
    'runtime' => 'runtime' => array(new Entity\ExpressionField('CNT', 'COUNT(*)')) 
    ));

    select

    array(
    'select' => array('ISBN', 'TITLE', 'PUBLISH_DATE')
    )
    // SELECT ISBN, TITLE, PUBLISH_DATE FROM my_book
    array(
    'select' => array('ISBN', 'TITLE', 'PUBLICATION' => 'PUBLISH_DATE')
    )
    // SELECT ISBN, TITLE, PUBLISH_DATE AS PUBLICATION FROM my_book
    array(
    'select' => array('*')
    )
    // SELECT *

    filter

    array(
    'filter' => array('=ID' => 1)
    )
    // WHERE ID = 1
    array(
    'filter' => array('%=TITLE' => 'Patterns%')
    )
    // WHERE TITLE LIKE 'Patterns%'

    Многоуровневые массивы со склейкой выражений AND/OR:

    array(
    'filter' => array(
       '=ID' => 1,
       '=ISBN' => '9780321127426'
    )
    )
    // WHERE ID = 1 AND ISBN = '9780321127426'
    array(
    'filter' => array(
     // по умолчанию элементы склеиваются через AND
     //'LOGIC' => 'AND', 
       'LOGIC' => 'OR',
       array(
           '=ID' => 1,
           '=ISBN' => '9780321127426'
       ),
       array(
           '=ID' => 2,
           '=ISBN' => '9781449314286'
       )
    )
    )
    // WHERE (ID=1 AND ISBN='9780321127426') OR (ID=2 AND ISBN='9781449314286')

    Полный список операторов сравнения, которые можно использовать в filter:

    'filter' => array('=ID' => 1)
    • = равно (работает и с массивами)

    • % подстрока

    • > больше

    • < меньше

    • @ IN (EXPR) в качестве значения передается массив или объект

    • !@ NOT IN (EXPR)в качестве значения передается массив или объект

    • != не равно

    • !% не подстрока

    • >< между, в качестве значения передается массив array(MIN, MAX)

    • >= больше или равно

    • <= меньше или равно

    • =% LIKE

    • %= LIKE

    • == булевое выражение для ExpressionField (например, для EXISTS() или NOT EXISTS())

    • !>< не между, в качестве значения передается массив array(MIN, MAX)

    • !=% NOT LIKE

    • !%= NOT LIKE

    • '==ID' => null условие, что поле ID равно NULL (в sql-запросе будет преобразовано в ID IS NULL)

    • '!==NAME' => null условие, что поле NAME не равно NULL (в sql-запросе будет преобразовано в NAME IS NOT NULL)

    group

    В параметре group перечисляются поля для группировки:

    array(
    'group' => array('PUBLISH_DATE')
    )

    order

    Параметр позволяет указать порядок сортировки:

    array(
    'order' => array('PUBLISH_DATE' => 'DESC', 'TITLE' => 'ASC')
    )
    array(
    'order' => array('ID') // направление по умолчанию - ASC
    )

    offset/limit

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

    array(
    'order' => array('ID' => 'DESC')
    'limit' => 10
    )
    // 10 последних записей
    array(
    'order' => array('ID')
    'limit' => 20,
    'offset' => 80
    )
    // 5-я страница с записями, по 20 на страницу

    Add

    Метод для добавления записи принимает на вход массив со значениями, где ключи - имена полей сущности:

    // подключаем модуль, через модуль подключается класс IblockTable
    \Bitrix\Main\Loader::IncludeModule("iblock");
    // делаем запрос на вставку данных add
    $res = \Bitrix\Iblock\IblockTable::add(array(
    'NAME' => 'Тест'
    ));

    Update

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

    // подключаем модуль, через модуль подключается класс IblockTable
    \Bitrix\Main\Loader::IncludeModule("iblock");
    // делаем запрос на тзменение поля NAME в записи с ID 1
    $res = \Bitrix\Iblock\IblockTable::update(1, array(
    'NAME' => 'Тест'
    ));

    Delete

    Для удаления записи нужен только первичный ключ:

    // подключаем модуль, через модуль подключается класс IblockTable
    \Bitrix\Main\Loader::IncludeModule("iblock");
    // делаем запрос на удаление записи с ID 1
    $res = \Bitrix\Iblock\IblockTable::delete(1);

    Вывод SQL запроса на экран

    Чтобы понять причину «неправильно» работающей выборки, нужно посмотреть какой sql-запрос формируетя. Рассмотрим на примере выборок из ORM ядра D7 в битриксе:

    // подключаем класс для вывода SQL запроса
    \Bitrix\Main\Application::getConnection()->startTracker();
    // подключаем модуль, через модуль подключается класс IblockTable
    \Bitrix\Main\Loader::IncludeModule("iblock");
    // делаем запрос на выборку данных getList
    $res = \Bitrix\Iblock\IblockTable::getList(array(
    'select' => array('ID')
    ));
    // перебираем массив и выводим на экран
    while ($arr = $res->fetch()) {
    pp($arr);
    }
    // выводим на экран SQL запрос
    echo '<pre>', $res->getTrackerQuery()->getSql(), '</pre>';