nodejs中mysql模块在写SQL语句时办法往往如下:
const SQL= 'SELECT * FRON users WHERE user_name=?'
db.query(SQL, ['张三'], (err, res) => {
if(err)console.log(err);
console.log(res);
})
//'张三'会被填充至SQL语句的?中
封装SQL
显然数据库不止一张表,所有接口里的数据库操作都如上操作,会很麻烦,要写很多的SQL语句,自然我们就想到对数据库操作进行封装。如下:
//错误版本
module.exports = {
select: (params, callback) =>
db.query('SELECT ? FROM ? WHERE ?', params, (err, res) =>
dbMW(err, res, callback)
),
insert: (params, callback) =>
db.query('INSERT INTO ? SET ?', params, (err, res) =>
dbMW(err, res, callback)
),
updata: (params, callback) =>
db.query('UPDATA ? SET ? WHERE ?', data, (err, res) =>
dbMW(err, res, callback)
)
};
/**
* @description:
* @param {*} err 报错
* @param {*} res 成功
* @param {*} callback 回调处理
* @return {*}
*/
function dbMW(err, res, callback) {
if (err) {
console.log(`ERROR IN MYSQL:${err}`);
throw err;
} else {
return callback(res);
}
}
上面封装中存在一个问题,就是mysql模块,在用参数data,替换前面SQL语句中的'?'时会保留字符串的引号。我们知道在写sql语句时,字段名、表名、键名是不能加上引号的,这样会报错或无法正确查找到数据。如下:
模板字符串,就能很好的解决引号的问题。
我们用模板字符串再进行如下的封装:
module.exports = {
select: (params, callback) =>
db.query(`SELECT ${params.target} FROM ${params.table} WHERE ${params.where}`, (err, res) =>
dbMW(err, res, callback)
),
insert: (params, callback) =>
db.query(`INSERT INTO ${params.table} SET ${params.set}`, (err, res) =>
dbMW(err, res, callback)
),
updata: (params, callback) =>
db.query(`UPDATA ${params.table} SET ${params.set} WHERE ${params.where}`, (err, res) =>
dbMW(err, res, callback)
)
};
当然上面的封装也会存在额外的问题,就是原本db.query的第二个参数是很灵活的,可以是对象,字符串,数组。
但笔者觉得模板字符串封装的版本更为灵活,因为如上的写法我们可以灵活的拓展sql语句。以select为例,我们可以将 params.where 赋予 `u_id = '1' and u_name = '张三'` 这样的值去多条件查询。
回调地狱
上一步完善的封装是通过callback函数实现的,在连续的数据库操作中存在回调地狱问题。下面我们用Promise再封装一版:
function dbMW(err, res, resolve, reject) {
if (err) {
console.log(`ERROR IN MYSQL:${err}`);
reject(err)
//抛出错误,使得错误级中间件捕获
throw err;
} else {
resolve(res);
}
}
module.exports = {
select(params) {
return new Promise((resolve, reject) => {
db.query(
`SELECT ${params.select} FROM ${params.table} WHERE ${params.where}`,
(err, res) => dbMW(err, res, resolve, reject)
);
});
},
insert(params) {
return new Promise((resolve, reject) => {
db.query(`INSERT INTO ${params.table} SET ${params.set}`, (err, res) =>
dbMW(err, res, resolve, reject)
);
});
},
updata(params) {
return new Promise((resolve, reject) => {
db.query(
`UPDATA ${params.table} SET ${params.set} WHERE ${params.where}`,
(err, res) => dbMW(err, res, resolve, reject)
);
});
}
};