MYSQL SQL拼接工具

最近用到node+express+mysql開發後端業務,但是sql的拼寫相當麻煩,特別是查詢條件的拼接,故書寫了如下工具,方便sql生成。

/*查詢字段 */
interface fieldsProps { //distinct name as aname
    expression: any; //字段表達式,對應數據庫字段,例如distinct name
    alias: string;   //別名
}

/*where條件 */
interface whereProps {   //where name=? and 
    expression: string; //條件表達式,例如name=?
    valueField: string;    //數據對應字段
    value: any;      //表達式中?的值
    relation: string;   //關係,and、or
}

/*排序 */
interface orderByProps {
    field: string; //排序字段
    direction: string;   //排序方向,desc/asc
}

interface limitProps {
    begin: number;   //起始位置
    end: number;     //結束位置
}

interface sqlOptionsProps {
    type: string;
    fields: null | fieldsProps[];
    tableName: string;
    where: null | whereProps[];
    orderBy: null | orderByProps[];
    limit: null | limitProps;
}


/**
 * 
 * @param type //sql類型,select、insert、update、delete
 * @param fields //查詢字段,默認爲空,查詢所有字段
 * @param tableName //表名
 * @param where //where條件,默認爲空,即無條件
 * @param orderBy //排序條件,默認爲空,即不排序
 * @param limit   //分頁參數,存在時默認查詢前10條數據
 */
const getSqlStr = (
    type: string,
    fields: null | fieldsProps[] = [],
    tableName: string,
    where: null | whereProps[] = [],
    orderBy: null | orderByProps[] = [],
    limit: null | limitProps = { begin: 0, end: 9 }
) => {
    let sql = "";
    //表名
    if (!tableName) {
        console.log("表名不能爲空!")
    }
    switch (type) {
        case "select":
        case "SELECT":
            //sql類型
            sql += "SELECT ";
            //查詢字段
            if (fields && fields.length > 0) {
                for (let field of fields) {
                    if (field.expression) {
                        sql += field.expression;
                    }
                    if (field.alias) {
                        sql += " AS " + field.alias
                    }

                    sql += ",";
                }
                //去掉末尾的,
                sql = sql.substring(0, sql.length - 1);
            } else {
                sql += "*";
            }

            sql += " FROM " + tableName;

            //where條件
            if (where && where.length > 0) {
                let whereStr = joinWhere(where);
                sql += whereStr
            }

            //order by
            if (orderBy && orderBy.length) {
                sql += " ORDER BY ";
                for (let i = 0; i < orderBy.length; i++) {
                    let order = orderBy[i];
                    sql += `${order.field} ${order.direction}`;
                    //添加逗號
                    if (i != orderBy.length - 1) {
                        sql += ","
                    }
                }
            }

            //limit
            if (limit) {
                sql += ` limit ${limit.begin},${limit.end}`;
            }

            break;

        case "insert":
        case "INSERT":
            sql += `INSERT INTO ${tableName}(`;
            if (fields && fields.length > 0) {
                //設置新增字段
                for (let i = 0; i < fields.length; i++) {
                    let field = fields[i];
                    sql += `${field.expression}`
                    if (i != fields.length - 1) {
                        sql += ","
                    } else {
                        sql += ")"
                    }
                }

                //設置新增值,新增和編輯的值用?代替,使用mysql的傳參方式傳入,
                //因爲參數入庫涉及到參數類型校驗,例如日期格式,前端檢驗相當麻煩,所以直接交由mysql的Api處理
                sql += " VALUE(";
                for (let i = 0; i < fields.length; i++) {
                    let field = fields[i];
                    sql += "?"
                    if (i != fields.length - 1) {
                        sql += ","
                    } else {
                        sql += ")"
                    }
                }
            } else {
                console.log("新增表字段不能爲空!")
            }

            break;

        case "update":
        case "UPDATE":
            sql += `UPDATE ${tableName} SET `;
            if (fields && fields.length > 0) {
                for (let i = 0; i < fields.length; i++) {
                    let field = fields[i];
                    sql += `${field.expression}=?`
                    if (i != fields.length - 1) {
                        sql += ","
                    }
                }
            } else {
                console.log("修改表字段不能爲空!")
            }

            //where條件
            if (where && where.length > 0) {
                let whereStr = joinWhere(where);
                sql += whereStr
            }
            break;
        case "delete":
        case "DELETE":
            sql += `DELETE FROM ${tableName}`;
            if (where && where.length > 0) {
                let whereStr = joinWhere(where);
                sql += whereStr
            }
            break;
    }
    return sql;
}

//參數解析
const sqlJoin = (sqlOptions: sqlOptionsProps) => {
    let type = sqlOptions.type || "select";
    let fields = sqlOptions.fields;
    let tableName = sqlOptions.tableName;
    let where = sqlOptions.where;
    let orderBy = sqlOptions.orderBy;
    let limit = sqlOptions.limit;
    return getSqlStr(type, fields, tableName, where, orderBy, limit);
}

//組裝wehre條件
const joinWhere = (where: whereProps[]) => {
    let whereStr = "";
    //where條件
    whereStr += " WHERE ";
    for (let i = 0; i < where.length; i++) {
        let wh = where[i]
        if (wh.value) {
            wh.expression = wh.expression.replace("?", wh.value)
        }

        whereStr += wh.expression;
        if (i != where.length - 1) {
            whereStr += " " + wh.relation + " ";
        }
    }
    return whereStr;
}

const setWhereValue = (whereList: any[], searchObj: any) => {
    let whereArr = []
    if (searchObj) {
        for (let where of whereList) {
            let value = searchObj[where.valueField];
            let valueType = Object.prototype.toString.call(value);
            switch (valueType) {
                case "[object Null]":
                case "[object Undefined]":
                    break;
                case "[object Number]":
                    where.value = value;
                    whereArr.push(where);
                    break;
                default:
                    where.value = `'${value}'`;
                    whereArr.push(where);
                    break;
            }
        }
    }
    return whereArr;
}

module.exports = {
    sqlJoin,
    setWhereValue
}; 

本拼接工具只適用於單表操作,多表操作請自行在單表操作的基礎上封裝。

用法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章