SAP-BTP :(7)RAP-EML

一、什么是 EML

EML(Entity Manipulation Language,实体操作语言) 是 ABAP 语言的一个子集,专门用于访问和操作 RAP(RESTful ABAP Programming Model)业务对象(Business Object,简称 BO)。

官方对 EML 的定义非常克制:它不是一门新语言,也不是 Open SQL 的别名,而是在 ABAP 体系中新增的一组语法结构,用于在 ABAP 代码中直接与 RAP BO 交互。

二、EML 在 RAP 生态中的定位

复制代码
┌─────────────────────────────────────────────────────┐
│                   RAP 应用层                          │
├─────────────────────────────────────────────────────┤
│  Fiori UI  │  OData API  │  ABAP Report  │  BAdI    │
└─────┬──────┴──────┬──────┴───────┬────────┴─────┬────┘
      │             │              │              │
      ▼             ▼              ▼              ▼
┌─────────────────────────────────────────────────────┐
│                     EML 入口                         │
│   ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌──────┐  │
│   │  READ   │  │ CREATE  │  │ UPDATE  │  │DELETE│  │
│   └─────────┘  └─────────┘  └─────────┘  └──────┘  │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│                  RAP 业务对象                         │
│   ┌──────────────┐  ┌──────────────┐                │
│   │  CDS 数据模型  │  │ Behavior定义 │                │
│   └──────────────┘  └──────────────┘                │
└─────────────────────────────────────────────────────┘

EML 是 RAP 业务对象的唯一 ABAP 访问入口,主要有以下两层定位:

1. 面向业务实体的访问语言

传统 ABAP 开发中,读写数据需要直接编写 SQL 语句操作数据库表。EML 则面向 RAP 中定义的业务实体(Entity),开发者只需要知道实体名称和字段,不需要关心底层表结构。所有访问都通过 RAP BO 接口进行,会自动触发 BO 中定义的校验逻辑、权限控制和行为实现。

2. RAP BO 的通用消费接口

EML 可以在任意 ABAP 程序中使用,包括 Report、BAdI 实现类,以及 RAP BO 自身的行为实现类。无论是消费一个已经发布的 RAP BO,还是在行为池内部操作自己的 BO,都使用同一套 EML 语法。

三、EML 核心语法实操

EML 提供两种核心语法结构:READ ENTITIES 用于读取数据,MODIFY ENTITIES 用于修改数据(包含 CUD 及 Action 执行)。创建类,类实现接口**if_oo_adt_classrun**

3.1 READ ENTITIES

复制代码
READ ENTITIES OF root_entity
   ENTITY entity_name
      FIELDS ( field1 field2 ... )
      FROM VALUE #( ( key1 = ... key2 = ... ) )
      RESULT DATA(lt_result)
      FAILED DATA(lt_failed)
      REPORTED DATA(lt_reported).
语法组件 说明
FIELDS 指定需要读取的字段列表(可选,不写则读取所有字段)
FROM 提供主键值,定位要读取的实例
RESULT 存放读取结果的内部表
FAILED 存放读取失败的实例键值
REPORTED 存放读取过程中产生的消息

常见读取方式:

  • 按主键读取 :FROM VALUE #( ( %key = ... ) )

  • 读取全部实例ALL FIELDS WITH CORRESPONDING #( empty_table )

  • 关联读取(READ BY ASSOCIATION):从主实体导航到子实体

案例:

3.2 MODIFY ENTITIES

复制代码
MODIFY ENTITIES OF root_entity
   ENTITY entity_name
      CREATE | UPDATE | DELETE | EXECUTE
      [IN LOCAL MODE]
      WITH VALUE #( ... )
      FAILED DATA(lt_failed)
      REPORTED DATA(lt_reported)
      MAPPED DATA(lt_mapped).

核心修饰符 IN LOCAL MODE

使用场景 说明
Develop 场景(BO 行为池内) 可在 EML 语句后加 IN LOCAL MODE,绕过访问控制、授权检查和特征实例控制
Consume 场景(消费其他 BO) 不可加 IN LOCAL MODE,必须走标准权限校验
Test 场景(单元测试) 推荐不加,保持与真实消费行为一致

案例:

复制代码
CLASS zcl_rap_eml_kj DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_oo_adt_classrun .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_rap_eml_kj IMPLEMENTATION.


  METHOD if_oo_adt_classrun~main.
    READ ENTITIES OF ZI_RAP_ATRAV_KJ
      ENTITY travel
        FROM VALUE #( ( TravelUUID = '007F6D70806C92DE1900C75A3D45A812' ) )
      RESULT DATA(travels).

    OUT->write( travels ).

    OUT->write( 'UPDATE DONE' ).

    MODIFY ENTITIES OF ZI_RAP_ATRAV_KJ
      ENTITY travel
        UPDATE SET FIELDS WITH VALUE #( ( TravelUUID  = '007F6D70806C92DE1900C75A3D45A812'
                                          Description = 'I like RAP@openSAP' ) )
        FAILED DATA(failed)
        REPORTED DATA(reported).

    COMMIT ENTITIES RESPONSE OF ZI_RAP_ATRAV_KJ
       FAILED     DATA(failed_commit)
       REPORTED   DATA(reported_commit).


  ENDMETHOD.
ENDCLASS.

保存激活后,数据预览

3.3 CREATE ENTITIES

新实体的创建通过带有**CREATE** 子句的**MODIFY** 语句执行。对于创建实例的操作,会返回一个**mapped**表,该表将创建的实例映射到提供的内容ID。

