相比于从零开始构建全套信息化系统,基于成熟的ERP等行业软件做二次开发是更多中大型企业应对个性化软件需求的首选方案。如何在二开模块中,可靠地对成品软件的数据库进行读写操作,以满足单据自动创建、元数据自动同步等系统集成要求,是摆在开发者面前的难题。今天,我们基于活字格低代码平台的技术支持工作中较为常见SAP HANA为例,为您介绍几种典型的路线。

方案1:通过ODBC直连HANA,操作原始数据

SAP HANA的客户端程序中提供了ODBC的数据源,这就使得开发团队可以直接通过ODBC连接HANA数据库,并通过SQL语句对数据库中的原始数据进行读写操作。

(通过ODBC操作HANA)

首先,我们需要在开发环境、测试环境和生产环境的服务器上,配置SAP提供的ODBC数据源。在安装有SAP Client(推荐x64)之后,打开系统的odbc数据源管理程序(注意区分64为和32位,需要和SAP Client保持一致)。在"系统DSN"选项卡中点击"添加",选择HDBODBC,之后按照界面提示输入数据源的名称,如"HANA-测试库"、服务器IP地址、用户名和密码就可以了。

(创建到HANA的ODBC数据源)

配置完成后,我们就可以像操作其他数据库一样,对 SAP HANA的数据进行读写了。回到活字格里面,我们使用"连接到外联表"功能,引入HANA中需要操作的所有数据表。之后就可以用拖拽的方式完成数据绑定,或者在服务端拼接和执行SQL语句了。

(在活字格低代码平台中引入ODBC数据源)

如果仅仅是读取元数据或者一些简单的单据,这种方案确实是一个简单的办法。但是,SAP的数据表结构复杂,且缺乏有效的数据库脚本跟踪能力,我们很难确定一个单据创建过程需要操作哪几张表的哪些字段。所以,在涉及到稍微复杂一点的应用场景时,通过ODBC直接操作原始数据的做法的风险较高。

(纯代码,通过ODBC操作HANA的数据表)

基于多年的技术支持经验,我们通常不会推荐客户采用这个方案。

方案2:调用NetWeaver API,操作业务对象

SAP显然也清楚开发者直连HANA,操作原始数据带来的可靠性风险。所以,SAP推出了NetWeaver集成平台,给开发者提供了一个原厂级二开解决方案,"尽量"确保写入的数据不会对SAP系统运行造成威胁。然而,这个平台的开发成本依然不如人意,以至于大多数开发者在二开项目之初就放弃了这个方案。不过,NetWeaver中对数据表中原始数据的操作封装成对业务对象的操作,并加入了一些必要的校验逻辑,这一点对于二开来说还是非常有意义的。更重要的是,这些封装的接口是开放的,即便我们采用了其他的二开方案,依然可以通过RFC协议,调用NetWeaver提供的HANA操作能力,从而避免直接读写原始数据带来的风险。

引入NetWeaver后,二开模块可以不再直接操作HANA数据库,而是通过位于二开服务器上的RFC桥(如果对可维护性要求不高,也可直接集成到二开模块中)和位于SAP集群中的NetWeaver来完成。二开模块通过HTTP等协议调用RFC桥,RFC桥则通过RFC协议转调NetWeaver,NetWeaver则负责在HANA上直接对应的SQL语句。

之所以我们将RFC调用部分抽象成一个专门的RFC桥模块,主要是考虑到这部分采用了一个第三方组件库(SAP原厂的.NET SDK口碑不佳),将其与二开模块进行隔离,可有效降低维护风险。因为客户采用的是低代码的开发方式,这个RFC桥的实现方式为基于活字格服务端编程接口开发的自定义WebAPI。对于纯代码开发者来说,RFC桥通常是一个ASP.NET MVC或Java SpringBoot的Web服务。在实现逻辑和架构原理上,低代码与纯代码大同小异,都需要通过写代码的方式完成。

(通过RFC + NetWeaver操作HANA)

步骤一:使用C#开发调用NetWeaver的RFC桥

