TableStruct.java 29.7 KB
Newer Older
yanzg's avatar
yanzg committed
1
package com.yanzuoguang.dao.impl;
yanzg's avatar
yanzg committed
2

yanzg's avatar
yanzg committed
3 4
import com.yanzuoguang.dao.DaoConst;
import com.yanzuoguang.dao.TableAnnotation;
yanzg's avatar
yanzg committed
5
import com.yanzuoguang.dao.cond.SqlCondDefault;
yanzg's avatar
yanzg committed
6 7
import com.yanzuoguang.util.base.MethodField;
import com.yanzuoguang.util.base.ObjectHelper;
yanzg's avatar
yanzg committed
8
import com.yanzuoguang.util.helper.StringHelper;
yanzg's avatar
yanzg committed
9 10 11 12 13 14 15 16

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

/**
 * 表结构的基本信息
yanzg's avatar
yanzg committed
17 18
 *
 * @author 颜佐光
yanzg's avatar
yanzg committed
19 20
 */
public class TableStruct {
yanzg's avatar
yanzg committed
21

yanzg's avatar
yanzg committed
22 23 24
    private static final int WHERE_ADD = 1;
    private static final int WHERE_REMOVE_ADD = 2;
    private static final int WHERE_ADD_NOT = 0;
yanzg's avatar
yanzg committed
25
    /**
yanzg's avatar
yanzg committed
26
     * 数据库中的表名称
yanzg's avatar
yanzg committed
27
     */
yanzg's avatar
yanzg committed
28
    private String name;
yanzg's avatar
yanzg committed
29 30

    /**
yanzg's avatar
yanzg committed
31
     * 缓存的字段,根据字段的类型进行缓存,同一个字段可能会属于多个类型。
yanzg's avatar
yanzg committed
32
     */
yanzg's avatar
yanzg committed
33 34 35 36 37 38 39 40 41
    private Map<Integer, List<TableFieldVo>> typeFieldCache = new HashMap<>();

    /**
     * 构造函数
     */
    public TableStruct() {
        this.name = "";
    }

yanzg's avatar
yanzg committed
42 43 44 45 46

    public TableStruct(String name) {
        this.name = name;
    }

yanzg's avatar
yanzg committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    /**
     * 通过实体的字段来创建表结构信息
     *
     * @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();
yanzg's avatar
yanzg committed
63
            if (field.getField() == null) {
yanzg's avatar
yanzg committed
64 65 66 67 68 69 70 71 72 73 74 75 76
                continue;
            }
            addMethodField(field);
        }
    }

    /**
     * 添加字段
     *
     * @param field 添加字段
     */
    private void addMethodField(MethodField field) {

yanzg's avatar
yanzg committed
77
        int fieldAction = DaoConst.FIELD_NONE;
yanzg's avatar
yanzg committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

        // 默认后台数据库字段和前台参数字段为字段名,字段类型为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) {
yanzg's avatar
yanzg committed
93 94 95
            if (!StringHelper.isEmpty(annotation.value())) {
                fieldName = annotation.value();
            }
yanzg's avatar
yanzg committed
96 97 98
            fieldAction = annotation.type();
        }

yanzg's avatar
yanzg committed
99 100 101 102 103 104 105 106 107 108 109 110
        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) {
yanzg's avatar
yanzg committed
111 112 113 114
        // 将字段组合成输入字段
        TableFieldVo vo = new TableFieldVo(fieldName, fieldInputName, fieldType);
        // 根据字段名称规则来获取名称默认类型
        int stringAction = getStringAction(vo);
yanzg's avatar
yanzg committed
115 116
        // 判断是否属于主键
        int resultActionType = getActionType(fieldAction, stringAction);
yanzg's avatar
yanzg committed
117 118 119

        // 获取普通类型字段列表
        List<TableFieldVo> commonActionList = this.getFieldActionList(DaoConst.FIELD_COMMON);
yanzg's avatar
yanzg committed
120
        if (resultActionType == DaoConst.FIELD_PRIMARY) {
yanzg's avatar
yanzg committed
121 122 123 124 125 126 127 128 129 130
            // 将历史主键添加到普通列,并且移除历史主键
            List<TableFieldVo> primaryActionList = this.getFieldActionList(DaoConst.FIELD_PRIMARY);
            commonActionList.addAll(primaryActionList);
            primaryActionList.clear();
            // 将现有列添加到主键
            primaryActionList.add(vo);
        } else {
            // 将所有非主键列添加到普通列
            commonActionList.add(vo);

yanzg's avatar
yanzg committed
131 132
            boolean isTypeMany = resultActionType != DaoConst.FIELD_MD5
                    && resultActionType != DaoConst.FIELD_REMOVE
yanzg's avatar
yanzg committed
133 134 135 136
                    && resultActionType != DaoConst.FIELD_VERSION
                    && resultActionType != DaoConst.FIELD_COMMON;

            if (resultActionType != DaoConst.FIELD_COMMON) {
yanzg's avatar
yanzg committed
137
                List<TableFieldVo> actionList = this.getFieldActionList(resultActionType);
yanzg's avatar
yanzg committed
138 139 140
                // 处理其他特殊列
                if (isTypeMany) {
                    actionList.add(vo);
yanzg's avatar
yanzg committed
141
                } else if (resultActionType == fieldAction) {
yanzg's avatar
yanzg committed
142 143
                    // fieldAction 优先级高于 stringAction
                    // 假如特殊列已经存在,则将已经存在的特殊列删除,并且添加新的特殊列
yanzg's avatar
yanzg committed
144
                    actionList.clear();
yanzg's avatar
yanzg committed
145
                    actionList.add(vo);
yanzg's avatar
yanzg committed
146 147
                } else if (actionList.isEmpty()) {
                    // stringAction
yanzg's avatar
yanzg committed
148
                    // 假如是默认的,并且特殊列已经存在,则不进行任何处理
yanzg's avatar
yanzg committed
149
                    actionList.add(vo);
yanzg's avatar
yanzg committed
150 151 152 153 154
                }
            }
        }
    }

