| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | 'use strict';/** * sql语句构建器 * * @author CaiAoLin * @date 2017/10/11 * @version */class SqlBuilder {    /**     * 构造函数     *     * @return {void}     */    constructor() {        this.resetCondition();    }    /**     * 设置andWhere数据     *     * @param {String} field - where中的字段名称     * @param {Object} data - where中的value部分     * @return {void}     */    setAndWhere(field, data) {        if (Object.keys(data).length <= 0) {            return;        }        this.andWhere.push({ field, data });    }    /**     * 更新字段设置     *     * @param {String} field - set的字段     * @param {Object} data - set中的字段     * @return {void}     */    setUpdateData(field, data) {        if (Object.keys(data).length <= 0) {            return;        }        this.setData.push({ field, data });    }    /**     * 重置条件     *     * @return {void}     */    resetCondition() {        this.andWhere = [];        this.orWhere = [];        this.columns = [];        this.limit = -1;        this.offset = -1;        this.orderBy = [];        this.setData = [];        this.sql = '';        this.sqlParam = [];        this.type = 'select';    }    /**     * 类型设置     *     * @param {String} tableName - 表名     * @return {void}     */    _typeBuild(tableName) {        switch (this.type) {            case 'select':                this.sql = this.columns.length === 0 ? 'SELECT * FROM ??' : 'SELECT ?? FROM ??';                this.sqlParam = this.columns.length === 0 ? [tableName] : [this.columns, tableName];                break;            case 'update':                this.sql = 'UPDATE ?? SET ';                this.sqlParam = [tableName];                break;            case 'delete':                this.sql = 'DELETE FROM ??';                this.sqlParam = [tableName];                break;            default:                break;        }    }    /**     * 设置update数据     *     * @return {void}     */    _setDataBuild() {        if (this.setData.length <= 0) {            return;        }        const setDataArr = [];        for (const set of this.setData) {            if (set.data.literal) {                const values = set.data.value instanceof Array ? set.data.value : [set.data.value];                setDataArr.push(' ?? = ' + set.data.literal + '(' + values.join(',') + ')');                this.sqlParam.push(set.field);            } else {                const tmp = set.data.selfOperate !== undefined ?                    ' ?? = IF(IsNull(??), 0, ??) ' + set.data.selfOperate + ' ' + set.data.value : ' ?? = ' + set.data.value;                setDataArr.push(tmp);                // 如果是自身操作则压多一次字段进数组                if (set.data.selfOperate !== undefined) {                    this.sqlParam.push(set.field);                    this.sqlParam.push(set.field);                }                this.sqlParam.push(set.field);            }        }        const setString = setDataArr.join(',');        this.sql += setString;    }    /**     * andWhere设置     *     * @return {void}     */    _andWhereBuild() {        if (this.andWhere.length <= 0) {            return;        }        const whereArr = [];        for (const where of this.andWhere) {            if (where.data.operate === 'in') {                // in操作                const valueLength = where.data.value instanceof Array ? where.data.value.length : 1;                // 生成参数集                const inArr = [];                for (let i = 0; i < valueLength; i++) {                    inArr.push('?');                }                const inData = inArr.join(',');                whereArr.push(' ?? IN (' + inData + ')');                this.sqlParam.push(where.field);                // 赋值参数                this.sqlParam.push.apply(this.sqlParam, where.data.value);            } else {                // 普通操作                whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);                this.sqlParam.push(where.field);            }        }        const whereString = whereArr.join(' AND ');        this.sql += this.sql.indexOf('WHERE') > 0 ? whereString : ' WHERE ' + whereString;    }    /**     * orWhere设置     *     * @return {void}     */    _orWhereBuild() {        if (this.orWhere.length <= 0) {            return;        }        const whereArr = [];        for (const where in this.orWhere) {            whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);            this.sqlParam.push(where.field);        }        const whereString = whereArr.join(' OR ');        // 如果前面已经有设置过WHERE则不需要再重复添加        this.sql += this.sql.indexOf('WHERE') > 0 ? whereString : ' WHERE ' + whereString;    }    /**     * limit设置     *     * @return {void}     */    _limitBuild() {        if (typeof this.limit !== 'number' || this.limit <= 0) {            return;        }        this.offset = parseInt(this.offset);        this.offset = isNaN(this.offset) || this.offset < 0 ? 0 : this.offset;        const limitString = this.offset >= 0 ? this.offset + ',' + this.limit : this.limit;        this.sql += ' LIMIT ' + limitString;    }    /**     * orderby 设置     *     * @return {void}     */    _orderByBuild() {        if (this.orderBy.length <= 0) {            return;        }        const orderArr = [];        for (const index in this.orderBy) {            orderArr.push(' ?? ' + this.orderBy[index][1]);            this.sqlParam.push(this.orderBy[index][0]);        }        const orderByString = orderArr.join(',');        this.sql += ' ORDER BY ' + orderByString;    }    /**     * 构建sql     *     * @param {String} tableName - 表名     * @param {String} type - 类型     * @return {Array} - 返回数组,第一个元素为sql语句,第二个元素为sql中问号部分的param     */    build(tableName, type = 'select') {        this.type = type;        this._typeBuild(tableName);        if (this.sql === '') {            throw '类型错误';        }        this._setDataBuild();        this._andWhereBuild();        this._orWhereBuild();        this._limitBuild();        this._orderByBuild();        const sql = this.sql;        const sqlParam = this.sqlParam;        // 重置数据        this.resetCondition();        return [sql, sqlParam];    }}module.exports = SqlBuilder;
 |