封装SQL语句
核心操作,前一篇的 help 就可以实现了,下面要封装SQL,避免手撸SQL的尴尬。
思路有点像 ORM,但是又不完全是 ORM,采用 meta + model 的形式拼接参数化的SQL语句。
insert into —— addModel
从SQL语句的角度来看,是 insert into table
,从对象的角度来看,就是添加了一个model。
不管怎么说,都是需要一个SQL语句才行,如果手撸的话,既麻烦又容易出错,那么怎么办呢?我们可以先设定一个 meta 进行描述,然后写个函数拼接即可。
- meta
{
"tableName": "node_user",
"idKey": "id",
"cols": {
"name": "",
"age": ""
}
}
由表名、主键字段名、需要的字段集合组成,这个看起来好像是一个表、字段的结构,其实并不是,区别在于字段集合的组成方式。
一般情况是基于表建立的 model,需要把表的字段都加上,不能少。
但是这里的 meta 并不要求把表里面的字段都加上,而是根据业务需求设置字段,业务需要哪些字段就放置哪些字段,不需要的可以不放。
另外一个表可以设置多种这样的 meta,完全依据业务需求来决定。
- 实现代码
/data-add.js
/**
* 实现添加数据的功能。拼接 insert 的 SQL语句
* @param { MySQLHelp } help 访问数据库的实例
* @param { Object } meta 表、字段
* @param { Object } model 数据
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象
* @returns 添加记录的ID
* * meta 结构:
* * * tableName: '', 表名
* * * cols:{colName: '类型'}, josn 字段需要标记
* * model 结构:
* * * colName: value
*/
function addData(help, meta, model, cn = null) {
// 拼接添加用的SQL语句,
// 提交SQL语句
const myPromise = new Promise((resolve, reject) => {
// sql = 'INSERT INTO aaa set aaacol = ? '
// 获取字段名称和值的数组
const { colNames, params } = help.createTableCols(meta, model)
const sql = `INSERT INTO ${meta.tableName} SET ${colNames.join(',')} `
console.log('addData --- sql:', sql, params)
const _cn = cn === null ? help.db : cn
help.query(sql, params, _cn)
.then((res) => {
// console.log('添加数据成功:', res.insertId)
resolve(res.insertId)
})
.catch((res) => {
// 出错了
reject(res)
})
})
return myPromise
}
module.exports = addData
如果使用事务的话,需要传递一个链接对象进来,否则使用内部默认的连接对象。
- help 实现基础功能的实例。
- meta 上面说到的表、字段的描述
- model 要添加的数据
使用方式
// 引入help
const { addModel } = require('../../packages/mysql.js')
console.log('\n★ add 文件被加载\n')
/**
* 实现添加服务
* @param {object} userInfo 当前登录人的信息
* @param {object} help 访问数据库的实例
* @param {object} serviceInfo 服务的 meta
* @param {object} model 前端提交的 body
* @returns 返回新添加的记录的ID
*/
const add = (userInfo, help, serviceInfo, model) => {
return new Promise((resolve, reject) => {
// 加载meta
modelName = serviceInfo.model
const info = require(`../../public/model/${modelName}.json`)
addModel(help, info, model).then((newId) => {
resolve({ newId })
}).catch((err) => {
reject('添加数据出错!')
})
})
}
module.exports = add
添加服务需要的meta,实现放在服务器上面,根据文件名称加载进来,并不需要(像Graph那样需要)前端提交。
这样一个实现添加数据的服务就实现了,当然还比较粗糙,缺少必要的验证。
数据验证可以再做一个校验层来搞定,这里默认model是可以信任的。
源码:
https://gitee.com/naturefw/node-services
https://gitee.com/naturefw/node-services/tree/master/packages
网友评论