yanzg's avatar
yanzg committed
155 156 157 158 159 160 161 162
    /**
     * 获取字段类型
     *
     * @param fieldAction  字段类型
     * @param stringAction 字符串字段类型
     * @return 最终类型
     */
    private int getActionType(int fieldAction, int stringAction) {
yanzg's avatar
yanzg committed
163
        if (fieldAction != DaoConst.FIELD_NONE) {
yanzg's avatar
yanzg committed
164 165 166 167 168 169
            return fieldAction;
        } else {
            return stringAction;
        }
    }

yanzg's avatar
yanzg committed
170 171 172 173
    /**
     * 获取字符串动作类型
     *
     * @param vo 输入子弹
yanzg's avatar
yanzg committed
174
     * @return 获取到的自动类型
yanzg's avatar
yanzg committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
     */
    private int getStringAction(TableFieldVo vo) {
        if (getKey() == null) {
            return DaoConst.FIELD_PRIMARY;
        } else if (DaoConst.REMOVE_FLAG.equals(vo.inputLName)) {
            return DaoConst.FIELD_REMOVE;
        } else if (DaoConst.VERSION_FLAG.equals(vo.inputLName)) {
            return DaoConst.FIELD_VERSION;
        }
        // 判断是否属于统计字段
        else if (DaoConst.MD5_KEY_FLAG.equals(vo.inputLName)) {
            return DaoConst.FIELD_MD5;
        } else if (vo.inputLName.startsWith(DaoConst.UPDATE_FLAG)) {
            return DaoConst.FIELD_REMOVE_UPDATE;
        } else if (vo.inputLName.startsWith(DaoConst.CREATE_FLAG)) {
            return DaoConst.FIELD_CREATE;
        } else {
            return DaoConst.FIELD_COMMON;
        }

    }
yanzg's avatar
yanzg committed
196 197

    /**
yanzg's avatar
yanzg committed
198 199
     * 获取某个类型的所有字段
     *
yanzg's avatar
yanzg committed
200 201 202
     * @param type       某个类型,需要排除的类型
     * @param exceptType 需要排除的字段的类型
     * @return 字段列表
yanzg's avatar
yanzg committed
203
     */
yanzg's avatar
yanzg committed
204
    private List<TableFieldVo> getFieldActionList(int type, int... exceptType) {
yanzg's avatar
yanzg committed
205 206
        if (!typeFieldCache.containsKey(type)) {
            typeFieldCache.put(type, new ArrayList<>());
yanzg's avatar
yanzg committed
207
        }
yanzg's avatar
yanzg committed
208 209 210 211 212
        List<TableFieldVo> from = typeFieldCache.get(type);
        if (exceptType == null || exceptType.length == 0) {
            return from;
        } else {
            // 缓存需要排除的子弹
yanzg's avatar
yanzg committed
213
            Map<String, Boolean> exceptCache = new HashMap<>(10);
yanzg's avatar
yanzg committed
214 215 216 217 218 219
            for (int except : exceptType) {
                if (!typeFieldCache.containsKey(except)) {
                    continue;
                }
                List<TableFieldVo> exceptList = typeFieldCache.get(except);
                for (TableFieldVo exceptField : exceptList) {
yanzg's avatar
yanzg committed
220
                    exceptCache.put(exceptField.name, true);
yanzg's avatar
yanzg committed
221 222 223 224 225
                }
            }
            // 剩下的字段
            List<TableFieldVo> to = new ArrayList<>();
            for (TableFieldVo fromItem : from) {
yanzg's avatar
yanzg committed
226
                if (exceptCache.containsKey(fromItem.name)) {
yanzg's avatar
yanzg committed
227 228 229 230 231 232
                    continue;
                }
                to.add(fromItem);
            }
            return to;
        }
yanzg's avatar
yanzg committed
233
    }
yanzg's avatar
yanzg committed
234 235

    /**
yanzg's avatar
yanzg committed
236
     * 获取某个类型的第一个字段
yanzg's avatar
yanzg committed
237 238
     *
     * @param type 类型
yanzg's avatar
yanzg committed
239
     * @return 获取到的子弹
yanzg's avatar
yanzg committed
240
     */
yanzg's avatar
yanzg committed
241 242
    private TableFieldVo getFieldAction(int type) {
        List<TableFieldVo> list = getFieldActionList(type);
yanzg's avatar
yanzg committed
243
        return !list.isEmpty() ? list.get(0) : null;
yanzg's avatar
yanzg committed
244
    }
