利用 Node.js 实现 SAP Hana 数据库编程接口

为什么80%的码农都做不了架构师?>>>   hot3.png

自 SAP HANA SP 11 之后,可以使用 Node.js 作为 Hana 的编程接口。SAP 将 Application server 简称为 XS。现在 XS 已经演化为 Advanced 版本。为了区别,早期的 XS 被称为 XS Classical。

从下图可以看出,和 Hana DB 进行交互的有 HANA XS Classical 、Hana Cloud Platform (HCP) 和 XS Advanced。而能够运行在 HCP 和 XS Advanced 的编程接口包括 XSJS (SAP 推出的服务器端 JavaScript,但目前看,社区并不活跃)、Node.js、Tomcat / TomEE (Java 应用程序编写)等。最近测试了 Node.js 编程接口,感觉还不错。

hdb 模块

Node.js 的编程接口模块是 hdb,可以用 npm install hdb 安装。Github 的源码地址为:node-hdb。有示例和说明,容易学习。

hdb CRUD

本文打算介绍两个方面:

  • hdb CRUD 的基本方法;

  • 以及如何利用 Node.js 的 express 框架实现 REST 风格 API (Restful API)。

先看看基本使用方法:

var hdb = require('hdb')var client = hdb.createClient({host: '192.168.2.100,port: 30015,user: 'STONE',password: 'pwd'
});client.connect(function(err){if (err){return console.error('Connect error', err);}var sql = 'SELECT * FROM STONE.EMP_MASTER';client.exec(sql, function(err, rows){if (err){return console.error('Execute error', err);}console.log('Results:', rows);});
});

和前几篇一样,仍然使用 STONE.EMP_MASTER 作为数据源。我们注意到,Node.js 广泛使用异步回调函数。使用异步的原因是 : Node.js 是单线程的,通过异步来避免阻塞 (blocking)。比如,从Hana 数据库查询 employees 表,但不知道需要多久能获得查询结果,通过异步机制,数据查询到之后放在 rows 中。

上面的 SQL 语句没有参数。下面通过 insert 语句来说明带参数 SQL 语句的处理方法。

client.connect(function(err){if (err){return console.error('Connect error', err);}var sql = 'INSERT INTO STONE.EMP_MASTER VALUES(?,?,?,?,?,?,?,?)';client.prepare(sql, function(err, statement){if (err){return console.error('Prepare error:', err);}var params = ['9001','Male',18,'test4@qq.com','13800-138000','Bachelor','Married',1];statement.exec(params, function(err, affectedRows){if (err){return console.error('Execute error:', err);}console.log('Affected rows:', affectedRows);});});
});
  • client.prepare() 先处理语句,成功后放在 statement

  • statement.exec() 语句执行查询,函数的第一个参数是 SQL 语句的参数。注意这个参数是数组类型,即使只有一个参数,也要使用数组。

提供 REST 风格的 Service

使用 Node.js 的 express 框架来实现。网上有非常多使用 express 创建 REST 风格 API 的教程,这里就不细说步骤了。后面会介绍怎样在 OpenUI5 中通过 Rest Service 来对对数据库进行增删改查。

  • 安装 Node.js

  • 创建一个文件夹,在文件夹中运行 npm init 创建 packages.json 文件。

  • 安装 express,这里提供一种方法: npm install express --save--save 参数会修改 packages.json 文件。

  • 安装 body-parser。这个模块将处理 post 请求,对 post 请求进行解析。

工程的文件结构如下:

主要文件有:

  • server.js : 启动服务
  • dbconfig.js: hana 数据库连接的配置信息
  • emp.controller.js: emp_master 表增删改查
  • emp_routes.js: 路由管理

先说明 package.json 文件,管理 app 依赖的模块:

{"name": "hana_app","version": "1.0.0","description": "hana in nodejs + express","main": "server.js","dependencies": {"body-parser": "^1.18.2","express": "^4.16.2","hdb": "^0.15.2"},"devDependencies": {},"scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "Stone Wang","license": "MIT"
}

server.js

var express = require('express');
var bodyParser = require('body-parser');var app = express();// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: true}));// parse requests of content-type - application/json
app.use(bodyParser.json());// home page
app.get('/', function(req, res){res.json('Welcome.');
});// register routes
var route = require('./app/routes/emp.routes.js')
route(app);// listen on port 3000
app.listen(3000, function(){console.log('Server is running on port 3000.');
});

server.js 中定义首页的响应,注册路由以及侦听 3000 端口。

dbconfig.js

保存数据库的配置信息,是一个对象:

module.exports = {hana:{host: '192.168.2.100',port: 30015,user: 'STONE',password: 'pwd'}
};

emp.controller.js

