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.YzgError; 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 YzgError.getRuntimeException("025"); } 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 YzgError.getRuntimeException("026", 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); } }