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

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

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

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

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

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

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

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

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

Warning

В фильтрах запросов можно использовать только custom, param и component параметры. Параметры ds и session не будут работать.

Пример:

<query>
    <![CDATA[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)