var hdb = require("hdb");
var dbconfig = require("../../config/dbconfig.js");var client = hdb.createClient(dbconfig.hana);// list all
exports.listAll = function(req, res){var sql = "SELECT * FROM STONE.EMP_MASTER";client.connect(function(err){if (err){res.send({"error": err.message});}client.exec(sql, function(err, rows){if (err){res.send({"error": err.message});}client.end();res.send({rows});});})
};// query by id
exports.queryById = function(req, res){var sql = "SELECT * FROM STONE.EMP_MASTER WHERE EMP_ID=?";client.connect(function(err){if (err){res.send({"error": err.message});}client.prepare(sql, function(err, statement){if (err){res.send({"error": err.message});}statement.exec([req.params.emp_id], function(err, rows){if (err){res.send({"error": err.message});}client.end();res.send({rows});});});});
};// create
exports.create = function(req, res){var sql = "INSERT INTO STONE.EMP_MASTER VALUES(?,?,?,?,?,?,?,?)";client.connect(function(err){if (err){res.send({"error": err.message});}client.prepare(sql, function(err, statement){if (err){res.send({"error": err.message});}var params = [req.body.EMP_ID,req.body.GENDER,req.body.AGE,req.body.EMAIL,req.body.PHONE_NR,req.body.EDUCATION,req.body.MARITAL_STAT,req.body.NR_OF_CHILDREN];statement.exec(params, function(err, data){if (err){res.send({"error": err.message});}client.end();res.sendStatus(200);});});});
};// update
exports.update = function(req, res){var sql = "UPDATE STONE.EMP_MASTER SET GENDER=?, AGE=?, EMAIL=?, PHONE_NR=?, EDUCATION=?, MARITAL_STAT=?, NR_OF_CHILDREN=? WHERE EMP_ID=?";client.connect(function(err){if (err){res.send({"error": err.message});}client.prepare(sql, function(err, statement){if (err){res.send({"error": err.message});}var params = [       req.body.GENDER,req.body.AGE,req.body.EMAIL,req.body.PHONE_NR,req.body.EDUCATION,req.body.MARITAL_STAT,req.body.NR_OF_CHILDREN,req.params.emp_id];statement.exec(params, function(err, data){if (err){res.send({"error": err.message});}client.end();res.sendStatus(200);});});});
};// delete
exports.delete = function(req, res){var sql = "DELETE FROM STONE.EMP_MASTER WHERE EMP_ID=?";client.connect(function(err){if (err){res.send({"error": err.message});}client.prepare(sql, function(err, statement){if (err){res.send({"error": err.message});}statement.exec([req.params.emp_id], function(err, data){if (err){res.send({"error": err.message});}client.end();res.sendStatus(200);});});});
};

emp.routes.js

module.exports = function(app){var empController = require("../controllers/emp.controller.js");// list allapp.get('/employees', empController.listAll);// query by IDapp.get('/employee/:emp_id', empController.queryById);// createapp.post('/employee/create', empController.create);// updateapp.put('/employee/:emp_id',empController.update);// deleteapp.delete('/employee/:emp_id', empController.delete);
};

使用 Postman 测试

在项目文件下,通过 node server.js 启动服务。然后打开 Postman 进行测试。以下是部分截图。

  • listAll

  • create

  • update

  • delete

  • update

 

转载于:https://my.oschina.net/fcweb/blog/1813688

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283231.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 实现自绘验证码

WPF 实现自绘验证码控件名:VerifyCode作者:WPFDevelopersOrg原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40;Visual Studio 2022;项目使用 MIT 开源许可协议;如何通过DrawingV…

css中的单位换算_CSS单位px、em、rem及它们之间的换算关系

作者:WangMin格言:努力做好自己喜欢的每一件事国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem,那么三者的区别与优势是什么?接下来我们就来学习一下吧!单位px、em、rem分别表示什么?1、 px(Pixel) 相对于显示…

【MAC】Ncnn 编译so文件方案

【MAC】Ncnn 编译so文件方案 1、下载ncnn github地址是:https://github.com/Tencent/ncnn 指定目录:在终端或者git管理工具 输入:git clone https://github.com/Tencent/ncnn.git 2、编译Ncnn 2.1 Mac平台 安装cmake、wget(根据实…

SSM学习注意杂记

2019独角兽企业重金招聘Python工程师标准>>> 1.spring导包时一定要版本对应,最好不要导不同版本的包,还有mybatis的包,springmvc的包,三个框架的包都需配套,要不然会出现一些想象不到的错误。 2.mybatis写映…

《ASP.NET Core 6框架揭秘》实例演示[15]:针对控制台的日志输出

针对控制台的ILogger实现类型为ConsoleLogger,对应的ILoggerProvider实现类型为ConsoleLoggerProvider,这两个类型都定义在 NuGet包“Microsoft.Extensions.Logging.Console”中。ConsoleLogger要将一条日志输出到控制台上,首选要解决的是格式…

《HeadFirst Python》第一章学习笔记

对于Python初学者来说,舍得强烈推荐从《HeadFirst Python》开始读起,这本书当真做到了深入浅出,HeadFirst系列,本身亦是品质的保证。这本书舍得已在《Python起步:写给零编程基础的童鞋》一文中提供了下载。为了方便大家…

