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
}; 

本拼接工具只适用於单表操作,多表操作请自行在单表操作的基础上封装。

用法

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