nodeJs快速拼接sql,獲取用於事務控制的sql_params物件
阿新 • • 發佈:2019-01-29
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;
}
不喜勿噴!