yanzg's avatar
yanzg committed
245

yanzg's avatar
yanzg committed
246 247 248 249 250
    /**
     * 获取所有普通子弹
     *
     * @return 所有的普通股字段
     */
yanzg's avatar
yanzg committed
251
    public List<TableFieldVo> getFields() {
yanzg's avatar
yanzg committed
252
        return getFieldActionList(DaoConst.FIELD_COMMON);
yanzg's avatar
yanzg committed
253 254
    }

yanzg's avatar
yanzg committed
255 256 257 258 259 260
    /**
     * 获取统计纬度列
     *
     * @return 获取统计纬度列
     */
    public List<TableFieldVo> getGroupLatitudeFields() {
yanzg's avatar
yanzg committed
261 262 263 264 265
        return getFieldActionList(DaoConst.FIELD_COMMON,
                DaoConst.FIELD_ADD_GROUP,
                DaoConst.FIELD_REPLACE_GROUP,
                DaoConst.FIELD_MD5
        );
yanzg's avatar
yanzg committed
266 267
    }

yanzg's avatar
yanzg committed
268 269 270
    /**
     * 获取表名
     *
yanzg's avatar
yanzg committed
271
     * @return 获取到的名称
yanzg's avatar
yanzg committed
272
     */
yanzg's avatar
yanzg committed
273
    public String getName() {
yanzg's avatar
yanzg committed
274
        return name;
yanzg's avatar
yanzg committed
275 276
    }

yanzg's avatar
yanzg committed
277 278 279
    /**
     * 设置表名
     *
yanzg's avatar
yanzg committed
280
     * @param name 设置的表名
yanzg's avatar
yanzg committed
281
     */
yanzg's avatar
yanzg committed
282
    public void setName(String name) {
yanzg's avatar
yanzg committed
283
        this.name = name;
yanzg's avatar
yanzg committed
284 285
    }

yanzg's avatar
yanzg committed
286 287 288
    /**
     * 主键
     *
yanzg's avatar
yanzg committed
289
     * @return 获取到的键值
yanzg's avatar
yanzg committed
290
     */
yanzg's avatar
yanzg committed
291
    public TableFieldVo getKey() {
yanzg's avatar
yanzg committed
292
        return getFieldAction(DaoConst.FIELD_PRIMARY);
yanzg's avatar
yanzg committed
293 294
    }

yanzg's avatar
yanzg committed
295 296 297
    /**
     * 主键名称
     *
yanzg's avatar
yanzg committed
298
     * @return 主键名称
yanzg's avatar
yanzg committed
299 300 301
     */
    public String getKeyName() {
        return this.getKey().inputName;
yanzg's avatar
yanzg committed
302 303
    }

yanzg's avatar
yanzg committed
304 305 306
    /**
     * 主键数据类型
     *
yanzg's avatar
yanzg committed
307
     * @return 主键类型
yanzg's avatar
yanzg committed
308 309 310
     */
    public Class<?> getKeyType() {
        return this.getKey().type;
yanzg's avatar
yanzg committed
311 312
    }

yanzg's avatar
yanzg committed
313 314 315
    /**
     * MD5缓存字段
     *
yanzg's avatar
yanzg committed
316
     * @return md5字段
yanzg's avatar
yanzg committed
317 318 319 320 321 322 323 324
     */
    public TableFieldVo getMd5Key() {
        return getFieldAction(DaoConst.FIELD_MD5);
    }

    /**
     * MD5缓存键值
     *
yanzg's avatar
yanzg committed
325
     * @return MD5名称
yanzg's avatar
yanzg committed
326
     */
yanzg's avatar
yanzg committed
327
    public String getMD5KeyName() {
yanzg's avatar
yanzg committed
328
        TableFieldVo md5Key = this.getMd5Key();
yanzg's avatar
yanzg committed
329
        return md5Key != null ? md5Key.inputName : null;
yanzg's avatar
yanzg committed
330 331
    }

yanzg's avatar
yanzg committed
332 333 334
    /**
     * 判断是否包含版本号字段
     *
yanzg's avatar
yanzg committed
335
     * @return 版本号字段
yanzg's avatar
yanzg committed
336 337 338 339 340 341 342 343
     */
    public TableFieldVo getVersion() {
        return getFieldAction(DaoConst.FIELD_VERSION);
    }

    /**
     * 判断是否包含remove字段
     *
yanzg's avatar
yanzg committed
344
     * @return 删除字段
yanzg's avatar
yanzg committed
345
     */
yanzg's avatar
yanzg committed
346
    public TableFieldVo getRemove() {
yanzg's avatar
yanzg committed
347
        return getFieldAction(DaoConst.FIELD_REMOVE);
yanzg's avatar
yanzg committed
348 349
    }

yanzg's avatar
yanzg committed
350 351 352 353 354 355 356 357 358 359

    /**
     * 获取删除时更新子弹
     *
     * @return 删除时更新字段
     */
    public List<TableFieldVo> getRemoveUpdate() {
        return getFieldActionList(DaoConst.FIELD_REMOVE_UPDATE);
    }

