4.5.3.2.3. Фильтр запроса

Запрос источника данных может быть модифицирован во время работы приложения, в зависимости от вводимых пользователем условий, что позволяет эффективно фильтровать данные на уровне выборки из БД.

Простейший способ обеспечения такой возможности - подключение к источнику данных специального визуального компонента Filter.

Если по какой-то причине применение универсального фильтра нежелательно, можно встроить в текст запроса специальную разметку на XML, позволяющую сформировать итоговый запрос в зависимости от значений, введенных пользователем в произвольные визуальные компоненты экрана.

В таком фильтре могут быть использованы следующие элементы:

  • filter - корневой элемент фильтра. Может непосредственно содержать только одно условие.

    • and, or - логические условия, могут содержать любое количество других условий и предложений.

    • c - предложение на JPQL, которое добавляется в секцию where. Содержит только текст и опционально атрибут join, значение которого будет добавлено в соответствующее место запроса, если добавляется данное предложение where.

Условия и предложения добавляются в итоговый запрос, только если присутствующие внутри них параметры получили значения, т.е. не равны null.

Пример:

<query>
  select distinct d from app$GeneralDoc d
  <filter>
      <or>
          <and>
              <c join=", app$DocRole dr">dr.doc.id = d.id and d.processState = :custom$state</c>
              <c>d.barCode like :component$barCodeFilterField</c>
          </and>
          <c join=", app$DocRole dr">dr.doc.id = d.id and dr.user.id = :custom$initiator</c>
      </or>
  </filter>
</query>

В данном случае если в метод refresh() источника данных переданы параметры state и initiator, а в визуальном компоненте barCodeFilterField установлено некоторое значение, то итоговый запрос примет вид:

select distinct d from app$GeneralDoc d, app$DocRole dr
where
(
  (dr.doc.id = d.id and d.processState = :custom$state)
  and
  (d.barCode like :component$barCodeFilterField)
)
or
(dr.doc.id = d.id and dr.user.id = :custom$initiator)

Если же, к примеру, компонент barCodeFilterField пуст, а в refresh() передан только параметр initiator, то запрос получится следующим:

select distinct d from app$GeneralDoc d, app$DocRole dr
where
(dr.doc.id = d.id and dr.user.id = :custom$initiator)

Не используйте ds-параметры в фильтрах запросов. Они предназначены для связывания источников данных и обрабатываются специальным образом.