SqlCondBase.java 5.93 KB
package com.yanzuoguang.dao.cond;

import com.yanzuoguang.dao.DaoConst;
import com.yanzuoguang.dao.impl.SqlData;
import com.yanzuoguang.dao.impl.SqlDataField;
import com.yanzuoguang.util.base.ObjectHelper;
import com.yanzuoguang.util.helper.StringHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 包含的值字段
 *
 * @author 颜佐光
 */
public abstract class SqlCondBase<T extends SqlCondBase> implements SqlCond<T> {

    protected List<String> fields = new ArrayList<>();

    protected Runnable debugRunnable = null;

    /**
     * 构造函数
     *
     * @param fields
     */
    public SqlCondBase(List<String> fields) {
        for (String field : fields) {
            if (!StringHelper.isEmpty(field)) {
                this.fields.add(field);
            }
        }
    }

    /**
     * 获取包含的字段
     *
     * @return
     */
    @Override
    public List<String> getFields() {
        return this.fields;
    }

    /**
     * 获取字段值
     *
     * @param model
     * @return
     */
    @Override
    public List<Object> getValues(Object model) {
        List<Object> rets = new ArrayList<>();
        for (String field : this.fields) {
            rets.add(ObjectHelper.get(model, field));
        }
        return rets;
    }

    /**
     * 当前条件是否相等
     *
     * @param model    请求参数实体
     * @param sqlField 请求字段
     * @return
     */
    protected abstract int getCondType(Object model, SqlDataField sqlField);

    /**
     * 获取新的SQL语句
     *
     * @param sql
     * @param sqlData
     * @param sqlDataField
     * @param model
     * @param codeMap
     * @return
     */
    @Override
    public String getSql(String sql, SqlData sqlData, SqlDataField sqlDataField, Object model, Map<String, List<String>> codeMap) {
        if (sqlDataField.getCond() != this) {
            throw new RuntimeException("不能处理非本条件的字段");
        }
        if (debugRunnable != null) {
            // 用于断点调试的支持
            debugRunnable.run();
        }
        int condType = getCondType(model, sqlDataField);
        switch (condType) {
            case COND_TYPE_CONST_ONLY_PARA: {
                for (String field : this.fields) {
                    // 进行SQL语句参数替换,后面增加一个空格,方便后续用正则表达式进行替换处理
                    sql = sql.replaceFirst("\\?", "@" + field + " ");
                }
                break;
            }
            case COND_TYPE_CODE_COND: {
                String fieldName = this.fields.isEmpty() ? StringHelper.EMPTY : this.fields.get(0);
                // 判断代码片段是否合法
                if (sqlDataField.getCodes().size() % 2 == 1) {
                    throw new RuntimeException("代码片段" + this.getClass().getSimpleName() + ":" + sqlData.getName() + ":" + fieldName + "为单数");
                }
                // 处理代码片段
                for (int i = 0; i < sqlDataField.getCodes().size(); i = i + DaoConst.CODE_UNIT) {
                    String codeName = sqlDataField.getCodes().get(i);
                    String codeValue = sqlDataField.getCodes().get(i + 1);
                    codeValue = codeValue.replaceAll("\\?", "@" + fieldName + " ");
                    addCodeMap(codeMap, codeName, codeValue);
                }
                break;
            }
            case COND_TYPE_NONE:
            default:
                break;
        }
        return sql;
    }


    /**
     * 将代码片段添加到SQL语句中
     *
     * @param codeMap 映射关系
     * @param name    执行的代码片段
     * @param code    代码片段
     */
    protected void addCodeMap(Map<String, List<String>> codeMap, String name, String code) {
        name = name.toLowerCase();
        if (!codeMap.containsKey(name)) {
            codeMap.put(name, new ArrayList<String>());
        }
        List<String> arr = codeMap.get(name);
        arr.add(code);
    }

    /**
     * 判断字段集合是否相等
     *
     * @param fromFields 来源字段
     * @param toFields   目标字段
     * @return
     */
    protected static boolean eqaulsField(List<String> fromFields, List<String> toFields) {
        Map<String, Boolean> mapField = new HashMap<>();
        for (String fromField : fromFields) {
            String from = fromField.toLowerCase().replaceAll("_", "");
            mapField.put(from, true);
        }
        for (String toField : toFields) {
            String to = toField.toLowerCase().replaceAll("_", "");
            if (mapField.containsKey(to)) {
                mapField.remove(to);
            } else {
                return false;
            }
        }
        return mapField.isEmpty();
    }

    /**
     * 判断值是否相等
     *
     * @param fromFields 来源字段
     * @param toFields   目标字段
     * @return
     */
    protected static boolean eqaulsValues(List fromFields, List toFields) {
        Map<Object, Boolean> mapField = new HashMap<>();
        for (Object fromField : fromFields) {
            Object from = fromField != null ? fromField : StringHelper.EMPTY;
            mapField.put(from, true);
        }
        for (Object toField : toFields) {
            Object to = toField != null ? toField : StringHelper.EMPTY;
            if (mapField.containsKey(to)) {
                mapField.remove(to);
            } else {
                return false;
            }
        }
        return mapField.isEmpty();
    }

    @Override
    public boolean equals(Object to) {
        if (to != null && to.getClass() == this.getClass()) {
            return this.equalsExecute((T) to);
        }
        return super.equals(to);
    }

    /**
     * 判断条件是否相等
     *
     * @param cond
     * @return
     */
    @Override
    public boolean equalsExecute(SqlCondBase cond) {
        return SqlCondBase.eqaulsField(this.fields, cond.fields);
    }
}