yanzg's avatar
yanzg committed
360
    /**
yanzg's avatar
yanzg committed
361
     * 获取某一列
yanzg's avatar
yanzg committed
362
     *
yanzg's avatar
yanzg committed
363
     * @param name 列名
yanzg's avatar
yanzg committed
364
     * @return 获取到的字段
yanzg's avatar
yanzg committed
365
     */
yanzg's avatar
yanzg committed
366 367 368 369 370 371 372 373 374 375
    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;
            }
        }
        return null;
yanzg's avatar
yanzg committed
376 377
    }

yanzg's avatar
yanzg committed
378 379 380 381 382 383 384 385 386 387
    /**
     * 获取某一列
     *
     * @param fieldType 字段类型
     * @return 获取到的字段
     */
    public List<TableFieldVo> getFields(int fieldType) {
        return getFieldActionList(fieldType);
    }

yanzg's avatar
yanzg committed
388 389 390
    /**
     * 通过表结构自动生成SQL语句
     *
yanzg's avatar
yanzg committed
391
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
392 393
     */
    public void init(TableSqlCache table) {
yanzg's avatar
yanzg committed
394
        table.setTable(this);
yanzg's avatar
yanzg committed
395
        if (!StringHelper.isEmpty(this.name)) {
yanzg's avatar
yanzg committed
396 397 398
            table.add(
                    releaseSqlReplace(),
                    releaseSqlCreate(),
yanzg's avatar
yanzg committed
399 400 401 402
                    releaseSqlUpdate().sortCond(),
                    releaseSqlRemove().sortCond(),
                    releaseSqlLoad().sortCond(),
                    releaseSqlQuery().sortCond()
yanzg's avatar
yanzg committed
403
            );
yanzg's avatar
yanzg committed
404
        }
yanzg's avatar
yanzg committed
405 406 407 408 409 410
        initSaveWith(table);
        initAddGroup(table);
    }

    /**
     * 初始化SaveWith
yanzg's avatar
yanzg committed
411 412
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
413 414 415 416 417 418 419 420 421 422 423
     */
    private void initSaveWith(TableSqlCache table) {
        List<TableFieldVo> saveWithField = getFieldActionList(DaoConst.FIELD_SAVE_WITH);
        if (saveWithField == null || saveWithField.isEmpty()) {
            return;
        }
        this.addSaveWithSql(table, DaoConst.SAVE_WITH, saveWithField);
    }

    /**
     * 初始化添加统计SQL语句
yanzg's avatar
yanzg committed
424 425
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
426 427 428
     */
    private void initAddGroup(TableSqlCache table) {
        List<TableFieldVo> addGroupField = getFieldActionList(DaoConst.FIELD_ADD_GROUP);
yanzg's avatar
yanzg committed
429
        List<TableFieldVo> replaceGroupField = getFieldActionList(DaoConst.FIELD_REPLACE_GROUP);
yanzg's avatar
yanzg committed
430
        List<TableFieldVo> commonField = this.getGroupLatitudeFields();
yanzg's avatar
yanzg committed
431
        this.addGroupSql(table, commonField, replaceGroupField, addGroupField);
yanzg's avatar
yanzg committed
432 433
    }

yanzg's avatar
yanzg committed
434 435 436 437 438 439 440 441 442
    /**
     * 生成创建的SQL语句
     *
     * @return 生成的语句
     */
    private SqlData releaseSqlReplace() {
        return releaseSqlCreateReplace(DaoConst.SQL_REPLACE, DaoConst.REPLACE, DaoConst.SQL_TYPE_CREATE);
    }

yanzg's avatar
yanzg committed
443 444 445
    /**
     * 生成创建的SQL语句
     *
yanzg's avatar
yanzg committed
446
     * @return 生成的语句
yanzg's avatar
yanzg committed
447 448
     */
    private SqlData releaseSqlCreate() {
yanzg's avatar
yanzg committed
449 450 451 452
        return releaseSqlCreateReplace(DaoConst.SQL_INSERT, DaoConst.CREATE, DaoConst.SQL_TYPE_CREATE);
    }

    private SqlData releaseSqlCreateReplace(String sqlModel, String sqlName, int sqlType) {
yanzg's avatar
yanzg committed
453
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
454 455 456
        String text = sqlModel.replace(DaoConst.CODE_TABLE, this.name);
        SqlData sql = new SqlData(sqlName, text);
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
457 458
        // 第一个增加的字段,不需要增加 ","
        String flag = StringHelper.EMPTY;
yanzg's avatar
yanzg committed
459
        if (this.getKeyType() == String.class) {
yanzg's avatar
yanzg committed
460 461
            sql.addParaConst(this.getKey().inputName, DaoConst.CODE_FIELD, this.getKey().name,
                    DaoConst.CODE_VALUES, DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
462 463
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
464
        }
yanzg's avatar
yanzg committed
465
        for (TableFieldVo field : this.getFields()) {
yanzg's avatar
yanzg committed
466 467
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + field.name,
                    DaoConst.CODE_VALUES, flag + DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
468 469
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
470 471 472 473 474 475 476
        }
        return sql;
    }

    /**
     * 生成修改的SQL语句
     *
yanzg's avatar
yanzg committed
477
     * @return 生成的语句
yanzg's avatar
yanzg committed
478 479
     */
    private SqlData releaseSqlUpdate() {
yanzg's avatar
yanzg committed
480
        TableFieldVo remove = this.getRemove();
yanzg's avatar
yanzg committed
481
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
482
        String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
483
        SqlData sql = new SqlData(DaoConst.UPDATE, text);
yanzg's avatar
yanzg committed
484
        sql.setSqlType(DaoConst.SQL_TYPE_UPDATE);
yanzg's avatar
yanzg committed
485

yanzg's avatar
yanzg committed
486
        // 主键字段操作
yanzg's avatar
yanzg committed
487
        sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_PRIMARY, this.getKey().name, this.getKey().name));