Oracle-13:Oracle中的表分区

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客记录了表分区 表分区的含义: 典型的拿空间换时间的案例! 表分区对一张表进行分区,分区之后表中的数据存在相对应的分区内(可以是不…

js控制图像等比例缩放

<!DOCTYPE html> <html> <head><title>图片内部放大效果</title> <meta charset"utf-8"> <style type"text/css">#imgborder{ width: 200px;height: 160px;border: 3px solid #000; overflow: hidden;position:…

mysql一张表最多多少索引_MySQL一个索引最多有多少个列?真实的测试例子

MySQL一个索引最多有多少个列&#xff1f;真实的测试例子更新时间&#xff1a;2009年07月01日 22:22:21 作者&#xff1a;MySQL一个索引最多有多少个列&#xff1f;下面是具体的实现代码。最多16列。create table test (f1 int,f2 int,f3 int,f4 int,f5 int,f6 int,f7 int,f8…

.NET Core 使用 LibreOffice 实现 Office 预览(Docker 部署)

前些年做云盘产品的时候&#xff0c;一个很核心的功能就是 Office 文件预览&#xff0c;当时还没有使用 .NET Core ,程序部署在 Windows Server 服务器上&#xff0c;文件预览的方案采用了微软的 OWA 。目前在做的零代码产品中的表单附件控件&#xff0c;同样面临着 Office 文件…

[开源精品] C#.NET im 聊天通讯架构设计 -- FreeIM 支持集群、职责分明、高性能

&#x1f4bb; FreeIM 是什么&#xff1f;FreeIM 使用 websocket 协议实现简易、高性能&#xff08;单机支持5万连接&#xff09;、集群即时通讯组件&#xff0c;支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已正式改名为 FreeIM。使用场景&#xff…

用websploit获取管理员后台地址

1, use web/dir_scanner 2, set TARGET http://www.****.com 3, run SOURCE: https://sourceforge.net/projects/websploit/ WebSploit Advanced MITM Framework[]Autopwn – Used From Metasploit For Scan and Exploit Target Service[]wmap – Scan,Crawler Target Used Fro…

《ASP.NET Core 6框架揭秘》实例演示[16]:内存缓存与分布式缓存的使用

.NET提供了两个独立的缓存框架&#xff0c;一个是针对本地内存的缓存&#xff0c;另一个是针对分布式存储的缓存。前者可以在不经过序列化的情况下直接将对象存储在应用程序进程的内存中&#xff0c;后者则需要将对象序列化成字节数组并存储到一个独立的“中心数据库”。对于分…

人工智能教程007:创建一个卷积神经网络(2)

2019独角兽企业重金招聘Python工程师标准>>> 我们如何对图像应用卷积 当我们在图像上应用卷积时&#xff0c;我们在两个维度上执行卷积——水平和竖直方向。我们混合两桶信息&#xff1a;第一桶是输入的图像&#xff0c;由三个矩阵构成——RGB三通道&#xff0c;其中…

【系统知识点】linux入门基础命令

大概总结了一下一些基础命令&#xff0c;仅仅是帮助基础使用linux文件系统&#xff0c;如果还有相关基础命令&#xff0c;希望大家留言一起补充汇总一下&#xff01;命令的基本格式&#xff1a;格式&#xff1a;command [-options] parameter1 parameter2 …ps&#xff1a;第一…

Blazor University (48)依赖注入 —— Scoped 依赖

原文链接&#xff1a;https://blazor-university.com/dependency-injection/dependency-lifetimes-and-scopes/scoped-dependencies/Scoped 依赖Scoped 依赖项类似于 Singleton 依赖项&#xff0c;因为 Blazor 会将相同的实例注入到依赖它的每个对象中&#xff0c;但不同之处在…

c 连接mysql怎么增删改_C++ API方式连接mysql数据库实现增删改查

这里复制的http://www.bitscn.com/pdb/mysql/201407/226252.html一、环境配置1&#xff0c;装好mysql&#xff0c;新建一个C控制台工程(从最简单的弄起&#xff0c;这个会了&#xff0c;可以往任何c工程移植)&#xff0c;在vs2010中设置&#xff0c;工程--属性--VC目录--包含目…

阿里云如何实现海量短视频的极速分发?答案在这里!

摘要&#xff1a;短视频行业目前比较火热&#xff0c;但是如何快速的实现海量短视频的极速分发&#xff0c;对于短视频业务提供方来讲是一个比较棘手的问题。阿里云技术专家将带领大家从视频的上传、采集、存储和CDN分发等方面为我们介绍阿里云的整体方案&#xff0c;并且重点讲…

GitHub项目管理维护实用教程

GitHub项目维护教程 1&#xff09;注册GitHub账户并登陆&#xff1b; 2&#xff09;在Windows cmd&#xff08;或Ubuntu中的terminal&#xff09;中cd到自己的工作目录&#xff0c;将仓库clone下来&#xff1a; 命令&#xff1a; 1 git clone https://github.com/... #项目地址…

图文详解cacti的安装和使用

简介&#xff1a; 1.cacti介绍2.安装服务端3.安装客户端4.添加监控的设备cacti的介绍Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具Cacti是通过 snmpget来获取数据&#xff0c;使用 RRDtool绘画图形&#xff0c;而且你完全可以不需要了解RRDtool复杂…