-
Notifications
You must be signed in to change notification settings - Fork 23
Переписал статью с построителем запроса #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,42 +3,68 @@ title: Построитель запросов | |||||||||||||||||||||||||
| description: 'Построитель запросов. ORM Bitrix Framework: ключевые концепции, примеры и рекомендации.' | ||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Методы выборки `getList` и `getRow` сразу выполняют запросы и возвращают результаты. Они подходят для простых запросов, но неудобны, если параметры неизвестны заранее или нужна сложная логика. | ||||||||||||||||||||||||||
| Методы `getList` и `getRow` сразу выполняют запрос и возвращают результат. Такой вызов подходит, когда состав полей и условия фильтрации известны заранее. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Гибкость с объектом Query.** Для гибкой настройки запросов используйте объект `Bitrix\Main\ORM\Query\Query`. Он накапливает параметры для запроса. Это полезно, когда параметры неизвестны заранее и формируются программно. | ||||||||||||||||||||||||||
| Если параметры запроса формируются программно, используйте построитель запросов — объект `Bitrix\Main\ORM\Query\Query`. Построитель накапливает параметры и выполняет запрос по вызову метода `exec`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Пример с `getList` | ||||||||||||||||||||||||||
| Сравните три способа собрать один и тот же запрос на получение книги по идентификатору. Все примеры статьи используют класс `BookTable` — его описание смотрите в статье [Операции с сущностями](./entity-operations.md). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Метод getList** | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Все параметры запроса передают одним массивом. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| // получение данных через getList | ||||||||||||||||||||||||||
| $result = BookTable::getList([ | ||||||||||||||||||||||||||
| 'select' => ['ISBN', 'TITLE', 'PUBLISH_DATE'], | ||||||||||||||||||||||||||
| 'filter' => ['=ID' => 1] | ||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Пример с `Bitrix\Main\ORM\Query\Query` | ||||||||||||||||||||||||||
| **Объект Query** | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Тот же запрос через построитель. Каждый параметр задает отдельный метод, а выполняет запрос метод `exec`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Query\Query; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // аналогичный запрос через Query | ||||||||||||||||||||||||||
| $q = new Query(BookTable::getEntity()); | ||||||||||||||||||||||||||
| $q->setSelect(['ISBN', 'TITLE', 'PUBLISH_DATE']); | ||||||||||||||||||||||||||
| $q->setFilter(['=ID' => 1]); | ||||||||||||||||||||||||||
| $result = $q->exec(); | ||||||||||||||||||||||||||
| $query = new Query(BookTable::getEntity()); | ||||||||||||||||||||||||||
| $query->setSelect(['ISBN', 'TITLE', 'PUBLISH_DATE']); | ||||||||||||||||||||||||||
| $query->setFilter(['=ID' => 1]); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $result = $query->exec(); | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Цепочка вызовов** | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Тот же запрос в короткой записи. Методы построителя возвращают сам объект, поэтому вызовы можно объединить в цепочку. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| $query = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ISBN', 'TITLE', 'PUBLISH_DATE']) | ||||||||||||||||||||||||||
| ->where('ID', 1) | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $result = $query->exec(); | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Объект `Query` — ключевой элемент для выборки данных и используется внутри `getList`. Однако переопределение методов `getList` может быть ограничено: метод может сработать при вызове, но не через `Query`. | ||||||||||||||||||||||||||
| Объект `Query` — основа выборки данных. Метод `getList` создает такой же объект и заполняет его переданным массивом параметров. О составе этого массива рассказывает статья [Выборка данных](./querying-data.md). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Метод `exec` возвращает объект `Bitrix\Main\ORM\Query\Result` — у него вызывают `fetch` для одной строки или `fetchAll` для всех. У построителя есть короткие псевдонимы `fetch`, `fetchAll`, `fetchObject` и `fetchCollection`: каждый выполняет запрос и сразу возвращает данные, поэтому вызывать `exec` отдельно не нужно. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| {% note warning "" %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Создавайте объект `Query` методом `query()` нужной таблицы, а не через `new Query()`. Метод `query()` возвращает класс запроса, указанный в методе `getQueryClass()` таблицы. Например, модуль информационных блоков подставляет свой класс запроса. Вызов `new Query()` всегда создает базовый класс, поэтому доработки таблицы теряются. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| {% endnote %} | ||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. После плашки потерялся факт, который был в статье до PR — в Добавьте абзац после Переопределенный метод |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Постепенное добавление параметров | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Если вы не знаете заранее, какие поля выбрать или какие фильтры применить, используйте объект `Query` для постепенного добавления параметров. | ||||||||||||||||||||||||||
| Если вы не знаете заранее, какие поля выбрать или какие фильтры применить, добавляйте их в объект `Query` по ходу программы. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Query\Query; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $query = new Query(BookTable::getEntity()); | ||||||||||||||||||||||||||
| $query = BookTable::query(); | ||||||||||||||||||||||||||
| attachSelect($query); | ||||||||||||||||||||||||||
| attachOthers($query); | ||||||||||||||||||||||||||
| $result = $query->exec(); | ||||||||||||||||||||||||||
|
|
@@ -71,73 +97,223 @@ function attachOthers(Query $query): void | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Замечание было про первое лицо и точки в пунктах, а не про то, что разбор примера лишний. Сейчас блок кода со строк 64–98 остался без пояснения. Замените строку на: Создание объекта Query. Метод Добавление полей в запрос. Функция
Добавление фильтров и сортировки. Функция
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Создание объекта Query**. Используем `new Query(BookTable::getEntity())` для создания нового объекта `Query`, связанного с сущностью `BookTable`. Это будет основой для построения запроса. | ||||||||||||||||||||||||||
| Параметры запроса разнесены по отдельным функциям, чтобы вынести логику сбора из основного кода. Метод `exec` выполнит запрос, когда обе функции добавят свои параметры. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Запрос без выполнения | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Объект `Query` позволяет построить запрос и не выполнять его. Метод `getQuery` возвращает текст запроса — он нужен для отладки или для встраивания в подзапрос. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\Type\Date; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $query = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ID']) | ||||||||||||||||||||||||||
| ->setFilter([ | ||||||||||||||||||||||||||
| '=PUBLISH_DATE' => new Date('2014-12-13', 'Y-m-d') | ||||||||||||||||||||||||||
| ]) | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $sql = $query->getQuery(); | ||||||||||||||||||||||||||
| file_put_contents('/tmp/today_books.sql', $sql); | ||||||||||||||||||||||||||
| // в файл попадет текст SELECT ID FROM my_book WHERE PUBLISH_DATE='2014-12-13', сам запрос не выполнится | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Методы Query | ||||||||||||||||||||||||||
|
gromdron marked this conversation as resolved.
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Добавление полей в запрос**. Функция `attachSelect` добавляет поля, которые нужно выбрать из базы данных. | ||||||||||||||||||||||||||
| Методы объекта `Query` задают параметры запроса. Префикс в названии показывает, что делает метод. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `addSelect('ID')` добавляет поле `ID` в список выбираемых полей | ||||||||||||||||||||||||||
| - `set` заменяет ранее заданное значение. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - Условие внутри функции добавляет поле `ISBN`, если оно необходимо | ||||||||||||||||||||||||||
| - `add` дополняет его. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Добавление фильтров и сортировки**. Функция `attachOthers` добавляет фильтры и сортировку. | ||||||||||||||||||||||||||
| - `get` возвращает текущее значение. | ||||||||||||||||||||||||||
|
Comment on lines
+125
to
+129
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Маркеры списков идут с одним пробелом. В разделе принято два Поправьте во всех 17 пунктах: строки 125, 127, 129, 139, 141, 143, 174, 176, 199, 201, 203, 242, 244, 246, 262, 264, 283.
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setFilter` устанавливает условия фильтрации данных | ||||||||||||||||||||||||||
| {% note warning "" %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setOrder` задает порядок сортировки результатов | ||||||||||||||||||||||||||
| Если запрос обращается к несуществующему полю, ORM выбрасывает `Bitrix\Main\ArgumentException`. То же исключение выбрасывает `addOrder` при направлении сортировки, отличном от `ASC` и `DESC`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Запрос без выполнения | ||||||||||||||||||||||||||
| {% endnote %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Объект `Query` позволяет строить запрос без его выполнения. Это полезно для подзапросов или получения текста запроса: | ||||||||||||||||||||||||||
| ### Select и Group | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setSelect`, `setGroup` — задают список полей, полностью заменяя предыдущие. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `addSelect`, `addGroup` — добавляют новые поля к существующему списку. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getSelect`, `getGroup` — возвращают массив полей. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Метод `setSelect` принимает массив, а `setGroup` и `addGroup` — строку с одним полем или массив полей. Вторым аргументом `addSelect` задают псевдоним поля: вызов `addSelect('PUBLISH_DATE', 'PUBLICATION')` вернет значение под ключом `PUBLICATION`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| В примере запрос выбирает три поля, последнее из них добавляет отдельный вызов. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Query\Query; | ||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE']) | ||||||||||||||||||||||||||
| ->addSelect('PUBLISH_DATE') | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| // SELECT ID, TITLE, PUBLISH_DATE FROM my_book | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $q = new Query(BookTable::getEntity()); | ||||||||||||||||||||||||||
| $q->setSelect(['ID']); | ||||||||||||||||||||||||||
| $q->setFilter(['=PUBLISH_DATE' => new Type\Date('2014-12-13', 'Y-m-d')]); | ||||||||||||||||||||||||||
| $sql = $q->getQuery(); | ||||||||||||||||||||||||||
| file_put_contents('/tmp/today_books.sql', $sql); | ||||||||||||||||||||||||||
| // Запрос "SELECT ID FROM my_book WHERE PUBLISH_DATE='2014-12-31'" будет сохранен в файл, но не выполнен. | ||||||||||||||||||||||||||
| Чтобы посчитать книги по датам выхода, добавьте группировку. Поле `CNT` описывает объект `ExpressionField` — о таких полях рассказывает раздел [Runtime-поля](#runtime-polya). | ||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ссылка не разрешится. Якорь генерируется из заголовка и кириллицу сохраняет, а явного Нужно либо |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Fields\ExpressionField; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $stat = BookTable::query() | ||||||||||||||||||||||||||
| ->registerRuntimeField(new ExpressionField('CNT', 'COUNT(*)')) | ||||||||||||||||||||||||||
| ->setSelect(['PUBLISH_DATE', 'CNT']) | ||||||||||||||||||||||||||
| ->setGroup('PUBLISH_DATE') | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| // SELECT PUBLISH_DATE, COUNT(*) AS CNT FROM my_book GROUP BY PUBLISH_DATE | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Методы Query | ||||||||||||||||||||||||||
| ### Distinct | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setDistinct` — устанавливает флаг `DISTINCT` SQL-запроса, чтобы убрать дубликаты строк. Без аргумента ставит флаг, вызов `setDistinct(false)` его снимает. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `hasDistinct` — возвращает `true`, если флаг `DISTINCT` установлен или указан внутри выражения `ExpressionField`, добавленного в выборку. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Чтобы получить даты выхода книг без повторов, установите флаг `DISTINCT`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| $dates = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['PUBLISH_DATE']) | ||||||||||||||||||||||||||
| ->setDistinct() | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| // SELECT DISTINCT PUBLISH_DATE FROM my_book | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| {% note info "" %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Метод `hasDistinct` разбирает выражения выборки, а они формируются в момент построения запроса. Вызывайте метод после `exec`, `fetchAll` или `getQuery`. У неисполненного запроса метод учитывает только флаг, заданный через `setDistinct`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Если `DISTINCT` уже задан внутри выражения, метод снимает собственный флаг запроса, чтобы `DISTINCT` не попал в SQL дважды. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **select, group** | ||||||||||||||||||||||||||
| {% endnote %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setSelect`, `setGroup` — задает список полей, полностью заменяя предыдущие | ||||||||||||||||||||||||||
| ### Filter | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `addSelect`, `addGroup` — добавляет новые поля к существующему списку | ||||||||||||||||||||||||||
| - `setFilter` — устанавливает фильтр и заменяет предыдущий. Принимает массив условий. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getSelect`, `getGroup` — возвращает массив полей | ||||||||||||||||||||||||||
| - `addFilter` — добавляет одно условие к текущему фильтру. Первым аргументом принимает имя поля с префиксом оператора, вторым — значение. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **distinct** | ||||||||||||||||||||||||||
| - `getFilter` — возвращает текущий фильтр. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setDistinct` — устанавливает флаг `DISTINCT`, чтобы убрать дубликаты строк из результата | ||||||||||||||||||||||||||
| Основное условие отбирает книги с начала 2014 года, а второй вызов уточняет отбор по ISBN, если он задан. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `hasDistinct` — возвращает `true`, если флаг `DISTINCT` установлен или указан внутри выражения `ExpressionField`, добавленного в выборку | ||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\Type\Date; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $query = BookTable::query()->setSelect(['ID', 'TITLE']); | ||||||||||||||||||||||||||
| $query->setFilter(['>=PUBLISH_DATE' => new Date('2014-01-01', 'Y-m-d')]); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (/* задан отбор по ISBN */) | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| $query->addFilter('=ISBN', '978-0321127426'); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **filter** | ||||||||||||||||||||||||||
| $books = $query->fetchAll(); | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setFilter` — устанавливает фильтр | ||||||||||||||||||||||||||
| {% note tip "" %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `addFilter` — добавляет параметр фильтра | ||||||||||||||||||||||||||
| Метод `setFilter` принимает массив условий — тот же формат, что и ключ `filter` в методе `getList`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getFilter` — возвращает фильтр | ||||||||||||||||||||||||||
| Для новых запросов удобнее методы `where*`: они принимают поле, оператор и значение отдельными аргументами. Об операторах и вложенных условиях рассказывает статья [Выборка данных](./querying-data.md). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **order** | ||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\Type\Date; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE']) | ||||||||||||||||||||||||||
| ->where('ISBN', '978-0321127426') | ||||||||||||||||||||||||||
| ->where('PUBLISH_DATE', '>=', new Date('2014-01-01', 'Y-m-d')) | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setOrder` — устанавливает порядок сортировки | ||||||||||||||||||||||||||
| {% endnote %} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `addOrder` — добавляет поле для сортировки | ||||||||||||||||||||||||||
| ### Order | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getOrder` — возвращает порядок сортировки | ||||||||||||||||||||||||||
| - `setOrder` — задает порядок сортировки и заменяет предыдущий. Принимает массив вида `['ID' => 'DESC']` или строку с одним полем — тогда сортировка идет по возрастанию. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **limit/offset** | ||||||||||||||||||||||||||
| - `addOrder` — добавляет поле сортировки к текущему порядку. Второй аргумент по умолчанию равен `ASC`, допустимы только значения `ASC` и `DESC`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setLimit`, `setOffset` — устанавливает значение | ||||||||||||||||||||||||||
| - `getOrder` — возвращает текущий порядок сортировки. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getLimit`, `getOffset` — возвращает значение | ||||||||||||||||||||||||||
| Две сортировки работают по порядку: сначала свежие книги, внутри одной даты — по названию. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **runtime fields** | ||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE']) | ||||||||||||||||||||||||||
| ->setOrder(['PUBLISH_DATE' => 'DESC']) | ||||||||||||||||||||||||||
| ->addOrder('TITLE', 'ASC') | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| // SELECT ID, TITLE FROM my_book ORDER BY PUBLISH_DATE DESC, TITLE ASC | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Limit и Offset | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `setLimit`, `setOffset` — задают количество записей и смещение от начала выборки. Принимают целое число или `null`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `getLimit`, `getOffset` — возвращают заданные значения. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Для постраничного вывода задайте размер страницы и смещение. В примере это третья страница каталога по 20 книг. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| $pageSize = 20; | ||||||||||||||||||||||||||
| $page = 3; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE']) | ||||||||||||||||||||||||||
| ->setOrder(['PUBLISH_DATE' => 'DESC']) | ||||||||||||||||||||||||||
| ->setLimit($pageSize) | ||||||||||||||||||||||||||
| ->setOffset(($page - 1) * $pageSize) | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Runtime-поля | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `registerRuntimeField` — регистрирует временное поле запроса. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Метод `registerRuntimeField` добавляет поле к таблице так же, как если бы его описали в методе `getMap`, но действует такое поле только внутри текущего запроса. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| В следующем запросе поле нужно зарегистрировать заново. В метод передавайте объект поля, чаще всего `ExpressionField` — о нем рассказывает статья [Ключевые концепции ORM](./orm-concepts.md). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Здесь выражение считает возраст книги в днях — хранить это значение в таблице не нужно. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Fields\ExpressionField; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->registerRuntimeField( | ||||||||||||||||||||||||||
| new ExpressionField('AGE_DAYS', 'DATEDIFF(NOW(), %s)', ['PUBLISH_DATE']) | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE', 'AGE_DAYS']) | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Пример отбирает книги старше года и выводит самые старые первыми. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```php | ||||||||||||||||||||||||||
| use Bitrix\Main\ORM\Fields\ExpressionField; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $books = BookTable::query() | ||||||||||||||||||||||||||
| ->registerRuntimeField( | ||||||||||||||||||||||||||
| new ExpressionField('AGE_DAYS', 'DATEDIFF(NOW(), %s)', ['PUBLISH_DATE']) | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ->setSelect(['ID', 'TITLE', 'AGE_DAYS']) | ||||||||||||||||||||||||||
| ->where('AGE_DAYS', '>', 365) | ||||||||||||||||||||||||||
| ->setOrder(['AGE_DAYS' => 'DESC']) | ||||||||||||||||||||||||||
| ->fetchAll() | ||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - `registerRuntimeField` — регистрирует временное поле | ||||||||||||||||||||||||||
| Зарегистрированное поле доступно в выборке, фильтре и сортировке текущего запроса — регистрировать его повторно не нужно. | ||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Якорь потерялся. В
entity-operations.md:445есть заголовок## Пример класса BookTable {#booktable-example}— ссылка должна вести на него, а не на статью целиком.Замените строку на:
Сравните три способа собрать один и тот же запрос на получение книги по идентификатору. Все примеры статьи используют объект
BookTable— его класс целиком смотрите в статье Операции с сущностями.