yanzg's avatar
yanzg committed
488
        sql.addConst(this.getKey().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, this.getKey().name));
yanzg's avatar
yanzg committed
489

yanzg's avatar
yanzg committed
490
        // 增加普通代码片段字段
yanzg's avatar
yanzg committed
491 492 493
        List<TableFieldVo> updateList = getFieldActionList(DaoConst.FIELD_COMMON,
                DaoConst.FIELD_CREATE, DaoConst.FIELD_REMOVE, DaoConst.FIELD_VERSION);
        for (TableFieldVo field : updateList) {
yanzg's avatar
yanzg committed
494
            sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
495
                    DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
496
            );
yanzg's avatar
yanzg committed
497
        }
yanzg's avatar
yanzg committed
498 499 500

        // 设置删除标记可以通过前台传入
        if (remove != null) {
yanzg's avatar
yanzg committed
501
            sql.addParaConst(remove.inputName, DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, remove.name));
yanzg's avatar
yanzg committed
502 503
        }

yanzg's avatar
yanzg committed
504
        // 添加删除字段
yanzg's avatar
yanzg committed
505
        // addWhereRemove(sql);
yanzg's avatar
yanzg committed
506 507 508 509
        addUpdateVersion(sql);
        // 添加版本号条件
        if (getVersion() != null) {
            sql.addConst(getVersion().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, getVersion().name));
yanzg's avatar
yanzg committed
510 511 512 513 514 515 516
        }
        return sql;
    }

    /**
     * 生成删除的SQL语句
     *
yanzg's avatar
yanzg committed
517
     * @return 生成的语句
yanzg's avatar
yanzg committed
518
     */
yanzg's avatar
yanzg committed
519
    private SqlData releaseSqlRemove() {
yanzg's avatar
yanzg committed
520 521
        TableFieldVo remove = this.getRemove();
        if (remove != null) {
yanzg's avatar
yanzg committed
522
            // 生成添加的SQL语句
yanzg's avatar
yanzg committed
523
            String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
524
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
525
            sql.setSqlType(DaoConst.SQL_TYPE_REMOVE);
yanzg's avatar
yanzg committed
526 527

            // 设置删除字段标记
yanzg's avatar
yanzg committed
528
            sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_REMOVE, remove.name));
yanzg's avatar
yanzg committed
529 530

            // 设置删除时需要修改的字段的值
yanzg's avatar
yanzg committed
531
            for (TableFieldVo field : this.getFieldActionList(DaoConst.FIELD_REMOVE_UPDATE)) {
yanzg's avatar
yanzg committed
532
                sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
533
                        DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
534
                );
yanzg's avatar
yanzg committed
535
            }
yanzg's avatar
yanzg committed
536 537 538 539
            // 增加版本号字段的值
            addUpdateVersion(sql);
            // 生成逻辑删除WHERE条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
540 541
            return sql;
        } else {
yanzg's avatar
yanzg committed
542
            String text = DaoConst.SQL_REMOVE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
543
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
544 545
            // 生成删除语句Where条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
546 547 548 549
            return sql;
        }
    }

yanzg's avatar
yanzg committed
550
    private SqlData releaseSqlQuery(String sqlName, int sqlType) {
yanzg's avatar
yanzg committed
551
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
552
        String text = DaoConst.SQL_LOAD.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
553
        SqlData sql = new SqlData(sqlName, text);
yanzg's avatar
yanzg committed
554
        sql.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
555
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
556 557
        // 生成加载语句的WHERE条件
        addWhereField(sql, DaoConst.CODE_TAG, false);
yanzg's avatar
yanzg committed
558

yanzg's avatar
yanzg committed
559 560 561
        return sql;
    }

yanzg's avatar
yanzg committed
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
    /**
     * 生成加载的SQL语句
     *
     * @return 生成的语句
     */
    private SqlData releaseSqlLoad() {
        return releaseSqlQuery(DaoConst.LOAD, DaoConst.SQL_TYPE_LOAD);
    }

    /**
     * 生成查询语句
     *
     * @return
     */
    private SqlData releaseSqlQuery() {
        return releaseSqlQuery(DaoConst.QUERY, DaoConst.SQL_TYPE_COMMON);
    }

yanzg's avatar
yanzg committed
580 581 582
    /**
     * 当前当前表所有字段的等于SQL语句
     *
yanzg's avatar
yanzg committed
583 584 585 586
     * @param sql      SDL语句
     * @param tag      标记
     * @param isRemove 是否生成删除相关字段
     * @return 生成的语句
yanzg's avatar
yanzg committed
587
     */
