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

自 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

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

  1. php连接sap hana数据库,SAP Hana 数据库编程接口 - ODBC

    对于 Windows 平台,SAP 提供了三种编程接口:ODBC, MDX (用于 Excel) 和 ADO.NET Provider.但在我的 Windows 系统上测试,ADO.NET Provi ...

  2. java获取hana接口数据,SAP Hana 数据库编程接口 - JDBC

    Hana JDBC 驱动 安装 SAP HANA Client 后,安装目录的 ngdbc.jar 就是 JDBC 数据库驱动.主要注意 url 的写法和 Driver 的名称 : Driver: c ...

  3. 如何使用 Node.js 访问 SAP HANA Cloud 数据库里的数据

    登录 SAP Business Technology Platform,找到 space 下自己创建好的 HANA Cloud 实例,右键菜单选择 Copy SQL Endpoint,将 HANA C ...

  4. 「跨域」利用node.js实践前端各种跨域方式(上)

    前言 常言道,"读万卷书,不如行万里路".技术的学习也是如此,唯有实践才能更清楚的明白原理和加深印象,因此本文会利用node.js对前端的各种跨域方式进行实践,强烈建议一步一步跟着 ...

  5. 如何更好的利用Node.js的性能极限

    通过使用非阻塞.事件驱动的I/O操作,Node.js为构建和运行大规模网络应用及服务提供了很好的平台,也受到了广泛的欢迎.其主要特性表现为能够处理庞大的并且高吞吐量的并发连接,从而构建高性能.高扩展性 ...

  6. 使用ABAP(ADBC)和Java(JDBC)连接SAP HANA数据库

    在表DBCON里维护一条记录,指向HANA数据库.con_ENV里填入HANA数据库的主机名和端口号.如vmXXXX:30015 DATA: ls_new TYPE DBCON.ls_new-con_ ...

  7. 区块链】利用Node.js开发与合约交互的Web界面

    区块链]利用Node.js开发与合约交互的Web界面 2018-03-11 16:10:37 宣之于口 阅读数 6128  收藏 更多 分类专栏: 区块链 区块链学习笔记 版权声明:本文为博主原创文章 ...

  8. node.js require 自动执行脚本 并生成html,利用node.js实现自动生成前端项目组件的方法详解...

    本文主要给大家介绍了关于利用node.js实现自动生成前端项目组件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 脚本编写背景 写这个小脚本的初衷是,项目本身添加一个组件太 ...

  9. 使用ABAP(ADBC)和Java(JDBC)连接SAP HANA数据库 1

    在表DBCON里维护一条记录,指向HANA数据库.con_ENV里填入HANA数据库的主机名和端口号.如vmXXXX:30015 DATA: ls_new TYPE DBCON.ls_new-con_ ...

最新文章

  1. python培训比较好的机构-python哪家的培训比较好?
  2. python内置函数中的 IO文件系列 open和os
  3. 前端学习(1850)vue之电商管理系统电商系统vue脚手架安装
  4. 解决VMware6.5 以上版本安装RHEL 5的自动安装的问题
  5. (七)使用Docker进行人脸识别
  6. iOS 11更新第6个开发者测试版,变化最大的竟然是App Store标识
  7. html5+php调用android手机图片,HTML5拍照上传图片Phonegap封装HTML5调用Android相机拍照上传到PHP端...
  8. Fatal error in launcher: Unable to create process using 'd:\bld\scrapy_1584555997548\_h_env\python.
  9. 带控制面板英伟达驱动下载地址
  10. 混淆的艺术-(苍井空变凤姐)Proguard源码分析(一)前言和计划
  11. jsp为什么被淘汰了?
  12. C语言————输出It‘s a computer中的computer
  13. 仿照Flexstroe3写的一个员工管理应用 (三)
  14. tp6 SQL调试常用操作
  15. C语言鼠标操作方法及源码
  16. 什么是智能安全帽,如何选购智能安全帽
  17. 有趣的转义字符,常见转义字符大全,转义字符速查手册 Escape character
  18. 看看 NF_HOOK 宏
  19. vue中使用echarts实现动态数据绑定、获取后端接口数据
  20. termux命令行美化oh my zsh

热门文章

  1. nginx修改upstream不重启的方法(ngx_http_dyups_module模块)
  2. Docker-machine创建虚机时停在虚机启动的提示上,并且创建的虚机显示Ip Not found...
  3. 在 Docker 中使用 flannel - 每天5分钟玩转 Docker 容器技术(60)
  4. ora-01591:锁被未分布式事物处理/Distrib tran
  5. JStorm2.1.1集群的安装和使用
  6. 【好程序员笔记分享】C语言之break和continue
  7. FFLIb Demo CQRS
  8. C#判断某软件是否安装
  9. 彻底删除 XP 自带的 Windows Messenger方法
  10. [转载]AXIS学习笔记