在这一步中,我们需要使用到Visual Studio(截屏是VS2021)、活字格服务端编程接口(截屏是活字格V7.0 Update1)、SAP NetWeaver RFC SDK(截屏是7.5)和开源项目SapNwRfc(https://github.com/huysentruitw/SapNwRfc)。其中SAP的SDK需要客户使用SAP账号,从SAP官网下载。

首先,我们在VS2021中创建.NET 4.7.2的类库工程,引用RFC SDK中lib文件夹的sapnwrfc.dll;然后通过nuget查找并安装SapNwRfc包和Microsoft.AspNetCore.Http.Abstractions包(活字格服务端编程接口需要依赖这个包);最后引用活字格服务器程序安装目录中的GrapeCity.Forguncy.ServerApi.dll。为了确保RFC SDK的正常运行,简化部署操作,我们更建议将RFC SDK的文件直接拷贝到系统盘下的某个目录,并且在系统的PATH变量中追加这个目录下面的lib文件夹,以确保运行时可以准确找到所引用的sapnwrfc.dll。

(Nuget中的SapNwRfc包)

然后,我们需要根据SAP的文档说明,创建RFC的传入和传出参数所对应的类。SAP为每一个NetWeaver接口准备一个Excel文件,记录了方法名,传入参数和传出参数的类型和结构。我们只需要找到所需调用的那个接口对应的Excel文件,根据文档要求创建入参和出参对应的class即可。需要注意的是,属性的名称、SapName标签的值需要和文档中的参数名严格保持一致。以创建供应商为例,我们需要创建传入参数类:CreateVendorParameters和传出参数类:createVendorParametersObj。

(NetWeaver中创建供应商的接口所对应的参数结构)

然后,我们在工程中创建WebAPI,一个继承自ForguncyApi的类GetSAPInfo,然后创建POST请求的响应方法CallRFCFunction(方法名和类名组成了URL的Path部分)。在代码中,我们从请求中读取连接字符串、需要使用的方法和参数,调用SapConnection类的对应方法进行处理,最后把结果序列化后返回给该WebAPI的调用者。和属性名称一样,调用SapConnection时传入的方法名也需要和文档中的文字严格保持一致,如创建供应商的方法名为ZLIFNR_CREATE。

(RFC桥的WebAPI实现)

根据既往经验,为了降低调用RFC桥的开发者的学习门槛,让他们也可以参照SAP提供的文档直接进行操作,我们推荐将所有用到的接口统合到一个WebAPI中,在代码中通过SAP的方法名进行switch分支。

如需使用这些示例代码,可以从码云获取:https://gitee.com/GrapeCity/lowcode_extention_demo_hana_via_sap_rfc

步骤二:在活字格中调用RFC桥

使用活字格服务端编程接口开发出的WebAPI与纯代码开发出的WebAPI的使用方法完全一致。在使用活字格开发业务系统的时候,都可以通过"发送HTTP请求"命令来调用。

首先,开发和测试的环境下,我们通常会连接不同的SAP数据库,所以,我们需要将连接NetWeaver所需的必要信息存储到数据库中,随程序一同发布,而不是写死在代码或全局配置文件中。

(存储在数据库中的NetWeaver连接信息)

在需要操作SAP的数据时,我们需要先使用"设置变量命令",从数据库中读取当前环境所使用的HANA数据库的参数,拼接成连接字符串;然后使用"发送HTTP请求命令",通过调用RFC桥的WebAPI。

按照步骤一中RFC桥的实现,其URL地址是customapi/{类名}/{方法名}。我们还需要在HEAD中设置连接字符串和方法名(来自SAP提供的Excel文档,如ZLIFNR_CREATE)。

(配置NetWeaver的连接字符串和方法名)

而具体的请求参数则需要在BODY中进行设置,将二开系统的业务数据作为参数传递给HANA,执行对应的数据操作,最终达到系统集成的效果,如这里举例的创建供应商档案。

(配置传递给NetWeaver的业务数据)

下面是我们帮助客户进行技术评估时,快速构建的活字格与SAP NetWeaver集成的Demo。如需使用这个工程,可以从码云获取:https://gitee.com/GrapeCity/lowcode_demo_hana_via_sap_rfc

(使用活字格集成SAP HANA的效果)

讨论

为了帮助开发者做二次开发,SAP和用友等主流厂商大多提供了直连数据库和封装业务接口两种开发模式。在纯代码开发方式下,两种模式最大的差异在于前者性能上限更高,后者可靠性更强。

进入低代码时代后,封装业务接口的模式体现出了更强的竞争优势。比如今天的例子中,在RFC桥的帮助下,业务应用的开发者能通过可视化配置,轻松实现对HANA数据库的读取和写入操作,而这一切,无需掌握任何一门编程语言。专业程序员借助平台的编程接口扩展平台能力,非专业程序员通过使用这些能力,可视化完成系统开发,这种"混合模式"正在成为低代码开发的主流。

还在写SQL做SAP二开?通过RFC调用NetWeaver,让HANA数据库操作更可靠的更多相关文章

  1. 屌炸天实战 MySQL 系列教程(二) 史上最屌、你不知道的数据库操作

    此篇写MySQL中最基础,也是最重要的操作! 第一篇:屌炸天实战 MySQL 系列教程(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:屌炸天实战 MySQL 系列教程(二) 史上最屌.你不 ...

  2. 《你还在写sql语句吗?》人生苦短,进入MybatisPlus的丝滑体验

    一.发展历程 依稀记得大学期间,类中写sql语句的日子,一个sql语句占据了大部分时间,到后来hibernate的出现算是解决了这一痛点.工作 后,我们又接触到了mybatis这样的框架,瞬间感觉这个 ...

  3. [SQL Server]用 C# 在 LinqPad 建立 Linked Server 跨服务器数据库操作

    在涉及老项目数据迁移的时候,数据库结构已经完全发生变化,而且需要对老数据进行特殊字段的处理,而且数据量较大,使用Navicat导出单表之后,一个表数据大概在100多万的样子,直接导出SQL执行根本行不 ...

  4. NC57,NC63-NC二开经验总结

    版主2010级市场营销专业本科生 2013年8月入达内培训Java相关技术 12月入职,做用友NC的二次开发工作 2015年4月离职,4中下旬入职一家互联网金融企业 下面是做NC二开期间积累的一些常用 ...

  5. SQL开发技巧(二) 【转】感觉他写的很好

    本文转自: http://www.cnblogs.com/marvin/p/DevelopSQLSkill_2.html 本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列 ...

  6. Python 数据分析:让你像写 Sql 语句一样,使用 Pandas 做数据分析

    Python 数据分析:让你像写 Sql 语句一样,使用 Pandas 做数据分析 一.加载数据 import pandas as pd import numpy as np url = ('http ...

  7. 还在用ABAP进行SAP产品的二次开发?来了解下这种全新的二次开发理念吧

    Jerry从2018年底至今,已经写了一系列关于SAP Kyma的文章,您可以移步到本文末尾获得这些文章的列表.Kyma是SAP开源的一个基于Kubernetes的云原生应用开发平台,能够允许SAP的 ...

  8. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  9. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

随机推荐

  1. Docker容器启动失败 Failed to start Docker Application Container Engine

    1.在k8s mster节点执行 1.kubectl get nodes 发现node节点没起来 [root@guanbin-k8s-master ~]# kubectl get nodes NAME ...

  2. 直播流媒体EasyDSS

    访问官方 http://www.easydss.com/ 点击试用下载 根据不同需求 选择不同版本 (我选择的右边) 下载完解压 双击 start.bat 看见如下图则成功 网页输入 http://i ...

  3. LAMP架构—源码编译安装 (爱情受过伤,为爱跳过鸭绿江)

    LAMP架构--源码编译安装 1.LAMP架构概述 2.编译安装Apache httpd 服务 3.编译安装mysql 服务 4.编译安装PHP 解析服务 5.利用LAMP搭建论坛 1.LAMP架构概 ...

  4. Charles抓包工具介绍

    1.Charles是什么? Charles是一款基于http协议的代理服务器,通过称为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的. 2.Charles有哪些用途? (1)能够分析前 ...

  5. pycharm关闭pytest

    在pycharm中,如果py文件以 test 开头,则运行时会使用pytest执行,pycharm关闭pytest方式如下 File -> Settings -> Tools -> ...

  6. unittest基础篇1

    转自http://blog.csdn.net/huilan_same/article/details/52944782 unittest是xUnit系列框架中的一员,如果你了解xUnit的其他成员,那 ...

  7. ClassPath资源的读取

    读取ClassPath的资源 在程序中经常有很多资源需要读取,常见的就是配置文件,Java中将文件当作一种资源来处理,可以使用Class或者ClassLoader来处理 一,使用Class类的getS ...

  8. python迭代器对象及异常处理

    内容概要 内置函数(可与匿名函数一起使用) 可迭代对象 迭代器对象 for循环内部原理 异常处理 内容详细 一.内置函数 # 1. map() 映射 l1 = [1, 3, 5, 7, 9] res ...

  9. [入门到吐槽系列] Webix 10分钟入门 一 管理后台制作

    前言 本人是服务端程序员,同时需要兼职前端开发.常用的就是原生态的HTML.Javascript,也用过ExtJS.Layui.可是ExtJS变公司后非常难用.Layui上手还行,用过一段时间,会觉得 ...

  10. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...