点击此处---> 群内免费提供SAP练习系统(在群公告中)
加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)
在这篇文章中,您将学习如何实现实体的所有操作。
这是构建 OData 服务系列的一篇文章。可以通过以下链接访问较早的帖子。
构建 OData 服务 [1]:OData 概述
构建 OData 服务 [2]:了解 OData 服务
构建 OData 服务 [3]:创建 OData 服务
构建 OData 服务 [4]:注册和测试 OData 服务
构建 OData 服务 [5]:使用 OData URI
在上一篇文章中,我们了解了 URI 的工作原理。现在让我们在 SAP ABAP 中实现 URI/服务操作。
在 SEGW 事务中生成 OData 项目时,会创建数据提供者基类和数据提供者扩展类。我们将使用扩展类来实现所有操作。
这是扩展类——通常称为 DPC_EXT 类。
每个操作在数据提供者类中都有一个专用方法。方法名称表明应该使用它们来实现哪个操作。
例如,CARRIERSET_CREATE_ENTITY 用于创建载体。每个操作的代码示例如下。
阅读 - 获取实体
IT_KEY_TAB 包含键名和键值。
DATA: lv_carrid TYPE scarr-carrid. TRY. DATA(ls_key_tab) = it_key_tab[ name = 'CarrierID' ]. lv_carrid = ls_key_tab-value. SELECT SINGLE * FROM scarr INTO CORRESPONDING FIELDS OF er_entity WHERE carrid = lv_carrid. CATCH cx_sy_itab_line_not_found. "Error handling ENDTRY.
查询:数据的选择和排序——GET ENTITYSET
在查询操作中,可以根据业务逻辑默认应用一些过滤器。
数据按照导入对象 io_tech_request_context 中的信息进行排序。
*-- Select the dataSELECT * FROM scarr INTO TABLE et_entityset WHERE carrid IN lr_carrid. "lr_carrid can be built as per business logic*-- Implement Sorting DATA: lt_otab TYPE abap_sortorder_tab, ls_otab TYPE abap_sortorder, lt_tech_order TYPE /iwbep/t_mgw_tech_order. lt_tech_order = io_tech_request_context->get_orderby( ). IF lt_tech_order IS NOT INITIAL. LOOP AT lt_tech_order INTO DATA(ls_order). ls_otab-name = ls_order-property. TRANSLATE ls_otab-name TO UPPER CASE. IF ls_order-order = 'desc'. ls_otab-descending = abap_true. ELSE. ls_otab-descending = abap_false. ENDIF. APPEND ls_otab TO lt_otab. ENDLOOP. SORT et_entityset BY (lt_otab). ENDIF.
查询:跳过和顶部 - GET ENTITYSET
Skip 和 Top 用于处理分页。
跳过x和顶部y意味着应该选择索引x+1中的y个记录。由于这应该考虑排序标准,因此通常在应用排序后应用。
*-- This is additional code after the data selection and sorting *-- Handle paging – provide number of records IF io_tech_request_context->has_inlinecount( ) = abap_true. es_response_context-inlinecount = lines( et_entityset ). ENDIF. *-- Handle paging – keep only required records IF is_paging IS NOT INITIAL. lv_to = is_paging-skip. lv_from = is_paging-skip + is_paging-top + 1. IF lv_from LT lines( et_entityset ). DELETE et_entityset FROM lv_from. ENDIF. IF lv_to GT 0. DELETE et_entityset TO lv_to. ENDIF. ENDIF.
查询:关联 – GET ENTITYSET
任何实体集查询操作都可以有两个来源。可以直接调用,也可以通过关联调用。所以两个调用源都应该被处理。
当查询被关联调用时,关联引用约束字段信息会随之传递。否则可以通过过滤器。
导入参数 iv_source_name 告诉它从哪里被调用。
DATA ls_key TYPE /iwbep/s_mgw_name_value_pair. CASE iv_source_name. "URI - /sap/opu/odata/sap/ZJP_DEMO_SRV/CarrierSet('DL')/ToFlightSchedule WHEN 'Carrier'. "Association READ TABLE it_key_tab INTO ls_key WITH KEY name = 'CarrierID'. IF sy-subrc EQ 0. SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE carrid = ls_key-value. ENDIF. "URI - /sap/opu/odata/sap/ZJP_DEMO_SRV/FlightScheduleSet?$filter=Carrid eq 'DL' WHEN 'FlightSchedule'. "Called directly - check filters "Get the data using filters READ TABLE it_filter_select_options INTO ls_filter WITH KEY property = 'Carrid'. IF sy-subrc EQ 0. "For demonstration, it is assumed that filter will be used only for one field READ TABLE ls_filter-select_options INTO ls_selopt INDEX 1. IF sy-subrc EQ 0. SELECT carrid connid countryfr cityfrom countryto cityto FROM spfli INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE carrid = ls_selopt-low. ENDIF. ENDIF. WHEN OTHERS. RETURN. ENDCASE.
函数导入——实现方法:/IWBEP/IF_MGW_APPL_SRV_RUNTIME~EXECUTE_ACTION
所有函数导入在数据提供者类中触发相同的方法。该方法具有导入参数 iv_action_name,该参数将函数导入名称作为值。
此示例描述了如果创建函数导入以获取承运人的航班数,如何实现代码。
在这里,重要的是要注意函数导入始终返回单个实体或实体集。由于它可以传回实体和实体集,因此使用特殊方法 copy_data_to_ref 将结果数据复制到 er_data ,即导出的数据引用。
CASE iv_action_name. WHEN 'GetCarrierFlights'. DATA: ls_parameter TYPE /iwbep/s_mgw_name_value_pair, lv_carrid TYPE scarr-carrid, lv_count TYPE i, ls_data TYPE zcl_zjp_demo_mpc=>ts_scarr. READ TABLE it_parameter INTO ls_parameter WITH KEY name = 'CarrierID'. IF sy-subrc EQ 0. lv_carrid = ls_parameter-value. ls_data-carrid = lv_carrid. SELECT COUNT(*) FROM sflight INTO lv_count WHERE carrid = lv_carrid. IF sy-subrc EQ 0. ls_data-carrname = lv_count. ELSE. ls_data-carrname = '0'. ENDIF. ENDIF.* Call method copy_data_to_ref and export entity data copy_data_to_ref( EXPORTING is_data = ls_data CHANGING cr_data = er_data ). ENDCASE.
其余的 CRUD 操作可以如下实现。为了演示,使用自定义表 ZJP_SFLIGHT。
创建 – 创建实体
要创建的数据从io_data_provider获取。
DATA: ls_sflight TYPE sflight.CALL METHOD io_data_provider->read_entry_data IMPORTING es_data= er_entity.MOVE-CORRESPONDING er_entity TO ls_sflight. ls_sflight-mandt = sy-mandt. INSERT zjp_sflight FROM ls_sflight. IF sy-subrc NE 0. RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception. ENDIF.
更新 – 更新实体
要更新的数据从对象io_data_provider 中获取。
DATA: ls_sflight TYPE sflight.CALL METHOD io_data_provider->read_entry_data IMPORTING es_data= er_entity. MOVE-CORRESPONDING er_entity TO ls_sflight. ls_sflight-mandt = sy-mandt. MODIFY zjp_sflight FROM ls_sflight. IF sy-subrc NE 0. RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception. ENDIF.
删除 – 删除实体
对于删除,密钥在 it_key_tab 中发送。一次删除一个条目。
DATA: ls_sflight TYPE sflight. LOOP AT it_key_tab INTO DATA(ls_key_tab). CASE ls_key_tab-name. WHEN 'Carrid'. ls_sflight-carrid = ls_key_tab-value. WHEN 'Connid'. ls_sflight-connid = ls_key_tab-value. WHEN 'Fldate'. ls_sflight-fldate = ls_key_tab-value. ENDCASE. ENDLOOP. DELETE FROM zjp_sflight WHERE carrid = ls_sflight-carrid AND connid = ls_sflight-connid AND fldate = ls_sflight-fldate.
这些代码示例仅在实体名称和属性完全匹配时才起作用,因此在创建服务时,请使用这些代码示例作为参考并实现该服务。