道者编程


基于nodejs的mysql简单封装

驱动基于第三方的mysqljs包,地址:https://github.com/mysqljs/mysql

npm install mysql mysql2 --save

安装后引入文件,比如db.js

const mysql=require('mysql');

/*
function __connection(){
    let connection = mysql.createConnection({
        host     : '127.0.0.1',
        user     : 'root',
        password : '123',
        database : 'test', //数据库名
        port     : '3306', //3306端口
        charset  : 'utf8mb4_unicode_ci', //编码
        timezone : '08:00', //时区
        debug : true
    });
    connection.connect();
    return connection;
}

//对外
exports.query=function(sql,params=null){
    let connection = __connection();
    return new Promise(function(reject,resolve){
        let query = connection.query(sql,params,function(error, results, fields){
            //logCustom(query.sql) //sql日志
            if (error) {
                //logCustom(error)
                //throw error
                console.error('error connecting: ' + error)
                resolve('mysql error') //抛出异常
            }
            reject(results)
        })
        //3关闭连接
        connection.end()
    })
};

*/

//采用连接池
let pool  = mysql.createPool({
    connectionLimit : 10, //最大连接数,默认10
    host     : '127.0.0.1',
    user     : 'root',
    password : '123',
    database : 'test', //数据库名
    port     : '3306', //3306端口
    charset  : 'utf8mb4_unicode_ci', //编码
    timezone : '08:00', //时区
    debug : true
  });

exports.query = ( sql, values ) => {
    if(data.see == 1){ //返回标准sql语句
        sql = 'a'+sql
        return new Promise(( resolve, reject ) => {
            pool.getConnection( (error, connection) => {
                if (error) { 
                    resolve (error.sqlMessage)
                } else {
                    let query = connection.query(sql, values, ( error, rows) => {
                    resolve( query.sql.slice(1) ) 
                    //connection.release() //释放连接
                    })
                }
                
            })
        })
    }

    return new Promise(( resolve, reject ) => {
        pool.getConnection( (error, connection) => {
            if (error) {
                //logCustom(error)
                console.error('error connecting: ' + error)
                reject('mysql error') //抛出异常
            } else {
                let query = connection.query(sql, values, ( error, rows) => {
                    data.bind = ''
                //logCustom(query.sql) //sql日志
                if ( error ) {
                    //logCustom(error)
                    console.error('error query: ' + error)
                    reject('mysql error') //抛出异常
                } else {
                    resolve( rows )
                }
                connection.release() //释放连接
                })
            }
        })
    })
}

let data = { dbname:'' , fileds:'*' , where:'' , order:'' , limit:'' , group:'' , see:'' , leftJoin:[] , rightJoin:[] , join:[] , bind:''}


/**
* 防注入
*/
exports.escape = function escape(str){
    return pool.escape(str)
}


/**
 * 获取一条
 */