yanzg's avatar
yanzg committed
588
    private void addWhereField(SqlData sql, String tag, boolean isRemove) {
yanzg's avatar
yanzg committed
589
        addWhereBase(sql, DaoConst.CODE_WHERE, tag, isRemove, false);
yanzg's avatar
yanzg committed
590 591 592 593
        // 查询时,不能查询到非删除的字段
        addWhereRemove(sql);
    }

yanzg's avatar
yanzg committed
594

yanzg's avatar
yanzg committed
595 596 597 598 599 600
    /**
     * 对当前Sql语句进行扩展
     *
     * @param sql 需要扩展的SQL语句
     * @param tag 扩展标签
     */
yanzg's avatar
yanzg committed
601
    public void addWhereExtend(SqlData sql, String tag, boolean removeHistory, String... codes) {
yanzg's avatar
yanzg committed
602 603 604 605 606 607 608 609 610 611 612
        addWhereBase(sql, DaoConst.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);
yanzg's avatar
yanzg committed
613 614
    }

yanzg's avatar
yanzg committed
615 616
    private void addWhereBase(SqlData sql, String codeName, String tag, boolean isRemove, boolean removeHistory, String... codes) {
        addWhereFieldCommon(sql, codeName, this.getKey(), tag, removeHistory);
yanzg's avatar
yanzg committed
617 618 619 620 621 622 623 624 625 626

        // Where条件包含的字段
        List<TableFieldVo> fields;
        if (!isRemove) {
            // 所有字段
            fields = this.getFields();
        } else {
            // 非删除时需要更新的字段
            fields = this.getFieldActionList(DaoConst.FIELD_COMMON, DaoConst.FIELD_REMOVE_UPDATE);
        }
yanzg's avatar
yanzg committed
627 628

        List<String> codesField = new ArrayList<>();
yanzg's avatar
yanzg committed
629 630
        // 添加普通的Where条件
        for (TableFieldVo field : fields) {
yanzg's avatar
yanzg committed
631
            int isAdd = addWhereFieldCommon(sql, codeName, field, tag, removeHistory);
yanzg's avatar
yanzg committed
632 633 634 635 636 637
            if (isAdd != WHERE_ADD_NOT) {
                codesField.add(field.inputName);
            }
        }
        if (!codesField.isEmpty()) {
            sql.addPara(new SqlCondDefault(codesField), codes);
yanzg's avatar
yanzg committed
638
        }
yanzg's avatar
yanzg committed
639
    }
yanzg's avatar
yanzg committed
640

yanzg's avatar
yanzg committed
641 642 643
    private int addWhereFieldCommon(SqlData sql, String codeName, TableFieldVo field, String tag, boolean removeHistory) {
        addWhereFieldNotExtend(sql, field.inputName, codeName,
                String.format(DaoConst.CODE_WHERE_EQUALS, tag, field.name, DaoConst.CODE_PARA), removeHistory);
yanzg's avatar
yanzg committed
644 645
        // 添加in条件
        String sqlIn = String.format(DaoConst.CODE_WHERE_IN, tag, field.name, DaoConst.CODE_PARA);
yanzg's avatar
yanzg committed
646 647 648

        return addWhereFieldNotExtend(sql, DaoConst.getArrayParameterName(field.inputName), codeName,
                sqlIn, removeHistory);
yanzg's avatar
yanzg committed
649 650
    }

yanzg's avatar
yanzg committed
651
    private int addWhereFieldNotExtend(SqlData sql, String inputName, String codeName, String sqlWhere, boolean removeHistory) {
yanzg's avatar
yanzg committed
652 653 654
        SqlDataField field = sql.getField(inputName);
        if (field == null) {
            // 添加新的条件
yanzg's avatar
yanzg committed
655
            sql.addPara(inputName, codeName, sqlWhere);
yanzg's avatar
yanzg committed
656
            return WHERE_ADD;
yanzg's avatar
yanzg committed
657
        } else if (field != null && removeHistory) {
yanzg's avatar
yanzg committed
658 659 660
            // 删除历史条件
            sql.removeField(inputName);
            // 添加新的条件
yanzg's avatar
yanzg committed
661
            sql.addPara(inputName, codeName, sqlWhere);
yanzg's avatar
yanzg committed
662
            return WHERE_REMOVE_ADD;
yanzg's avatar
yanzg committed
663
        }
yanzg's avatar
yanzg committed
664
        return WHERE_ADD_NOT;
yanzg's avatar
yanzg committed
665 666
    }

yanzg's avatar
yanzg committed
667 668 669
    /**
     * 添加删除WHERE条件字段
     *
yanzg's avatar
yanzg committed
670
     * @param sql SQL语句实体
yanzg's avatar
yanzg committed
671 672 673 674
     */
    private void addWhereRemove(SqlData sql) {
        if (getRemove() != null) {
            sql.addParaConst(DaoConst.REMOVE_FLAG_INPUT,
yanzg's avatar
yanzg committed
675
                    DaoConst.CODE_WHERE,
yanzg's avatar
yanzg committed
676 677
                    String.format(DaoConst.CODE_WHERE_EQUALS_NOT_REMOVE, this.getRemove().name)
            );
yanzg's avatar
yanzg committed
678
        }
yanzg's avatar
yanzg committed
679 680 681 682 683 684 685 686 687 688
    }

    /**
     * 版本号进行累加
     *
     * @param sql 需要处理的SQL语句
     */
    private void addUpdateVersion(SqlData sql) {
        // 添加版本字段
        if (getVersion() != null) {
yanzg's avatar
yanzg committed
689
            sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_VERSION_FIELD, getVersion().name, getVersion().name));
