package com.yanzuoguang.dao.impl; import com.yanzuoguang.dao.TableAnnotation; import com.yanzuoguang.dao.cond.SqlCondDefault; import com.yanzuoguang.dao.cond.SqlCondEquals; import com.yanzuoguang.db.impl.DbRow; import com.yanzuoguang.util.base.MethodField; import com.yanzuoguang.util.base.ObjectHelper; import com.yanzuoguang.util.exception.RuntimeCodeException; import com.yanzuoguang.util.helper.StringHelper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; import static com.yanzuoguang.dao.DaoConst.*; /** * 表结构的基本信息 * * @author 颜佐光 */ public class TableStruct { private static final int WHERE_ADD = 1; private static final int WHERE_REMOVE_ADD = 2; private static final int WHERE_ADD_NOT = 0; /** * 数据库中的表名称 */ private String name; /** * 缓存的字段,根据字段的类型进行缓存,同一个字段可能会属于多个类型。 */ private final Map<Integer, List<TableFieldVo>> typeFieldCache = new HashMap<>(); /** * 构造函数 */ public TableStruct() { this.name = ""; } public TableStruct(String name) { this.name = name; } /** * 通过实体的字段来创建表结构信息 * * @param name 表名称 * @param cls 关联的实体,主键放在第一位,其他字段放到后面;需要注意的是必需和表结构对应起来,会有隐性BUG,比如说在实体中增加了字段,会导致增加修改失败 */ public TableStruct(String name, Class<?> cls) { this.name = name; // 获取实体中的所有字段信息,包含get、set、field HashMap<String, MethodField> fields = ObjectHelper.getTypeField(cls); // 遍历字段 for (Map.Entry<String, MethodField> entry : fields.entrySet()) { // 字段信息获取 MethodField field = entry.getValue(); if (field.getField() == null) { continue; } addMethodField(field); } } /** * 添加字段 * * @param field 添加字段 */ private void addMethodField(MethodField field) { int fieldAction = FIELD_NONE; // 默认后台数据库字段和前台参数字段为字段名,字段类型为class String fieldName = field.getName(); String fieldInputName = field.getName(); Class<?> fieldType = String.class; // 获取注解以及返回类型 TableAnnotation annotation = null; if (field.getField() != null) { annotation = field.getField().getAnnotation(TableAnnotation.class); fieldType = field.getField().getType(); } // 注解不为空,则修改后台数据库映射字段、字段类型 if (annotation != null) { if (!StringHelper.isEmpty(annotation.value())) { fieldName = annotation.value(); } fieldAction = annotation.type(); } this.addField(fieldName, fieldInputName, fieldType, fieldAction); } /** * 添加额外字段 * * @param fieldName 字段名称 * @param fieldInputName 字段输入名称 * @param fieldType 字段类型 * @param fieldAction 字段含义 */ public void addField(String fieldName, String fieldInputName, Class<?> fieldType, int fieldAction) { // 将字段组合成输入字段 TableFieldVo vo = new TableFieldVo(fieldName, fieldInputName, fieldType); // 根据字段名称规则来获取名称默认类型 int stringAction = getStringAction(vo); // 判断是否属于主键 int resultActionType = getActionType(fieldAction, stringAction); // 获取普通类型字段列表 List<TableFieldVo> commonActionList = this.getFieldActionList(FIELD_COMMON); if (resultActionType == FIELD_PRIMARY) { // 将历史主键添加到普通列,并且移除历史主键 List<TableFieldVo> primaryActionList = this.getFieldActionList(FIELD_PRIMARY); commonActionList.addAll(primaryActionList); primaryActionList.clear(); // 将现有列添加到主键 primaryActionList.add(vo); } else { // 将所有非主键列添加到普通列 commonActionList.add(vo); boolean isTypeMany = resultActionType != FIELD_MD5 && resultActionType != FIELD_REMOVE && resultActionType != FIELD_VERSION && resultActionType != FIELD_COMMON; if (resultActionType != FIELD_COMMON) { List<TableFieldVo> actionList = this.getFieldActionList(resultActionType); // 处理其他特殊列 if (isTypeMany) { actionList.add(vo); } else if (resultActionType == fieldAction) { // fieldAction 优先级高于 stringAction // 假如特殊列已经存在,则将已经存在的特殊列删除,并且添加新的特殊列 actionList.clear(); actionList.add(vo); } else if (actionList.isEmpty()) { // stringAction // 假如是默认的,并且特殊列已经存在,则不进行任何处理 actionList.add(vo); } } } } /** * 获取字段类型 * * @param fieldAction 字段类型 * @param stringAction 字符串字段类型 * @return 最终类型 */ private int getActionType(int fieldAction, int stringAction) { if (fieldAction != FIELD_NONE) { return fieldAction; } else { return stringAction; } } /** * 获取字符串动作类型 * * @param vo 输入子弹 * @return 获取到的自动类型 */ private int getStringAction(TableFieldVo vo) { if (getKey() == null) { return FIELD_PRIMARY; } else if (REMOVE_FLAG.equals(vo.inputLName)) { return FIELD_REMOVE; } else if (VERSION_FLAG.equals(vo.inputLName)) { return FIELD_VERSION; } // 判断是否属于统计字段 else if (MD5_KEY_FLAG.equals(vo.inputLName)) { return FIELD_MD5; } else if (vo.inputLName.startsWith(UPDATE_FLAG)) { return FIELD_REMOVE_UPDATE; } else if (vo.inputLName.startsWith(CREATE_FLAG)) { return FIELD_CREATE; } else { return FIELD_COMMON; } } /** * 获取某个类型的所有字段 * * @param type 某个类型,需要排除的类型 * @param exceptType 需要排除的字段的类型 * @return 字段列表 */ private List<TableFieldVo> getFieldActionList(int type, int... exceptType) { if (!typeFieldCache.containsKey(type)) { typeFieldCache.put(type, new ArrayList<>()); } List<TableFieldVo> from = typeFieldCache.get(type); if (exceptType == null || exceptType.length == 0) { return from; } else { // 缓存需要排除的子弹 Map<String, Boolean> exceptCache = new HashMap<>(10); for (int except : exceptType) { if (!typeFieldCache.containsKey(except)) { continue; } List<TableFieldVo> exceptList = typeFieldCache.get(except); for (TableFieldVo exceptField : exceptList) { exceptCache.put(exceptField.name, true); } } // 剩下的字段 List<TableFieldVo> to = new ArrayList<>(); for (TableFieldVo fromItem : from) { if (exceptCache.containsKey(fromItem.name)) { continue; } to.add(fromItem); } return to; } } /** * 获取某个类型的第一个字段 * * @param type 类型 * @return 获取到的子弹 */ private TableFieldVo getFieldAction(int type) { List<TableFieldVo> list = getFieldActionList(type); return !list.isEmpty() ? list.get(0) : null; } /** * 获取所有普通子弹 * * @return 所有的普通股字段 */ public List<TableFieldVo> getFields() { return getFieldActionList(FIELD_COMMON); } /** * 获取统计纬度列 * * @return 获取统计纬度列 */ public List<TableFieldVo> getGroupLatitudeFields() { return getFieldActionList(FIELD_COMMON, FIELD_ADD_GROUP, FIELD_REPLACE_GROUP, FIELD_MD5 ); } /** * 获取表名 * * @return 获取到的名称 */ public String getName() { return name; } /** * 设置表名 * * @param name 设置的表名 */ public void setName(String name) { this.name = name; } /** * 主键 * * @return 获取到的键值 */ public TableFieldVo getKey() { return getFieldAction(FIELD_PRIMARY); } /** * 主键名称 * * @return 主键名称 */ public String getKeyName() { return this.getKey().inputName; } /** * 主键数据类型 * * @return 主键类型 */ public Class<?> getKeyType() { return this.getKey().type; } /** * MD5缓存字段 * * @return md5字段 */ public TableFieldVo getMd5Key() { return getFieldAction(FIELD_MD5); } /** * MD5缓存键值 * * @return MD5名称 */ public String getMD5KeyName() { TableFieldVo md5Key = this.getMd5Key(); return md5Key != null ? md5Key.inputName : null; } /** * 判断是否包含版本号字段 * * @return 版本号字段 */ public TableFieldVo getVersion() { return getFieldAction(FIELD_VERSION); } /** * 判断是否包含remove字段 * * @return 删除字段 */ public TableFieldVo getRemove() { return getFieldAction(FIELD_REMOVE); } /** * 获取删除时更新字段 * * @return 删除时更新字段 */ public List<TableFieldVo> getRemoveUpdate() { return getFieldActionList(FIELD_REMOVE_UPDATE); } /** * 获取某一列 * * @param name 列名 * @return 获取到的字段 */ public TableFieldVo getField(String name) { if (StringHelper.isEmpty(name)) { return null; } for (TableFieldVo fieldVo : this.getFields()) { if (fieldVo.lName.equals(name.toLowerCase()) || fieldVo.inputLName.equals(name.toLowerCase())) { return fieldVo; } } throw new RuntimeCodeException("表" + this.name + "不存在列" + name); } /** * 获取某一列 * * @param fieldType 字段类型 * @return 获取到的字段 */ public List<TableFieldVo> getFields(int fieldType) { return getFieldActionList(fieldType); } /** * 通过表结构自动生成SQL语句 * * @return 初始化的表SQL语句 */ public void init(TableSqlCache table) { table.setTable(this); if (!StringHelper.isEmpty(this.name)) { table.add( releaseSqlReplace(), releaseSqlCreate(), releaseSqlUpdate().sortCond(), releaseSqlRemove().sortCond(), releaseSqlLoad().sortCond(), releaseSqlQuery().sortCond() ); } initSaveWith(table); initAddGroup(table); } /** * 初始化SaveWith * * @return 初始化的表SQL语句 */ private void initSaveWith(TableSqlCache table) { List<TableFieldVo> saveWithField = getFieldActionList(FIELD_SAVE_WITH); if (saveWithField == null || saveWithField.isEmpty()) { return; } this.addSaveWithSql(table, SAVE_WITH, saveWithField); } /** * 初始化添加统计SQL语句 * * @return 初始化的表SQL语句 */ private void initAddGroup(TableSqlCache table) { List<TableFieldVo> addGroupField = getFieldActionList(FIELD_ADD_GROUP); List<TableFieldVo> replaceGroupField = getFieldActionList(FIELD_REPLACE_GROUP); List<TableFieldVo> commonField = this.getGroupLatitudeFields(); this.addGroupSql(table, commonField, replaceGroupField, addGroupField); } /** * 生成创建的SQL语句 * * @return 生成的语句 */ private SqlData releaseSqlReplace() { return releaseSqlCreateReplace(SQL_REPLACE, REPLACE, SQL_TYPE_CREATE); } /** * 生成创建的SQL语句 * * @return 生成的语句 */ private SqlData releaseSqlCreate() { return releaseSqlCreateReplace(SQL_INSERT, CREATE, SQL_TYPE_CREATE); } private SqlData releaseSqlCreateReplace(String sqlModel, String sqlName, int sqlType) { // 生成添加的SQL语句 String text = sqlModel.replace(CODE_TABLE, this.name); SqlData sql = new SqlData(sqlName, text); sql.setSqlType(sqlType); TableFieldVo key = this.getKey(); // 第一个增加的字段,不需要增加 "," sql.addParaConst(key.inputName, CODE_FIELD, key.name, CODE_VALUES, CODE_PARA ); for (TableFieldVo field : this.getFields()) { sql.addParaConst(field.inputName, CODE_FIELD, CODE_SPLIT + field.name, CODE_VALUES, CODE_SPLIT + CODE_PARA ); } return sql; } /** * 生成修改的SQL语句 * * @return 生成的语句 */ private SqlData releaseSqlUpdate() { // 生成添加的SQL语句 SqlData sql = getUpdateSql(UPDATE, SQL_TYPE_UPDATE); TableFieldVo key = this.getKey(); sql.addConst(key.inputName, String.format(CODE_WHERE_EQUALS_PARA, key.name)); // 增加普通代码片段字段 List<TableFieldVo> updateList = getFieldActionList(FIELD_COMMON, FIELD_CREATE, FIELD_REMOVE, FIELD_VERSION); for (TableFieldVo field : updateList) { sql.addParaConst(field.inputName, CODE_FIELD, String.format(CODE_UPDATE_FIELD_PARA, field.name) ); } // 添加版本号条件 if (getVersion() != null) { sql.addConst(getVersion().inputName, String.format(CODE_WHERE_EQUALS_PARA, getVersion().name)); } return sql; } /** * 生成删除的SQL语句 * * @return 生成的语句 */ private SqlData releaseSqlRemove() { TableFieldVo remove = this.getRemove(); if (remove != null) { SqlData sql = getUpdateSql(REMOVE, SQL_TYPE_REMOVE); // 设置删除时需要修改的字段的值 for (TableFieldVo field : this.getFieldActionList(FIELD_REMOVE_UPDATE)) { sql.addParaConst(field.inputName, CODE_FIELD, String.format(CODE_UPDATE_FIELD_PARA, field.name) ); } // 生成逻辑删除WHERE条件 addWhereField(sql, CODE_TAG, true); return sql; } else { String text = SQL_REMOVE.replace(CODE_TABLE, this.name); SqlData sql = new SqlData(REMOVE, text); // 生成删除语句Where条件 addWhereField(sql, CODE_TAG, true); return sql; } } private SqlData getUpdateSql(String sqlName, int sqlType) { // 生成添加的SQL语句 String text = SQL_UPDATE.replace(CODE_TABLE, this.name); SqlData sql = new SqlData(sqlName, text); sql.setSqlType(sqlType); TableFieldVo key = this.getKey(); // 主键字段操作 sql.addCode(CODE_FIELD, String.format(CODE_UPDATE_PRIMARY, key.name, key.name)); // 设置删除字段标记 addUpdateRemoveField(sql); // 增加版本号字段的值 addUpdateVersionField(sql); return sql; } private SqlData releaseSqlQuery(String sqlName, int sqlType) { // 生成添加的SQL语句 String text = SQL_LOAD.replace(CODE_TABLE, this.name); SqlData sql = new SqlData(sqlName, text); sql.addParaConst(CODE_FIELD_DEFAULT_NAME, CODE_FIELD, CODE_FIELD_DEFAULT); sql.setSqlType(sqlType); // 生成加载语句的WHERE条件 addWhereField(sql, CODE_TAG, false); return sql; } /** * 生成加载的SQL语句 * * @return 生成的语句 */ private SqlData releaseSqlLoad() { return releaseSqlQuery(LOAD, SQL_TYPE_LOAD); } /** * 生成查询语句 * * @return */ private SqlData releaseSqlQuery() { return releaseSqlQuery(QUERY, SQL_TYPE_COMMON); } /** * 当前当前表所有字段的等于SQL语句 * * @param sql SDL语句 * @param tag 标记 * @param isRemove 是否生成删除相关字段 * @return 生成的语句 */ private void addWhereField(SqlData sql, String tag, boolean isRemove) { addWhereBase(sql, CODE_WHERE, tag, isRemove, false); // 查询时,不能查询到非删除的字段 addWhereRemove(sql); } /** * 对当前Sql语句进行扩展 * * @param sql 需要扩展的SQL语句 * @param tag 扩展标签 */ public void addWhereExtend(SqlData sql, String tag, boolean removeHistory, String... codes) { addWhereBase(sql, CODE_WHERE, tag, false, removeHistory, codes); } /** * 对当前Sql语句进行扩展 * * @param sql 需要扩展的SQL语句 * @param tag 扩展标签 */ public void addWhereExtend(SqlData sql, String codeName, String tag, boolean removeHistory, String... codes) { addWhereBase(sql, codeName, tag, false, removeHistory, codes); } private void addWhereBase(SqlData sql, String codeName, String tag, boolean isRemove, boolean removeHistory, String... codes) { addWhereFieldCommon(sql, codeName, this.getKey(), tag, removeHistory); // Where条件包含的字段 List<TableFieldVo> fields; if (!isRemove) { // 所有字段 fields = this.getFields(); } else { // 非删除时需要更新的字段 fields = this.getFieldActionList(FIELD_COMMON, FIELD_REMOVE_UPDATE); } List<String> codesField = new ArrayList<>(); // 添加普通的Where条件 for (TableFieldVo field : fields) { int isAdd = addWhereFieldCommon(sql, codeName, field, tag, removeHistory); if (isAdd != WHERE_ADD_NOT) { codesField.add(field.inputName); } } if (!codesField.isEmpty()) { sql.addPara(new SqlCondDefault(codesField), codes); } } private int addWhereFieldCommon(SqlData sql, String codeName, TableFieldVo field, String tag, boolean removeHistory) { addWhereFieldNotExtend(sql, field.inputName, codeName, String.format(CODE_WHERE_EQUALS, tag, field.name, CODE_PARA), removeHistory); // 添加in条件 String sqlIn = String.format(CODE_WHERE_IN, tag, field.name, CODE_PARA); return addWhereFieldNotExtend(sql, getArrayParameterName(field.inputName), codeName, sqlIn, removeHistory); } private int addWhereFieldNotExtend(SqlData sql, String inputName, String codeName, String sqlWhere, boolean removeHistory) { SqlDataField field = sql.getField(inputName); if (field == null) { // 添加新的条件 sql.addPara(inputName, codeName, sqlWhere); return WHERE_ADD; } else if (removeHistory) { // 删除历史条件 sql.removeField(inputName); // 添加新的条件 sql.addPara(inputName, codeName, sqlWhere); return WHERE_REMOVE_ADD; } return WHERE_ADD_NOT; } /** * 添加删除WHERE条件字段 * * @param sql SQL语句实体 */ private void addWhereRemove(SqlData sql) { TableFieldVo remove = this.getRemove(); if (remove != null) { sql.addPara(new SqlCondEquals(remove.inputName + OLD_FLAG, 0, 1, 2), CODE_WHERE, String.format(CODE_WHERE_EQUALS_NOT_REMOVE, this.getRemove().name) ).addPara(new SqlCondEquals(remove.inputName + OLD_FLAG, 3), CODE_WHERE, String.format(CODE_WHERE_REMOVE, this.getRemove().name) ); } } /** * 添加删除到更新SQL语句 * * @param sql 删除语句 */ private void addUpdateRemoveField(SqlData sql) { TableFieldVo remove = this.getRemove(); // 设置删除标记可以通过前台传入 if (remove != null) { if (sql.getSqlType() == SQL_TYPE_REMOVE) { sql.addParaConst(remove.inputName, CODE_FIELD, String.format(CODE_REMOVE_FIELD_REMOVE, remove.name, remove.name)); } else { sql.addParaConst(remove.inputName, CODE_FIELD, String.format(CODE_UPDATE_FIELD_REMOVE, remove.name)); } } } /** * 版本号进行累加 * * @param sql 需要处理的SQL语句 */ private void addUpdateVersionField(SqlData sql) { // 添加版本字段 TableFieldVo version = getVersion(); if (version != null) { sql.addCode(CODE_FIELD, String.format(CODE_UPDATE_VERSION_FIELD, version.name, version.name)); } } /** * 生成SQL语句 * * @param sqlType SQL语句类型 * @param name SQL语句名称 * @param model SQL语句模板 * @param valueModel 值字段模板 * @param valueFields 值字段 * @param whereFields WHERE字段 * @return 生成的SQL语句 */ private SqlData releaseSql(int sqlType, String name, String model, String valueModel, List<TableFieldVo> valueFields, List<TableFieldVo> whereFields) { // 生成修改的SQL语句 SqlData sql = new SqlData(name, model.replace(CODE_TABLE, this.name)); sql.setSqlType(sqlType); // 生成添加的SQL语句 String flag = StringHelper.EMPTY; for (TableFieldVo field : valueFields) { sql.addParaConst(field.inputName, CODE_FIELD, flag + valueModel.replace(CODE_FIELD, field.name)); flag = CODE_SPLIT; } for (TableFieldVo field : whereFields) { sql.addConst(field.inputName, String.format(CODE_WHERE_EQUALS_PARA, field.name)); } return sql; } /** * 根据来源字符串获取结束字符串 * * @param fieldFrom 来源字符串 * @return 返回字符串 */ private List<TableFieldVo> getFieldString(TableFieldString fieldFrom) { List<TableFieldVo> list = new ArrayList<>(); if (fieldFrom != null) { for (String fieldName : fieldFrom.getFields()) { list.add(this.getField(fieldName)); } } return list; } /** * 生成根据某些字段不存在则保存的SQL语句 * * @param tableStruct 表结构 * @param sqlName SQL语句 * @param whereFields WHERE条件 */ public void addSaveWithSql(TableSqlCache tableStruct, String sqlName, TableFieldString whereFields) { addSaveWithSql(tableStruct, sqlName, getFieldString(whereFields)); } /** * 生成根据某些字段不存在则保存的SQL语句 * * @param tableStruct 表结构 * @param sqlName SQL语句 * @param whereFields WHERE条件 */ private void addSaveWithSql(TableSqlCache tableStruct, String sqlName, List<TableFieldVo> whereFields) { SqlData sqlData = this.releaseSql(SQL_TYPE_SAVE_WITH, sqlName, SQL_LOAD, StringHelper.EMPTY, new ArrayList<>(), whereFields); sqlData.addParaConst(CODE_FIELD_DEFAULT_NAME, CODE_FIELD, CODE_FIELD_DEFAULT); tableStruct.add(sqlData); } /** * 生成统计的SQL语句 * * @param sqlTableData 需要生成的实体 * @param whereFields WHERE字段 * @param addFields 需要增加的值的字段 */ public void addGroupSql(TableSqlCache sqlTableData, TableFieldString whereFields, TableFieldString addFields) { addGroupSql(sqlTableData, whereFields, null, addFields); } /** * 生成统计的SQL语句 * * @param sqlTableData 需要生成的实体 * @param whereFields WHERE字段 * @param addFields 需要增加的值的字段 */ public void addGroupSql(TableSqlCache sqlTableData, TableFieldString whereFields, TableFieldString replaceFields, TableFieldString addFields) { addGroupSql(sqlTableData, getFieldString(whereFields), getFieldString(replaceFields), getFieldString(addFields)); } /** * 生成统计的SQL语句 * * @param sqlTableData 需要生成的实体 * @param replaceFields WHERE字段 * @param addFields 需要增加的值的字段 */ private void addGroupSql(TableSqlCache sqlTableData, List<TableFieldVo> whereFields, List<TableFieldVo> replaceFields, List<TableFieldVo> addFields) { List<TableFieldVo> prmaryKey = this.getFieldActionList(FIELD_PRIMARY); // 生成统计加载SQL语句 SqlData sqlLoad = this.releaseSql(SQL_TYPE_ADD_GROUP, GROUP_QUERY, SQL_LOAD, StringHelper.EMPTY, new ArrayList<>(), whereFields); sqlLoad.addParaConst(CODE_FIELD_DEFAULT_NAME, CODE_FIELD, CODE_FIELD_DEFAULT); // 生成统计累加SQL语句 SqlData sqlGroupAdd = this.releaseSql(SQL_TYPE_ADD_GROUP, GROUP_ADD, SQL_UPDATE, CODE_GROUP_ADD, addFields, prmaryKey); // 当没有字段时,直接修改主键 if (addFields.isEmpty()) { sqlGroupAdd.addCode(CODE_FIELD, String.format("%s=%s", prmaryKey.get(0).inputName, prmaryKey.get(0).inputName)); } // 生成覆盖值 if (replaceFields != null) { for (TableFieldVo field : replaceFields) { sqlGroupAdd.addPara(field.inputName, CODE_FIELD, String.format(",a.%s=?", field.name)); } } sqlTableData.add(sqlLoad); sqlTableData.add(sqlGroupAdd); } /** * 生成判断数据是否存在的SQL语句 * * @param sqlTableData 表结构 * @param sqlName SQL语句的名称 * @param mustField 需要判断的字段 * @param allowNullField 需要判断的字段 */ public void addExist(TableSqlCache sqlTableData, String sqlName, TableFieldString mustField, TableFieldString allowNullField) { // String[] fields SqlData sql = new SqlData(sqlName, SQL_LOAD.replace(CODE_TABLE, this.name)); sql.addParaConst(CODE_FIELD_DEFAULT_NAME, CODE_FIELD, CODE_FIELD_DEFAULT); sql.setSqlType(SQL_TYPE_EXISTS); sql.addConst(this.getKey().inputName, String.format(CODE_WHERE_NOT_EQUALS_PARA, this.getKey().name) ); // 必须判断的字段 if (mustField != null && mustField.getFields() != null) { for (String fieldName : mustField.getFields()) { TableFieldVo field = this.getField(fieldName); sql.addConst(field.inputName, String.format(CODE_WHERE_EQUALS_PARA, field.name) ); } } // 允许空值的字段 if (allowNullField != null && allowNullField.getFields() != null) { for (String fieldName : allowNullField.getFields()) { TableFieldVo field = this.getField(fieldName); sql.addConst(field.inputName, String.format(CODE_WHERE_EQUALS_NOT_EMPTY_PARA, field.name) ); } } addWhereRemove(sql); sqlTableData.add(sql); } /** * 表结构累加 * * @param froms 来源数据 * @param cls 类型 * @param <T> 类型 * @return 返回值 */ public static <T extends GroupAdd> List<T> megerGroupAdd(List<T> froms, Class<T> cls) { return megerGroupAdd(cls, dbRow -> { for (T from : froms) { dbRow.handle(from); } }); } /** * 表结构累加 * * @param cls 类型 * @param consumer 消费类型 * @param <T> 类型 * @return 返回值 */ public static <T extends GroupAdd> List<T> megerGroupAdd(Class<T> cls, Consumer<DbRow<T>> consumer) { List<T> tos = new ArrayList<>(); Map<String, T> mapFrom = new HashMap<>(); TableStruct tableStruct = new TableStruct(StringHelper.EMPTY, cls); List<TableFieldVo> fields = tableStruct.getGroupLatitudeFields(); consumer.accept((from) -> { StringBuilder sb = new StringBuilder(); for (TableFieldVo field : fields) { String value = StringHelper.getFirst(ObjectHelper.getString(from, field.inputName)); sb.append(value); sb.append(":"); } String key = StringHelper.getIdMD5(sb.toString()); if (!mapFrom.containsKey(key)) { tos.add(from); mapFrom.put(key, from); } else { T history = mapFrom.get(key); history.add(from); } }); return tos; } }