exports.first = function(sql='') {
    sql =  splic(sql)
    reset()
    try {
        return this.query(sql,data.bind).then(rows => {
            if(data.see == 1){
                return rows
            }else{
                return rows[0]
            }
            
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 获取全部
 */
exports.get = function(sql='') {
    sql =  splic(sql)
    reset()
    try {
        return this.query(sql,data.bind).then(rows => {
            return rows
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 获取一个字段,如果为空,返回空字符串
 *
 */
exports.getField = function(filedName,sql=''){
    sql =  splic(sql)
    reset()
    try {
        return this.query(sql,data.bind).then(rows => {
            if(data.see == 1){
                return rows
            }else {
                if(rows.length){
                    return rows[0][filedName]
                }else{
                    return ''
                }
            }
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 获取总数 SELECT * FROM table
 */
exports.count = function (sql='') {
    sql =  splic(sql)
    reset()
    if ( sql.indexOf("FROM") !=-1 ){
        strSp = ' FROM '
    }else{
        strSp = ' from '
    }
    sqlList = sql.split(strSp)


    sql = 'SELECT count(*) AS count FROM '+sqlList[1]
    try {
        return this.query(sql,data.bind).then(rows => {
            if(data.see == 1){
                return rows
            }else {
                return rows[0].count
            }
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 插入数据,返回自增ID
 * fileds = {name: 'Hello MySQL'}
 */
exports.insert = function (table,fileds) {
    let sql = 'INSERT INTO '+table+ ' SET ?'
    try {
        return this.query(sql,fileds).then(rows => {
            if(data.see == 1){
                return rows
            }else {
                return rows.insertId
            }
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 删除数据,返回影响行数
 */
exports.delete = function (table,where) {
    let sql = 'DELETE FROM '+table+' WHERE '+where
    try {
        return this.query(sql).then(results => {
            if(data.see == 1){
                return results
            }else {
                return results.affectedRows
            }
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 更新数据 返回影响行数
 * fileds = {name: 'Hello MySQL'}
 */
exports.update = function(table,fileds,where) {
    let sql = 'UPDATE '+table+' SET '
    let field = ''
    let values = []
    for (let index in fileds){
        field += index+'= ?, '
        values.push(fileds[index])
    }
    field = field.replace(/^(\s|,)+|(\s|,)+$/g, '')
    sql += field + ' WHERE '+where
    try {
        return this.query(sql,values).then(results => {
            if(data.see == 1){
                return results
            }else {
                return results.changedRows
            }
        })
    } catch (err) {
        return new Promise((resolve, reject) => {
            reject(err)
        })
    }
}


/**
 * 事务处理
 */
exports.beginTransaction = function () {
    return new Promise((resolve, reject) => {
        pool.getConnection((error, connection) => {
            if (error) {
                //logCustom(error);
                console.error(`error connecting: ${error}`);
                reject(error); // 抛出异常
            } else {
                data.connection = connection;
                data.connection.beginTransaction();
                resolve(connection);
            }
        });
    });
};


/**
 * 提交事务
 */
exports.commit = function () {
    return new Promise((resolve, reject) => {
        data.connection.commit((err) => {
            if (err) {
                // console.log(err)
                reject(err);
                // resolve('mysql error')
            } else {
                resolve();
            }
        });
    });
};


/**
 * 回滚
 */
exports.rollback = function (connection) {
    return new Promise((resolve, reject) => {
        data.connection.rollback((err) => {
            if (err) {
                reject(err);
                // resolve('mysql error')
            } else {
                resolve();
            }
        });
    });
};


/**
 * 返回 SQL语句
 */
exports.see = function () {
    data.see = 1
}


/**
 * 拼凑SQL
 */
splic = function (sql='') {
    if( sql != '' ) {
        return sql
    }
    let sqldata = 'SELECT '+data.fileds+' FROM '+data.dbname


    if( data.leftJoin.length >= 0 ) {
        let left = ''
        for (let index in data.leftJoin){
            left += data.leftJoin[index]
        }
        sqldata += left
    }


    if( data.rightJoin.length >= 0 ) {
        let right = ''
        for (let index in data.rightJoin){
            right += data.rightJoin[index]
        }
        sqldata += right
    }


    if( data.join.length >= 0 ) {
        let join = ''
        for (let index in data.join){
            join += data.join[index]
        }
        sqldata += join
    }


    if( data.where != '' ) {
        sqldata += data.where
    }


    if( data.group != '' ) {
        sqldata += data.group
    }


    if( data.order !='' ) {
        sqldata += data.order
    }


    if( data.limit !='' ) {
        sqldata += data.limit
    }
    return sqldata
}


exports.dbname = function (table) {
    data.dbname = table
    return this
}


exports.fileds = function(fileds){
    data.fileds = fileds
    return this
}


exports.where = function(where,bind='') {
    if(bind == ''){
        data.where = ' WHERE '+where
    }else{
        data.where = ' WHERE '+where
        data.bind = bind
    }
    return this
}


exports.group = function(filed) {
    data.group = ' GROUP BY '+filed
    return this
}


exports.order = function(field,sort='ASC'){
    data.order = ' ORDER BY '+field+' '+sort
    return this
}


exports.limit = function (start,end=''){
    if(end !=''){
        data.limit = ' LIMIT '+start+','+end
    }else{
        data.limit = ' LIMIT '+start
    }
    return this
}


exports.leftJoin = function(tableName,where) {
    whereList = where.split('=')
    leftWhere = whereList[0].trim()+' = '+whereList[1].trim()
    data.leftJoin.push(' LEFT JOIN '+tableName+' ON '+leftWhere)
    return this
}


exports.rightJoin = function(tableName,where) {
    whereList = where.split('=')
    leftWhere = whereList[0].trim()+' = '+whereList[1].trim()
    data.leftJoin.push(' RIGHT JOIN '+tableName+' ON '+leftWhere)
    return this
}


exports.join = function(tableName,where) {
    whereList = where.split('=')
    leftWhere = whereList[0].trim()+' = '+whereList[1].trim()
    data.leftJoin.push(' INNER JOIN '+tableName+' ON '+leftWhere)
    return this
}


reset = function() {
    data.fileds = '*'
    data.where = ''
    data.order = ''
    data.limit = ''
    data.group = ''
    data.sql = ''
    data.leftJoin = []
    data.rightJoin = []
    data.join = []
}
 用法:

const db = require('db')
//查询单条
result = await db.dbname('goods').where("id = ?",[4]).order('id').first() //绑定参数,绑定自动转义
result = await db.dbname('goods').where('id = 7').group('id').first() //直接写参数
result = await db.dbname('goods').leftJoin('goods','a =b').where('id = 7').group('id').first() //左连接,支持多个
result = await db.dbname('goods').rightJoin('goods','a =b').where('id = 7').group('id').first() //右连接
result = await db.dbname('goods').join('goods','a =b').where('id = 7').group('id').first() //内连接
result = await db.first("SELECT * FROM goods WHERE id=4") //也可以直接写sql
return ctx.body = result

防止SQL注入有两种方法
1:使用escape方法,过滤where参数
let mobile = await db.escape('13512347890')
let name = await db.escape('liming')
data = await db.dbname('goods')
    .where(`mobile='${mobile}' AND name='${name}'`)
    .get();

2:使用占位符 ?  绑定参数
let mobile = '13512347890'
let name = 'liming'
data = await db.dbname('goods')
    .where('mobile=? AND name=?',[mobile,name])
    .get();


//查询所有
result = await db.get("SELECT * FROM goods") //也可以直接写sql
result = await db.dbname('goods').limit(8).get() //查询所有
result = await db.dbname('goods').limit(1,8).get()
return ctx.body = result


// 获取数量
result = await db.count("SELECT id , title , name from goods") //可以直接写
result = await db.dbname('goods').fileds('id,title').where("id != ?",[4]).count() //也可以构建
return ctx.body = result


//获取一个字段的值
result = await db.dbname('goods').where("id = ?",[7]).getField('title') //也可以构建
result = await db.getField('title','SELECT * FROM goods WHERE id=7') //可以直接写
return ctx.body = result


//插入,键值对入库 ,返回自增ID
fileds = {name:"hellow nodejs",title:"李大龙",age:23}
result = await db.insert('goods',fileds)
return ctx.body = result


//更新 ,键值对入库,加where条件 返回影响行数
fileds = {name:"hellow nodejs",title:"成龙",age:23}
result = await db.update('goods',fileds,'id = 7')
return ctx.body = result


//删除 返回影响行数
result = await db.delete('goods','id=4')
return ctx.body = result


//原生SQL
result = await db.query(sql) //这里写原生方式的增删查改


//获取sql语句
db.see() //获取sql语句


//比如获取查询语句
db.see() //首先设置获取sql语句
result = await db.get("SELECT * FROM goods") //这里返回的就是sql语句,其他所有的增删查改都是一样
return ctx.body = result

 事务用法:

await db.beginTransaction(); //开启事务
try {
    await db.insert('merchant_banks', banksFileds);
    await db.insert('merchant_manages', managesFileds);
    await db.update('shop_users', { mid: merchant_id }, `id = ${shop_user_id}`);
 
    await db.commit(); //提交
} catch (err) {
    await db.rollback(); //回滚
    throw err;
} finally {
    await db.release(); //释放
}
 


最新评论:
1楼 广东省深圳市 电信 发表于 2020-06-17 11:57:57
6666666666
共有 1 条记录  首页 上一页 下一页 尾页 1
我要评论:

看不清楚


道知

about me

身体是革命的本钱,健身,养生,运动,公众号都有!

链接