yanzg's avatar
yanzg committed
690 691 692 693 694 695
        }
    }

    /**
     * 生成SQL语句
     *
yanzg's avatar
yanzg committed
696
     * @param sqlType     SQL语句类型
yanzg's avatar
yanzg committed
697 698 699 700 701
     * @param name        SQL语句名称
     * @param model       SQL语句模板
     * @param valueModel  值字段模板
     * @param valueFields 值字段
     * @param whereFields WHERE字段
yanzg's avatar
yanzg committed
702
     * @return 生成的SQL语句
yanzg's avatar
yanzg committed
703
     */
yanzg's avatar
yanzg committed
704 705
    private SqlData releaseSql(int sqlType, String name, String model, String valueModel, List<TableFieldVo> valueFields, List<TableFieldVo> whereFields) {
        // 生成修改的SQL语句
yanzg's avatar
yanzg committed
706
        SqlData sql = new SqlData(name, model.replace(DaoConst.CODE_TABLE, this.name));
yanzg's avatar
yanzg committed
707
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
708
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
709 710
        String flag = StringHelper.EMPTY;
        for (TableFieldVo field : valueFields) {
yanzg's avatar
yanzg committed
711
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + valueModel.replace(DaoConst.CODE_FIELD, field.name));
yanzg's avatar
yanzg committed
712
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
713 714
        }

yanzg's avatar
yanzg committed
715
        for (TableFieldVo field : whereFields) {
yanzg's avatar
yanzg committed
716
            sql.addConst(field.inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, field.name));
yanzg's avatar
yanzg committed
717 718
        }

yanzg's avatar
yanzg committed
719 720 721 722 723 724 725 726 727 728 729
        return sql;
    }

    /**
     * 根据来源字符串获取结束字符串
     *
     * @param fieldFrom 来源字符串
     * @return 返回字符串
     */
    private List<TableFieldVo> getFieldString(TableFieldString fieldFrom) {
        List<TableFieldVo> list = new ArrayList<>();
yanzg's avatar
yanzg committed
730 731 732 733
        if (fieldFrom != null) {
            for (String fieldName : fieldFrom.getFields()) {
                list.add(this.getField(fieldName));
            }
yanzg's avatar
yanzg committed
734 735
        }
        return list;
yanzg's avatar
yanzg committed
736 737 738 739 740
    }

    /**
     * 生成根据某些字段不存在则保存的SQL语句
     *
yanzg's avatar
yanzg committed
741 742 743
     * @param tableStruct 表结构
     * @param sqlName     SQL语句
     * @param whereFields WHERE条件
yanzg's avatar
yanzg committed
744 745
     */
    public void addSaveWithSql(TableSqlCache tableStruct, String sqlName, TableFieldString whereFields) {
yanzg's avatar
yanzg committed
746 747 748 749 750 751 752 753 754 755 756
        addSaveWithSql(tableStruct, sqlName, getFieldString(whereFields));
    }

    /**
     * 生成根据某些字段不存在则保存的SQL语句
     *
     * @param tableStruct 表结构
     * @param sqlName     SQL语句
     * @param whereFields WHERE条件
     */
    private void addSaveWithSql(TableSqlCache tableStruct, String sqlName, List<TableFieldVo> whereFields) {
yanzg's avatar
yanzg committed
757
        SqlData sqlData = this.releaseSql(DaoConst.SQL_TYPE_SAVE_WITH, sqlName, DaoConst.SQL_LOAD, StringHelper.EMPTY, new ArrayList<>(), whereFields);
yanzg's avatar
yanzg committed
758
        sqlData.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
759 760 761 762 763 764 765 766
        tableStruct.add(sqlData);
    }

    /**
     * 生成统计的SQL语句
     *
     * @param sqlTableData 需要生成的实体
     * @param whereFields  WHERE字段
yanzg's avatar
yanzg committed
767
     * @param addFields    需要增加的值的字段
yanzg's avatar
yanzg committed
768
     */
yanzg's avatar
yanzg committed
769 770
    public void addGroupSql(TableSqlCache sqlTableData, TableFieldString whereFields, TableFieldString addFields) {
        addGroupSql(sqlTableData, whereFields, null, addFields);
yanzg's avatar
yanzg committed
771 772 773 774 775 776 777
    }

    /**
     * 生成统计的SQL语句
     *
     * @param sqlTableData 需要生成的实体
     * @param whereFields  WHERE字段
yanzg's avatar
yanzg committed
778
     * @param addFields    需要增加的值的字段
yanzg's avatar
yanzg committed
779
     */
