1. 程式人生 > >nodeJs快速拼接sql,獲取用於事務控制的sql_params物件

nodeJs快速拼接sql,獲取用於事務控制的sql_params物件

nodeJs快速拼接sql,獲取sql_params[]

之前開發一個專案,一開始是MongoDB,後來因為事務不好控制,改用Mysql,導致很多方法不可用,並且拼接sql很麻煩,所以寫了一個工具來實現快速拼接sql,快速獲取sql_params[]物件用於事務控制,程式碼如下,不盡完善,請大家指正共同進步!

  • 獲取where後的條件字串:傳參格式{a:’a’,b:’%??%’,c:{in:['c1','c2']},'or’:{d:’d’,e:’e’}} –返回sql字串where
exports.pushParam = function (conditionMap, cb)
{
var sql = ''; if (isEmpty(conditionMap)) { if (cb) cb('傳入引數為空', null) return sql; } for (var i in conditionMap) { var j = fn(conditionMap[i]); if (Array.isArray(conditionMap[i][j])) { if (j.toLowerCase() == '$in' || j.toLowerCase() == 'in'
) { sql += " AND " + i + " IN ("; for (var k in conditionMap[i][j]) { sql += '"' + conditionMap[i][j][k] + '",'; } sql = sql.substr(0, sql.length - 1); sql += ") "; } else if (j.toLowerCase() == '$nin'
|| j.toLowerCase() == 'nin' || j.toLowerCase() == 'not in') { sql += " AND " + i + " NOT IN ("; for (var k in conditionMap[i][j]) { sql += '"' + conditionMap[i][j][k] + '",'; } sql = sql.substr(0, sql.length - 1); sql += ") " } } else if (i.toLowerCase() == '$or' || i.toLowerCase() == 'or') {//or 的條件回到一個conditionMap物件 sql += ' AND (' for (var m = 0; m < conditionMap[i].length; m++) { sql += '(' sql += exports.pushParam(conditionMap[i][m]).replace(/AND/, 'OR').replace(/OR/, '');//遞迴 sql += " OR "; sql = sql.substr(0, sql.length - 3); sql += ") OR "; } sql = sql.substr(0, sql.length - 3); sql += ")"; } else if (Array.isArray(conditionMap[i])) {//直接傳陣列時,用in來解析 sql += " AND " + i + " IN ("; for (var k in conditionMap[i]) { sql += '"' + conditionMap[i][k] + '",'; } sql = sql.substr(0, sql.length - 1); sql += ") " } else { if (conditionMap[i].toString().indexOf('%') > -1 || conditionMap[i].toString().indexOf('_') > -1 || conditionMap[i].toString().indexOf('[') > -1) { sql += " AND " + i + ' LIKE "' + conditionMap[i] + '"'; } else { sql += " AND " + i + ' = "' + conditionMap[i] + '"'; } } } function isEmpty(obj) { for (var i in obj) return false; return true; } function fn(obj) {//返回index for (var i in obj) { return i; } return false; } if (cb) { return cb(null, sql) } return sql; };
  • 獲取where後的條件字串:傳參格式{a:’a’,b:’%??%’,c:{in:['c1','c2']},'or’:{d:’d’,e:’e’}} 返回sql_params[]物件包含where後的 a=? and b=? 字串和params[]
exports.getTransactionSqlParams = function (conditionMap, cb) {
    var sql = '';
    var params = [];
    for (var i in conditionMap) {
        var j = fn(conditionMap[i]);
        if (Array.isArray(conditionMap[i][j])) {
            if (j.toLowerCase() == '$in' || j.toLowerCase() == 'in') {
                sql += " AND " + i + " IN (";
                for (var k in conditionMap[i][j]) {
                    sql += '?,';
                    params.push(conditionMap[i][j][k]);
                }
                sql = sql.substr(0, sql.length - 1);
                sql += ") ";
            }
            else if (j.toLowerCase() == '$nin' || j.toLowerCase() == 'nin' || j.toLowerCase() == 'not in') {
                sql += " AND " + i + " NOT IN (";
                for (var k in conditionMap[i][j]) {
                    sql += '?,';
                    params.push(conditionMap[i][j][k]);
                }
                sql = sql.substr(0, sql.length - 1);
                sql += ") ";
            }
        }
        else if (i.toLowerCase() == '$or' || i.toLowerCase() == 'or') {//or 的條件回到一個conditionMap物件
            sql += ' AND (';
            for (var m = 0; m < conditionMap[i].length; m++) {
                sql += '(';
                var sqlParams = exports.getTransactionSqlParams(conditionMap[i][m]);
                sql += sqlParams.sql.replace(/AND/, 'OR').replace(/OR/, '');
                for (var k in sqlParams.params) {
                    params.push(sqlParams.params[k])
                }
                sql += " OR ";
                sql = sql.substr(0, sql.length - 3);
                sql += ") OR ";
            }
            sql = sql.substr(0, sql.length - 3);
            sql += ")";
        }
        else if (Array.isArray(conditionMap[i])) {//直接傳陣列時,用in來解析
            sql += " AND " + i + " IN (";
            for (var k in conditionMap[i]) {
                sql += '?,';
                params.push(conditionMap[i][k]);
            }
            sql = sql.substr(0, sql.length - 1);
            sql += ") "
        }
        else {
            if (conditionMap[i].toString().indexOf('%') > -1 || conditionMap[i].toString().indexOf('_') > -1 || conditionMap[i].toString().indexOf('[') > -1) {
                sql += " AND " + i + ' LIKE ? ';
                params.push(conditionMap[i]);
            } else {
                sql += " AND " + i + ' = ? ';
                params.push(conditionMap[i]);
            }
        }

    }

    function fn(obj) {//返回index
        for (var i in obj) {
            return i;
        }
        return false;
    }

    if (cb) return cb({sql: sql, params: params});
    return {sql: sql, params: params};
};
  • 獲取查詢語句 傳入條件(表名,顯示欄位,排序欄位,排序方式,查詢起始記錄數,查詢長度,回撥(可選)),需要呼叫上面的pushParam(),返回快速拼接的sql
exports.selectSqlStr = function (tableName, field, conditionMap, orderBy, desc, start, length, cb) {
    var sql = '';
    if (isEmpty(field)) {
        sql += ' select * ';
    } else {
        sql += ' select ';
        for (var i in field) {
            sql += field[i] + ',';
        }
        sql = sql.substr(0, sql.length - 1);
    }
    if (!tableName) {
        if (cb) cb('表名不存在!', null)
        return '';
    } else {
        sql += ' from ' + tableName + ' where 1=1 ';
    }
    if (!isEmpty(conditionMap)) {
        sql += exports.pushParam(conditionMap);//呼叫拼接查詢條件
    }
    if (orderBy && desc) {
        sql += ' ORDER BY ' + orderBy + (desc == 'desc' ? ' desc ' : ' asc ');
    }
    if (length && typeof length === 'number') {
        if (!start || !(typeof start === 'number') || start == 0) {
            start = 0;
        }
        sql += ' limit '
        sql += parseInt(start) + ',';
        sql += parseInt(length) ? parseInt(length) : 0;
    }
    if (sql) {
        if (cb) cb(null, sql);
        return sql;
    } else {
        if (cb) cb('拼接錯誤,請檢查拼接條件', null);
        return '';
    }
}
  • 插入方法 (表名,插入欄位),返回sql_params[]
exports.insertSqlEntity = function (tableName, conditionMap, cb) {
    var params = [];
    var sql = "insert into " + tableName + " (";
    for (var i in conditionMap) {
        sql += "" + i + ",";
        params.push(conditionMap[i]);
    }
    sql = sql.substr(0, sql.length - 1);
    sql += ") value (";
    for (var i in conditionMap) {
        sql += "?,";
    }
    sql = sql.substr(0, sql.length - 1);
    sql += ") ";
    if (cb) {
        return cb(null, {
            sql: sql,
            params: params
        });
    }
    return {sql: sql, params: params};
};
  • 刪除/修改方法(動作[delete/update],表名,刪除/修改條件,修改物件,排序欄位,修改條數,排序方式,回撥【可選】),返回sql_params[]
exports.updateOrDeleteSqlEntity = function (action, tableName, findMap, objNew, orderBy, limit, desc, cb) {
    //查詢條件為空,危險操作!人為使得刪除或者修改時出錯
    if (isEmpty(findMap)) {
        findMap.thisIsAInexistentColumn = '這裡構造一個不可能存在的值,用於漏傳刪除條件時誤刪資料!';
        limit = '傳入一個非數字,讓資料庫報錯回滾!';
    }
    desc = (desc == 'desc') ? desc : 'asc';
    var sql = '';
    var params = [];
    if (action.toLowerCase() == 'update') {
        sql = "update " + tableName + " set ";
        if (!isEmpty(objNew)) {
            for (var i in objNew) {
                sql += i + "=?,";
                params.push(objNew[i]);
            }
        }
        sql = sql.substr(0, sql.length - 1);
    }
    else if (action.toLowerCase() == 'delete') {
        sql = "delete from " + tableName;
    }
    sql += " where 1=1 ";
    var aa = exports.getTransactionSqlParams(findMap);//拼接事務sql
    sql += aa.sql;
    var params1 = aa.params;//拼接事務sql
    for (var i in params1) {
        params.push(params1[i]);
    }

    if (orderBy) {
        sql += " order by " + orderBy + " ";
        if (desc) sql += desc;
    }
    if (limit) {
        sql += " limit " + limit;
    }
    if (cb) {
        return cb(null, {
            sql: sql,
            params: params
        });
    }
    return {sql: sql, params: params};
};

//判空
function isEmpty(obj) {
    for (var i in obj) {
        return false
    }
    return true;
}

不喜勿噴!