复制代码
CLASS zcl_rap_eml_kj DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_oo_adt_classrun .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_rap_eml_kj IMPLEMENTATION.


  METHOD if_oo_adt_classrun~main.

  " step 7 - MODIFY Create
    MODIFY ENTITIES OF ZI_RAP_ATRAV_KJ
      ENTITY travel
        CREATE
          SET FIELDS WITH VALUE
            #( ( %cid        = 'MyContentID_1'
                 AgencyID    = '70012'
                 CustomerID  = '14'
                 BeginDate   = cl_abap_context_info=>get_system_date( )
                 EndDate     = cl_abap_context_info=>get_system_date( ) + 10
                 Description = 'I like RAP@openSAP' ) )

    MAPPED DATA(mapped)
     FAILED DATA(failed)
     REPORTED DATA(reported).

    out->write( mapped-travel ).

    COMMIT ENTITIES
      RESPONSE OF ZI_RAP_ATRAV_KJ
      FAILED     DATA(failed_commit)
      REPORTED   DATA(reported_commit).

    out->write( 'Create done' ).

  ENDMETHOD.
ENDCLASS.

数据预览:

3.4 DELETE ENTITIES

测试代码:

复制代码
CLASS zcl_rap_eml_kj DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_oo_adt_classrun .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_rap_eml_kj IMPLEMENTATION.


  METHOD if_oo_adt_classrun~main.

   " step 8 - MODIFY Delete
    MODIFY ENTITIES OF ZI_RAP_ATRAV_KJ
      ENTITY travel
        DELETE FROM
          VALUE
            #( ( TravelUUID  = '6AD96431AFBE1FD1948FBAC7A12D8771' ) )

     FAILED DATA(failed)
     REPORTED DATA(reported).

    COMMIT ENTITIES
      RESPONSE OF ZI_RAP_ATRAV_KJ
      FAILED     DATA(failed_commit)
      REPORTED   DATA(reported_commit).

    out->write( 'Delete done' ).

  ENDMETHOD.
ENDCLASS.

数据预览:过滤器查找时不存在

四、三结构消息机制:FAILED / REPORTED / MAPPE

这是最容易被忽略且最容易出错的部分。每个 EML 语句基本都有这三个结构:

复制代码
MODIFY ENTITIES ...
   WITH lt_data
   FAILED   DATA(lt_failed)    " 失败记录 —— 存不下去的那些行
   REPORTED DATA(lt_reported)  " 消息记录 —— 存不下的“理由”
   MAPPED   DATA(lt_mapped).   " 映射记录 —— 存下去的“证据”
结构 作用 常见使用方式
FAILED 记录操作失败的实例 ,存放的是实例的键(通常是 %tky),用于跟踪哪些操作失败了 IF lt_failed IS NOT INITIAL. ROLLBACK ENTITIES. ENDIF.
REPORTED 记录操作过程中产生的业务消息,每条消息可精确关联到实体、字段甚至具体实例 APPEND VALUE #( %msg = new_message( ... ) ) TO lt_reported,或在 OData 中自动映射到 UI 消息区域
MAPPED 记录成功执行的实例的映射关系 ,尤其是 %cid 到实际持久化主键的映射 获取 %cid 对应的主键;在需要跨实体顺序操作时(先创建 A,再把 A 的键塞给 B)对 MAPPED 做判断

理解关键FAILED 告诉 RAP "哪些不行" ,REPORTED 告诉用户 "为什么不行" ,MAPPED 告诉框架 "新的键在哪里"。三个结构分工明确、缺一不可。、从 BOPF 到 RAP 的演进

总结

框架 推出平台 核心特征
BOPF ABAP Platform 7.5 及更早 面向 SAP NetWeaver On-Premise,配置复杂
RAP + EML SAP S/4HANA 1909 及 SAP BTP ABAP 环境 云原生设计,Behavior Definition + EML 语法声明式简化操作

EML 不是"多了几条语法"这么简单:它改变了 ABAP 开发者与业务数据交互的方式------从面向表、面向 SQL 转变成面向实体、面向业务模型,让代码更贴近业务语义,而非底层数据结构。

相关推荐
爱喝水的鱼丶1 天前
SAP-ABAP:新手入门篇——从0到1写出你的第一个ABAP Hello World程序并完成调试运行
运维·服务器·数据库·学习·sap·abap
爱喝水的鱼丶2 天前
SAP-ABAP:第二篇:实操避坑篇——ABAP Hello World程序创建、语法校验到调试运行全流程指南
运维·服务器·数据库·学习·sap·abap
HeathlX4 天前
SAP-BTP :(5)RAP-CDS VIEW发布ODATA UI Service
abap
HeathlX5 天前
SAP-BTP :(4)RAP-创建CDS DATA模型映射和拓展
abap
爱喝水的鱼丶5 天前
SAP-ABAP:ABAP Development Tools(ADT)安装配置学习分享教程(四篇连载) 第三篇:ADT常用开发插件与个性化配置教程
数据库·学习·sap·abap
爱喝水的鱼丶5 天前
SAP-ABAP:ABAP Development Tools(ADT)安装配置学习分享教程(四篇连载) 第二篇:ADT客户端完整安装与初始配置教程
运维·开发语言·学习·sap·abap
爱喝水的鱼丶6 天前
SAP-ABAP:ABAP Development Tools(ADT)安装配置学习分享教程(四篇连载)第四篇:ADT连接故障排查与环境迁移教程
运维·开发语言·数据库·学习·sap·abap
爱喝水的鱼丶7 天前
SAP-ABAP:SAP 与 ABAP 关联逻辑与入门路径:业务×开发的协作指南
服务器·前端·数据库·学习·sap·abap
爱喝水的鱼丶9 天前
SAP-ABAP:SAP 系统变量 SY-INDEX 学习笔记:从 1 开始的循环计数器
运维·开发语言·数据库·sap·abap