yanzg's avatar
yanzg committed
780 781 782 783 784 785 786 787 788 789 790 791
    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) {
yanzg's avatar
yanzg committed
792
        List<TableFieldVo> prmaryKey = this.getFieldActionList(DaoConst.FIELD_PRIMARY);
yanzg's avatar
yanzg committed
793
        // 生成统计加载SQL语句
yanzg's avatar
yanzg committed
794 795 796
        SqlData sqlLoad = this.releaseSql(DaoConst.SQL_TYPE_ADD_GROUP, DaoConst.GROUP_QUERY, DaoConst.SQL_LOAD,
                StringHelper.EMPTY, new ArrayList<>(), whereFields);
        sqlLoad.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
797 798

        // 生成统计累加SQL语句
yanzg's avatar
yanzg committed
799
        SqlData sqlGroupAdd = this.releaseSql(DaoConst.SQL_TYPE_ADD_GROUP, DaoConst.GROUP_ADD, DaoConst.SQL_UPDATE,
yanzg's avatar
yanzg committed
800
                DaoConst.CODE_GROUP_ADD, addFields, prmaryKey);
yanzg's avatar
yanzg committed
801 802 803 804
        // 当没有字段时,直接修改主键
        if (addFields.isEmpty()) {
            sqlGroupAdd.addCode(DaoConst.CODE_FIELD, String.format("%s=%s", prmaryKey.get(0).inputName, prmaryKey.get(0).inputName));
        }
yanzg's avatar
yanzg committed
805 806 807
        // 生成覆盖值
        if (replaceFields != null) {
            for (TableFieldVo field : replaceFields) {
yanzg's avatar
yanzg committed
808
                sqlGroupAdd.addPara(field.inputName, DaoConst.CODE_FIELD, String.format(",a.%s=?", field.name));
yanzg's avatar
yanzg committed
809 810
            }
        }
yanzg's avatar
yanzg committed
811
        sqlTableData.add(sqlLoad);
yanzg's avatar
yanzg committed
812
        sqlTableData.add(sqlGroupAdd);
yanzg's avatar
yanzg committed
813 814 815 816 817
    }

    /**
     * 生成判断数据是否存在的SQL语句
     *
yanzg's avatar
yanzg committed
818 819 820 821
     * @param sqlTableData   表结构
     * @param sqlName        SQL语句的名称
     * @param mustField      需要判断的字段
     * @param allowNullField 需要判断的字段
yanzg's avatar
yanzg committed
822
     */
yanzg's avatar
yanzg committed
823 824
    public void addExist(TableSqlCache sqlTableData, String sqlName, TableFieldString mustField, TableFieldString allowNullField) {
        // String[] fields
yanzg's avatar
yanzg committed
825 826
        SqlData sql = new SqlData(sqlName, DaoConst.SQL_LOAD.replace(DaoConst.CODE_TABLE, this.name));
        sql.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
827

yanzg's avatar
yanzg committed
828
        sql.setSqlType(DaoConst.SQL_TYPE_EXISTS);
yanzg's avatar
yanzg committed
829
        sql.addConst(this.getKey().inputName,
yanzg's avatar
yanzg committed
830 831
                String.format(DaoConst.CODE_WHERE_NOT_EQUALS_PARA, this.getKey().name)
        );
yanzg's avatar
yanzg committed
832

yanzg's avatar
yanzg committed
833 834 835 836 837 838 839 840
        // 必须判断的字段
        if (mustField != null && mustField.getFields() != null) {
            for (String fieldName : mustField.getFields()) {
                TableFieldVo field = this.getField(fieldName);
                sql.addConst(field.inputName,
                        String.format(DaoConst.CODE_WHERE_EQUALS_PARA, field.name)
                );
            }
yanzg's avatar
yanzg committed
841 842
        }

yanzg's avatar
yanzg committed
843 844 845 846 847 848 849 850
        // 允许空值的字段
        if (allowNullField != null && allowNullField.getFields() != null) {
            for (String fieldName : allowNullField.getFields()) {
                TableFieldVo field = this.getField(fieldName);
                sql.addConst(field.inputName,
                        String.format(DaoConst.CODE_WHERE_EQUALS_NOT_EMPTY_PARA, field.name)
                );
            }
yanzg's avatar
yanzg committed
851
        }
yanzg's avatar
yanzg committed
852
        addWhereRemove(sql);
yanzg's avatar
yanzg committed
853 854
        sqlTableData.add(sql);
    }
yanzg's avatar
yanzg committed
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884


    /**
     * 表结构累加
     *
     * @param froms 来源数据
     * @param cls   类型
     * @param <T>
     * @return
     */
    public static <T extends GroupAdd> List<T> megerGroupAdd(List<T> froms, Class<T> cls) {
        List<T> tos = new ArrayList<>();
        Map<String, T> mapFrom = new HashMap<>();

        TableStruct tableStruct = new TableStruct(StringHelper.EMPTY, cls);
        List<TableFieldVo> fields = tableStruct.getGroupLatitudeFields();

        for (T from : froms) {
            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 {
yanzg's avatar
yanzg committed
885 886
                T history = mapFrom.get(key);
                history.add(from);
yanzg's avatar
yanzg committed
887 888 889 890 891 892 893
            }
        }

        return tos;
    }


yanzg's avatar
yanzg committed
894
}