Ранее было показано, каким образом можно загрузить хранимый объект из БД относительно ключевых полей и даже как массово их инициализировать (метод GET_PERSISTENT_BY_KEY_TAB). Альтернативой подобному методу служит — Query Service. QS — Инструмент позволяющий Вам делать поиск и загрузку хранимых объектов, относительно логических выражений (условий). Кроме фильтров относительно условий, QS позволяет задать параметры сортировки. Используя QS, вам не надо будет выбирать отдельные ключевые поля, т.о. для массовой инициализации группы объектов, система выполнит только один SQL запрос.
Пример использования QS с фильтром по дате полёта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, gv_filter TYPE string, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). gv_filter = 'FLDATE <= ''' && '20130306'''. go_query = go_query_manager->create_query( i_filter = gv_filter ). go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query RECEIVING result = gt_result ). |
Для того чтобы иметь возможность получить объекты по запросу, необходимо сначала этот запрос создать. За создание запроса отвечает менеджер запросов, получить ссылку на который, можно через класс CL_OS_SYSTEM. Далее, используя метод CREATE_QUERY, создается экземпляр класса запроса (реализующего интерфейс — IF_OS_QUERY). В данный метод передан параметр, формирующий динамическое условие относительно даты полёта. Результатом запроса будет внутренняя таблица (gt_result), заполненная ссылочными переменными на хранимые объекты.
Компоненты Query Service
QS включает в себя следующие компоненты:
Методы менеджера запросов (IF_OS_QUERY_MANAGER)
CREATE_QUERY. Создание экземпляра класса запроса, на вход получает следующие параметры: I_FILTER,I_ORDERING,I_PARAMETERS. Условие фильтрации основано на динамическом вызове WHERE, с поддержкой некоторых условий относительно ссылочных переменных. Как и в условии WHERE, поддерживаются логические операторы AND, OR, NOT, а так же объединение условий через круглые скобки. При вызове запроса через агент класса, фильтрация привязана к атрибутам хранимого класса для этого агента, атрибуты должны быть публичными (public) хранимыми атрибутами, иначе произойдет исключение. Таким образом, созданный объект запроса может использоваться разными агентами, но с соблюдением условий наличия атрибутов.
Условие фильтрации, как и его параметры обрабатываются каждый раз, когда выполняется запрос, для того чтобы не делать разбор выражения каждый раз, можно использовать методы интерфейса IF_OS_QUERY_EXPR_FACTORY чтобы сформировать условия фильтрации сразу во внутреннем представлении (пример ниже).
Условия фильтрации поддерживают следующие операторы:
- =, <>, <, <=, >, >=
- attr [NOT] LIKE { pattern } [ESCAPE escape]
- attr IS [NOT] NULL
- attr EQUALSREF par – Сравнение двух ссылочных переменных. Когда выполняется запрос, параметр parдолжен быть привязан к ссылочной переменной хранимого класса.
- NOT expr
- expr AND expr
- expr OR expr
Примеры фильтров:
- price < ‘100’ AND currency = ‘EUR’
- name LIKE PAR1 AND age > ’45’ AND age < ’65’
- ( department EQUALSREF DEP1 OR department EQUALSREF DEP2 ) AND NOT ( salary > ‘50000’ AND currency = ‘EUR’ ) )
I_FILTER позволяет использовать внутри себя параметры, заполнить которые можно в запросе агента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, gv_filter TYPE string, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). gv_filter = 'FLDATE <= PAR1'. go_query = go_query_manager->create_query( i_filter = gv_filter ). go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query i_par1 = '20130406' RECEIVING result = gt_result ). |
Если параметров будет больше чем 3, необходимо использовать таблицу параметров (нельзя одновременно использовать i_par1-3 и таблицу параметров). Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, gr_paramval TYPE REF TO DATA, gv_paramval TYPE sy-datum VALUE '20130206', gv_filter TYPE string, gt_parameters TYPE osdreftab, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). gv_filter = 'FLDATE <= CustomParameter'. go_query = go_query_manager->create_query( i_filter = gv_filter i_parameters = 'CustomParameter' ). GET REFERENCE OF gv_paramval INTO gr_paramval. APPEND gr_paramval TO gt_parameters. go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query i_parameter_tab = gt_parameters RECEIVING result = gt_result ). |
I_PARAMETERS — определяет имена используемых в запросе параметров, имена должны быть разделены пробелом. В условии сортировки I_ORDERING может быть прописано два вида условия: сортировка по возрастанию и сортировка по убыванию, пример:
price ASCENDING date DESCENDING
Методы интерфейса IF_OS_QUERY
IF_OS_QUERY~GET_EXPR_FACTORY.Получает ссылку на фабрику условий, класс реализующий интерфейс IF_OS_QUERY_EXPR_FACTORY. С помощью фабрики условий можно формировать условия во внутреннем представлении QS.
IF_OS_QUERY~SET_FILTER_EXPR. Установка условия фильтрации, на вход принимает класс реализующий интерфейс IF_OS_QUERY_FILTER_EXPR. Ссылку на данный класс можно получить через фабрику условий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_expr_factory TYPE REF TO if_os_query_expr_factory, go_filter_expr TYPE REF TO if_os_query_filter_expr, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( ). go_expr_factory = go_query->get_expr_factory( ). go_filter_expr = go_expr_factory->create_operator_expr( i_attr1 = 'FLDATE' i_operator = '<=' i_val = '20130206' ). go_query->set_filter_expr( go_filter_expr ). go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query RECEIVING result = gt_result ). |
В условии выражения с операторами можно указать индекс в таблице с параметрами:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_expr_factory TYPE REF TO if_os_query_expr_factory, go_filter_expr TYPE REF TO if_os_query_filter_expr, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, go_sflight_agent TYPE REF TO zca_sflight, gr_paramval TYPE REF TO data, gv_paramval TYPE sflight-fldate VALUE '20130206', gt_parameters TYPE osdreftab. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( ). go_expr_factory = go_query->get_expr_factory( ). go_filter_expr = go_expr_factory->create_operator_expr( i_attr1 = 'FLDATE' i_operator = '<=' i_idx = 1 ). go_query->set_filter_expr( go_filter_expr ). GET REFERENCE OF gv_paramval INTO gr_paramval. APPEND gr_paramval TO gt_parameters. go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query i_parameter_tab = gt_parameters RECEIVING result = gt_result ). |
IF_OS_QUERY~SET_PARAMETERS_EXPR. Устанавливает список параметров для условия фильтрации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_expr_factory TYPE REF TO if_os_query_expr_factory, go_params_expr TYPE REF TO if_os_query_parameters_expr, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, go_sflight_agent TYPE REF TO zca_sflight, gr_paramval TYPE REF TO data, gv_paramval TYPE sflight-fldate VALUE '20130206', gt_parameters TYPE osdreftab. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( i_filter = 'FLDATE <= PARAM' ). go_expr_factory = go_query->get_expr_factory( ). go_params_expr = go_expr_factory->create_parameters_expr( ). go_params_expr->append('PARAM'). go_query->set_parameters_expr( go_params_expr ). GET REFERENCE OF gv_paramval INTO gr_paramval. APPEND gr_paramval TO gt_parameters. go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query i_parameter_tab = gt_parameters RECEIVING result = gt_result ). |
IF_OS_QUERY~SET_ORDERING_EXPR. Устанавливает условия сортировки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_expr_factory TYPE REF TO if_os_query_expr_factory, go_order_expr TYPE REF TO if_os_query_ordering_expr, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( i_filter = 'FLDATE <= ''' && '20130206''' ). go_expr_factory = go_query->get_expr_factory( ). go_order_expr = go_expr_factory->create_ordering_expr( ). go_order_expr->append_ascending( 'FLDATE' ). go_query->set_ordering_expr( go_order_expr ). go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query RECEIVING result = gt_result ). |
Условия фильтрации, показанные ранее, включали в себя всего одно условие, QS позволяет создавать комплексные условия (OR,AND,NOT), пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_expr_factory TYPE REF TO if_os_query_expr_factory, go_filter_fldate TYPE REF TO if_os_query_filter_expr, go_filter_price TYPE REF TO if_os_query_filter_expr, go_filter_date_and_price TYPE REF TO if_os_query_filter_expr, go_query TYPE REF TO if_os_query, gt_result TYPE osreftab, go_sflight_agent TYPE REF TO zca_sflight. go_sflight_agent = zca_sflight=>agent. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( ). go_expr_factory = go_query->get_expr_factory( ). go_filter_fldate = go_expr_factory->create_operator_expr( i_attr1 = 'FLDATE' i_operator = '<=' i_val = '20130206' ). go_filter_price = go_expr_factory->create_operator_expr( i_attr1 = 'PRICE' i_operator = '>' i_val = '1000' ). go_filter_date_and_price = go_expr_factory->create_and_expr( i_expr1 = go_filter_fldate i_expr2 = go_filter_price ). go_query->set_filter_expr( go_filter_date_and_price ). go_sflight_agent->if_os_ca_persistency~get_persistent_by_query( EXPORTING i_query = go_query RECEIVING result = gt_result ). |
Инициировать объекты через QS можно как с помощью агента класса, так и с помощью менеджера постоянства, указав имя класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
DATA: go_query_manager TYPE REF TO if_os_query_manager, go_query TYPE REF TO if_os_query, go_pers_manager TYPE REF TO if_os_persistency_manager, gs_cls_name TYPE seoclskey, gt_result TYPE osreftab. go_query_manager = cl_os_system=>get_query_manager( ). go_query = go_query_manager->create_query( i_filter = 'FLDATE <= ''20130206''' ). gs_cls_name-clsname = 'ZCL_SFLGIHT'. go_pers_manager = cl_os_system=>get_persistency_manager( ). gt_result = go_pers_manager->get_persistent_by_query( i_class_name = gs_cls_name i_query = go_query ). |