使用 SAP Cloud SDK 连接 OData 服务
Connect to OData service on Neo using SAP Cloud SDK
Virtual Data Model
S/4HANA 系统中存储的数据本质上结构复杂,因此很难手动查询。因此,HANA 引入了虚拟数据模型 (VDM),旨在从这种复杂性中抽象出来,并以语义上有意义且易于使用的方式提供数据。从 S/4HANA 系统使用数据的首选方式是通过 OData 协议。虽然出于兼容性原因也支持 BAPI,但 OData 应该始终是您的首选。您可以在 SAP 的 API 业务中心找到 S/4HANA Cloud 系统的所有可用 OData 端点的列表。
SAP Cloud SDK 现在将 VDM for OData 引入 Java 世界,使 OData 端点的类型安全使用更加简单! VDM 是使用来自 SAP API 业务中心的信息生成的。这意味着它与 API 业务中心提供的每个 API 兼容,因此也与每个 S/4HANA Cloud 系统兼容。
传统的 OData 服务访问方式:
让我们来看看我们可以编写的典型代码来访问任何使用 SAP Cloud Platform SDK 进行服务开发的 OData 服务。这里,我们从 S/4HANA 系统中检索业务合作伙伴列表:
final ErpConfigContext configContext = new ErpConfigContext();final List<MyBusinessPartnerType> businessPartners = ODataQueryBuilder .withEntity("/sap/opu/odata/sap/API_BUSINESS_PARTNER", "A_BusinessPartner") .select("BusinessPartner", "LastName", "FirstName", "IsMale", "IsFemale", "CreationDate") .build() .execute(configContext) .asList(MyBusinessPartnerType.class);
ODataQueryBuilder 代表了一种在应用程序中使用 OData 服务的简单通用方法,非常适合支持任意服务。 从手动构建到 OData 服务的 HTTP 请求并在代码中处理结果,这是向前迈出的一大步,并且由 SAP Cloud SDK 在内部使用。 反过来,ODataQueryBuilder 还使用 SAP Cloud SDK 的概念来简化与系统的通信,这些系统由 ErpConfigContext 引用。
然而,在使用普通的 ODataQueryBuilder 方法调用 OData 服务时,您可能会陷入一些陷阱:
对于 .withEntity("/sap/opu/odata/sap/API_BUSINESS_PARTNER", "A_BusinessPartner") 您已经需要知道三件事:OData 端点服务路径(/sap/opu/odata/sap)、端点名称(API_BUSINESS_PARTNER ) 和端点元数据中定义的实体集合 (A_BusinessPartner) 的名称。
然后,当您想要使用 select() 函数从 BusinessPartner 实体类型中选择特定属性时,您需要知道这些字段是如何命名的。但由于它们在此代码中仅表示为字符串,因此您需要查看元数据以了解它们的调用方式。这同样适用于 order() 和 filter() 等函数。当然,使用字符串作为参数很容易出现拼写错误,您的 IDE 很可能无法为您捕获这些错误。
最后,您需要定义一个类,例如 MyBusinessPartnerType,其中包含表示结果的属性及其类型的特定注释。为此,您再次需要了解有关 OData 服务的大量详细信息。
Virtual Data Model: The new way to OData
现在我们已经解释了当前方法可能存在的缺陷,让我们来看看 SAP Cloud SDK 的 OData VDM 如何简化相同的任务,因为 SDK 能够整合更多关于被调用系统的知识。
final List<BusinessPartner> businessPartners = new DefaultBusinessPartnerService() .getAllBusinessPartner() .select(BusinessPartner.BUSINESS_PARTNER, BusinessPartner.LAST_NAME, BusinessPartner.FIRST_NAME, BusinessPartner.IS_MALE, BusinessPartner.IS_FEMALE, BusinessPartner.CREATION_DATE) .execute();
使用 OData VDM,我们现在可以访问特定 OData 服务的对象表示,在本例中为 DefaultBusinessPartnerService(BusinessPartnerService 接口的默认实现)。所以现在不再需要知道端点的服务路径、服务名称或实体集合名称。我们可以调用该服务的 getAllBusinessPartner() 函数来从系统中检索所有业务合作伙伴的列表。
现在看一下 select() 函数。我们可以简单地使用 BusinessPartner 类提供的静态字段,而不是传递表示实体字段的字符串。因此,我们不仅消除了拼写错误的风险,而且还使其类型安全!同样,这同样适用于 filter() 和 orderBy()。例如,过滤男性业务伙伴变得像 .filter(BusinessPartner.IS_MALE.eq(true)) 一样简单——注意类型安全的比较。
这种方法的另一个好处是可发现性。由于所有内容都表示为代码,因此您可以简单地使用 IDE 的自动完成功能来查看服务支持哪些功能以及实体包含哪些字段:首先查看包 com.sap.cloud.sdk 中提供的不同服务.s4hana.datamodel.odata.services,实例化你需要的服务的默认实现(类名以Default为前缀),然后查找服务类中代表不同可用操作的方法。基于此,您可以使用返回类型的字段来选择要选择的字段和要应用的过滤器。
每个服务都由一个 Java 接口描述,例如 BusinessPartnerService。 SDK 为每个服务接口提供了一个默认的、完整的实现。相应的实现在名称为前缀为 Default 的接口名称的类中可用,例如 DefaultBusinessPartnerService。您可以简单地实例化该类,也可以将依赖注入与相应的 Java 框架结合使用。接口的好处是更好的测试和可扩展性支持。