背景
node.js 操作数据库的用法,目前只了解 mysql 和 oracledb 两个模块,它们的用法稍有不同。相比 oracledb,node.js 的 mysql 模块相对容易些,本文将整理 node.js 操作这两种数据库的通用方法,完成简单 SQL 语句的执行。
此外,node.js 操作数据库的过程跟 Java 的 JDBC 也有很大差异:ode.js 的数据库模块通过回调函数来处理数据库,可以在回调函数处理 results 之前关闭 connection 。而 Java 的 JDBC 操作数据库则需逐步从 Connection 到 ResultSet 顺次执行,如果未处理 ResultSet 就关闭 Connection 就会报异常。
基本用法
简略分析了下源码,发现 oracledb 和 mysql 的连接池对象提供的 getConnection 实现方式有所差异。
mysql 连接池的 getConnection 只能通过回掉函数完成对连接对象的处理,而且没有返回值,其源码为:
oracledb 连接池的 getConnection 可以返回一个包裹了 connection 的 Promise 对象,所以它支持 await 操作;同时它也支持与 mysql 一样的回调函数的处理方式。
其大致流程为:
(1)oracledb 的 getConnection 无参方法:
(2)getConnection 最终由nodbUtil 工具的 promisify 实现:
(3)promisify 返回了一个 Promise 对象:
另一种接受一个回调函数的 getConnection 的源码基本跟 mysql 的一致。
数据库操作封装
基于连接池的数据库操作,从 getConnection 的 API 实现来看,我总结出两种处理数据库操作结果的方式。
第一种,上层调用者传递回调函数 dbCallback,在数据库连接的回调函数中再调用该dbCallback 完成对操作结果的处理。
以 oracledb 为例,封装 execute 方法如下:
/**
* 数据库执行操作:外界提供回调函数,用于对查询结果进行处理
* 1、数据库连接的 execute 操作是一个异步请求,需要一个回掉函数
* 2、如果等待异步完成,则需要使用 await 后则可调用回调函数
* 3、外部调用者提供对数据的处理函数,然后在该数据库操作函数中调用回调函数。
*/
async function oracleExecuteByCallback(oracledb, sql,params,dbCallback) {
//回调函数参数封装对象
var resultData = {
status:0 //默认为失败状态
};
let connection;
try {
// Get a connection from the default pool
connection = await oracledb.getConnection();
//execute返回的是一个Promise对象
let results = await connection.execute(sql, params);
//成功:则记录操作结果
resultData.status = 1;
resultData.message = "操作成功";
resultData.data = results;
resultData.number = results.length;
} catch (err) {
//失败:记录失败信息
resultData.message = "连接数据库失败";
console.error(err);
} finally {
//关闭连接池
if (connection) {
try {
// Put the connection back in the pool
await connection.close();
} catch (err) {
console.error(err);
}
}
//统一执行回调
dbCallback(resultData);
}
};
第二种,整个数据库操作返回一个包裹了操作结果的 Promise 对象,由上层调用者去对操作结果进行处理,此时的关键在于数据库连接和执行回调函数中返回 Promise 的resolve 数据,demo 如下:
/**
* 数据库执行操作:异步返回方式
* 1、数据库连接的execute操作是一个异步请求,需要一个回调函数。
* 2、封装一个Promise对象,在getConnection的回调中处理查询结果,封装resolve返回对象。
* 3、外部调用者完成后续对resolve的对象的处理。
*/
function oracleExecuteByPromise(db, sql,params) {
return new Promise(async (resolve, reject) => {
try{
//数据库连接获取操作,需要传入一个回调函数,处理创建的连接。
db.getConnection(function(err, connection) {
if(err) {
console.error(err);
reject({
status: 0,
message: '连接数据库失败'
});
return;
}
//数据库SQL执行操作,需要传入一个回调函数,处理执行结果。
let _query = connection.execute(sql, params, function(err, results) {
if(err) {
console.error(err);
reject({
status: 0,
message:'操作失败'
});
return;
}
//释放连接
connection.release();
//返回操作执行成功的结果
resolve({
status: 1,
data: results,
number: results.length,
message:'操作成功'
});
})
})
}catch(err){
console.error(err);
reject({
status: 0,
message:'操作异常'
});
}
});
}
mysql 的封装过程与上述类似,只是 mysql 不支持 await 操作,其回调函数方式和Promise 方式都只能在数据库连接回调中处理。实现过程已经上传本人的 Github 仓库了,这里不再赘述,有兴趣的朋友可以看看。
地址为:https://github.com/woodvine/nodeJsCommonUtil/blob/master/oracledbUtil.js
参考资料
https://segmentfault.com/a/1190000007535316?utm_source=tag-newest
这篇文章将 async 和 await 解释的笔记清晰,用作参考。
oracledb 的官方资料,example 中有很多例子。
https://github.com/oracle/node-oracledb/
来源:CSDN
作者:毕小宝
链接:https://blog.csdn.net/wojiushiwo945you/article/details/87633001