TableStruct.java 26.8 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 6
import com.yanzuoguang.util.base.MethodField;
import com.yanzuoguang.util.base.ObjectHelper;
yanzg's avatar
yanzg committed
7
import com.yanzuoguang.util.helper.StringHelper;
yanzg's avatar
yanzg committed
8 9 10 11 12 13 14 15

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

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

yanzg's avatar
yanzg committed
21
    /**
yanzg's avatar
yanzg committed
22
     * 数据库中的表名称
yanzg's avatar
yanzg committed
23
     */
yanzg's avatar
yanzg committed
24
    private String name;
yanzg's avatar
yanzg committed
25 26

    /**
yanzg's avatar
yanzg committed
27
     * 缓存的字段,根据字段的类型进行缓存,同一个字段可能会属于多个类型。
yanzg's avatar
yanzg committed
28
     */
yanzg's avatar
yanzg committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    private Map<Integer, List<TableFieldVo>> typeFieldCache = new HashMap<>();

    /**
     * 构造函数
     */
    public TableStruct() {
        this.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();
yanzg's avatar
yanzg committed
54
            if (field.getField() == null) {
yanzg's avatar
yanzg committed
55 56 57 58 59 60 61 62 63 64 65 66 67
                continue;
            }
            addMethodField(field);
        }
    }

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

yanzg's avatar
yanzg committed
68
        int fieldAction = DaoConst.FIELD_NONE;
yanzg's avatar
yanzg committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

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

        // 将字段组合成输入字段
        TableFieldVo vo = new TableFieldVo(fieldName, fieldInputName, fieldType);
        // 根据字段名称规则来获取名称默认类型
        int stringAction = getStringAction(vo);

        // 获取普通类型字段列表
        List<TableFieldVo> commonActionList = this.getFieldActionList(DaoConst.FIELD_COMMON);

        // 判断是否属于主键
yanzg's avatar
yanzg committed
99 100
        int resultActionType = getActionType(fieldAction, stringAction);
        if (resultActionType == DaoConst.FIELD_PRIMARY) {
yanzg's avatar
yanzg committed
101 102 103 104 105 106 107 108 109 110
            // 将历史主键添加到普通列,并且移除历史主键
            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
111 112
            boolean isTypeMany = resultActionType != DaoConst.FIELD_MD5
                    && resultActionType != DaoConst.FIELD_REMOVE
yanzg's avatar
yanzg committed
113 114 115 116
                    && resultActionType != DaoConst.FIELD_VERSION
                    && resultActionType != DaoConst.FIELD_COMMON;

            if (resultActionType != DaoConst.FIELD_COMMON) {
yanzg's avatar
yanzg committed
117
                List<TableFieldVo> actionList = this.getFieldActionList(resultActionType);
yanzg's avatar
yanzg committed
118 119 120
                // 处理其他特殊列
                if (isTypeMany) {
                    actionList.add(vo);
yanzg's avatar
yanzg committed
121
                } else if (resultActionType == fieldAction) {
yanzg's avatar
yanzg committed
122 123
                    // fieldAction 优先级高于 stringAction
                    // 假如特殊列已经存在,则将已经存在的特殊列删除,并且添加新的特殊列
yanzg's avatar
yanzg committed
124
                    actionList.clear();
yanzg's avatar
yanzg committed
125
                    actionList.add(vo);
yanzg's avatar
yanzg committed
126 127
                } else if (actionList.isEmpty()) {
                    // stringAction
yanzg's avatar
yanzg committed
128
                    // 假如是默认的,并且特殊列已经存在,则不进行任何处理
yanzg's avatar
yanzg committed
129
                    actionList.add(vo);
yanzg's avatar
yanzg committed
130 131 132
                }
            }
        }
yanzg's avatar
yanzg committed
133

yanzg's avatar
yanzg committed
134 135
    }

yanzg's avatar
yanzg committed
136 137 138 139 140 141 142 143
    /**
     * 获取字段类型
     *
     * @param fieldAction  字段类型
     * @param stringAction 字符串字段类型
     * @return 最终类型
     */
    private int getActionType(int fieldAction, int stringAction) {
yanzg's avatar
yanzg committed
144
        if (fieldAction != DaoConst.FIELD_NONE) {
yanzg's avatar
yanzg committed
145 146 147 148 149 150
            return fieldAction;
        } else {
            return stringAction;
        }
    }

yanzg's avatar
yanzg committed
151 152 153 154
    /**
     * 获取字符串动作类型
     *
     * @param vo 输入子弹
yanzg's avatar
yanzg committed
155
     * @return 获取到的自动类型
yanzg's avatar
yanzg committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
     */
    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
177 178

    /**
yanzg's avatar
yanzg committed
179 180
     * 获取某个类型的所有字段
     *
yanzg's avatar
yanzg committed
181 182 183
     * @param type       某个类型,需要排除的类型
     * @param exceptType 需要排除的字段的类型
     * @return 字段列表
yanzg's avatar
yanzg committed
184
     */
yanzg's avatar
yanzg committed
185
    private List<TableFieldVo> getFieldActionList(int type, int... exceptType) {
yanzg's avatar
yanzg committed
186 187
        if (!typeFieldCache.containsKey(type)) {
            typeFieldCache.put(type, new ArrayList<>());
yanzg's avatar
yanzg committed
188
        }
yanzg's avatar
yanzg committed
189 190 191 192 193
        List<TableFieldVo> from = typeFieldCache.get(type);
        if (exceptType == null || exceptType.length == 0) {
            return from;
        } else {
            // 缓存需要排除的子弹
yanzg's avatar
yanzg committed
194
            Map<String, Boolean> exceptCache = new HashMap<>(10);
yanzg's avatar
yanzg committed
195 196 197 198 199 200
            for (int except : exceptType) {
                if (!typeFieldCache.containsKey(except)) {
                    continue;
                }
                List<TableFieldVo> exceptList = typeFieldCache.get(except);
                for (TableFieldVo exceptField : exceptList) {
yanzg's avatar
yanzg committed
201
                    exceptCache.put(exceptField.name, true);
yanzg's avatar
yanzg committed
202 203 204 205 206
                }
            }
            // 剩下的字段
            List<TableFieldVo> to = new ArrayList<>();
            for (TableFieldVo fromItem : from) {
yanzg's avatar
yanzg committed
207
                if (exceptCache.containsKey(fromItem.name)) {
yanzg's avatar
yanzg committed
208 209 210 211 212 213
                    continue;
                }
                to.add(fromItem);
            }
            return to;
        }
yanzg's avatar
yanzg committed
214
    }
yanzg's avatar
yanzg committed
215 216

    /**
yanzg's avatar
yanzg committed
217
     * 获取某个类型的第一个字段
yanzg's avatar
yanzg committed
218 219
     *
     * @param type 类型
yanzg's avatar
yanzg committed
220
     * @return 获取到的子弹
yanzg's avatar
yanzg committed
221
     */
yanzg's avatar
yanzg committed
222 223
    private TableFieldVo getFieldAction(int type) {
        List<TableFieldVo> list = getFieldActionList(type);
yanzg's avatar
yanzg committed
224
        return !list.isEmpty() ? list.get(0) : null;
yanzg's avatar
yanzg committed
225
    }
yanzg's avatar
yanzg committed
226

yanzg's avatar
yanzg committed
227 228 229 230 231
    /**
     * 获取所有普通子弹
     *
     * @return 所有的普通股字段
     */
yanzg's avatar
yanzg committed
232
    public List<TableFieldVo> getFields() {
yanzg's avatar
yanzg committed
233
        return getFieldActionList(DaoConst.FIELD_COMMON);
yanzg's avatar
yanzg committed
234 235
    }

yanzg's avatar
yanzg committed
236 237 238 239 240 241 242 243 244 245 246
    /**
     * 获取统计纬度列
     *
     * @return 获取统计纬度列
     */
    public List<TableFieldVo> getGroupLatitudeFields() {
        List<TableFieldVo> commonField = getFieldActionList(DaoConst.FIELD_COMMON,
                DaoConst.FIELD_ADD_GROUP, DaoConst.FIELD_MD5);
        return commonField;
    }

yanzg's avatar
yanzg committed
247 248 249
    /**
     * 获取表名
     *
yanzg's avatar
yanzg committed
250
     * @return 获取到的名称
yanzg's avatar
yanzg committed
251
     */
yanzg's avatar
yanzg committed
252
    public String getName() {
yanzg's avatar
yanzg committed
253
        return name;
yanzg's avatar
yanzg committed
254 255
    }

yanzg's avatar
yanzg committed
256 257 258
    /**
     * 设置表名
     *
yanzg's avatar
yanzg committed
259
     * @param name 设置的表名
yanzg's avatar
yanzg committed
260
     */
yanzg's avatar
yanzg committed
261
    public void setName(String name) {
yanzg's avatar
yanzg committed
262
        this.name = name;
yanzg's avatar
yanzg committed
263 264
    }

yanzg's avatar
yanzg committed
265 266 267
    /**
     * 主键
     *
yanzg's avatar
yanzg committed
268
     * @return 获取到的键值
yanzg's avatar
yanzg committed
269
     */
yanzg's avatar
yanzg committed
270
    public TableFieldVo getKey() {
yanzg's avatar
yanzg committed
271
        return getFieldAction(DaoConst.FIELD_PRIMARY);
yanzg's avatar
yanzg committed
272 273
    }

yanzg's avatar
yanzg committed
274 275 276
    /**
     * 主键名称
     *
yanzg's avatar
yanzg committed
277
     * @return 主键名称
yanzg's avatar
yanzg committed
278 279 280
     */
    public String getKeyName() {
        return this.getKey().inputName;
yanzg's avatar
yanzg committed
281 282
    }

yanzg's avatar
yanzg committed
283 284 285
    /**
     * 主键数据类型
     *
yanzg's avatar
yanzg committed
286
     * @return 主键类型
yanzg's avatar
yanzg committed
287 288 289
     */
    public Class<?> getKeyType() {
        return this.getKey().type;
yanzg's avatar
yanzg committed
290 291
    }

yanzg's avatar
yanzg committed
292 293 294
    /**
     * MD5缓存字段
     *
yanzg's avatar
yanzg committed
295
     * @return md5字段
yanzg's avatar
yanzg committed
296 297 298 299 300 301 302 303
     */
    public TableFieldVo getMd5Key() {
        return getFieldAction(DaoConst.FIELD_MD5);
    }

    /**
     * MD5缓存键值
     *
yanzg's avatar
yanzg committed
304
     * @return MD5名称
yanzg's avatar
yanzg committed
305
     */
yanzg's avatar
yanzg committed
306
    public String getMD5KeyName() {
yanzg's avatar
yanzg committed
307
        TableFieldVo md5Key = this.getMd5Key();
yanzg's avatar
yanzg committed
308
        return md5Key != null ? md5Key.inputName : null;
yanzg's avatar
yanzg committed
309 310
    }

yanzg's avatar
yanzg committed
311 312 313
    /**
     * 判断是否包含版本号字段
     *
yanzg's avatar
yanzg committed
314
     * @return 版本号字段
yanzg's avatar
yanzg committed
315 316 317 318 319 320 321 322
     */
    public TableFieldVo getVersion() {
        return getFieldAction(DaoConst.FIELD_VERSION);
    }

    /**
     * 判断是否包含remove字段
     *
yanzg's avatar
yanzg committed
323
     * @return 删除字段
yanzg's avatar
yanzg committed
324
     */
yanzg's avatar
yanzg committed
325
    public TableFieldVo getRemove() {
yanzg's avatar
yanzg committed
326
        return getFieldAction(DaoConst.FIELD_REMOVE);
yanzg's avatar
yanzg committed
327 328
    }

yanzg's avatar
yanzg committed
329 330 331 332 333 334 335 336 337 338

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

yanzg's avatar
yanzg committed
339
    /**
yanzg's avatar
yanzg committed
340
     * 获取某一列
yanzg's avatar
yanzg committed
341
     *
yanzg's avatar
yanzg committed
342
     * @param name 列名
yanzg's avatar
yanzg committed
343
     * @return 获取到的字段
yanzg's avatar
yanzg committed
344
     */
yanzg's avatar
yanzg committed
345 346 347 348 349 350 351 352 353 354
    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
355 356 357 358 359
    }

    /**
     * 通过表结构自动生成SQL语句
     *
yanzg's avatar
yanzg committed
360
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
361 362
     */
    public void init(TableSqlCache table) {
yanzg's avatar
yanzg committed
363
        table.setTable(this);
yanzg's avatar
yanzg committed
364
        if (!StringHelper.isEmpty(this.name)) {
yanzg's avatar
yanzg committed
365 366 367 368 369 370 371 372
            table.add(
                    releaseSqlReplace(),
                    releaseSqlCreate(),
                    releaseSqlUpdate(),
                    releaseSqlRemove(),
                    releaseSqlLoad(),
                    releaseSqlQuery()
            );
yanzg's avatar
yanzg committed
373
        }
yanzg's avatar
yanzg committed
374 375 376 377 378 379
        initSaveWith(table);
        initAddGroup(table);
    }

    /**
     * 初始化SaveWith
yanzg's avatar
yanzg committed
380 381
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
382 383 384 385 386 387 388 389 390 391 392
     */
    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
393 394
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
395 396 397 398 399 400
     */
    private void initAddGroup(TableSqlCache table) {
        List<TableFieldVo> addGroupField = getFieldActionList(DaoConst.FIELD_ADD_GROUP);
        if (addGroupField == null || addGroupField.isEmpty()) {
            return;
        }
yanzg's avatar
yanzg committed
401
        List<TableFieldVo> commonField = this.getGroupLatitudeFields();
yanzg's avatar
yanzg committed
402
        this.addGroupSql(table, commonField, addGroupField);
yanzg's avatar
yanzg committed
403 404
    }

yanzg's avatar
yanzg committed
405 406 407 408 409 410 411 412 413
    /**
     * 生成创建的SQL语句
     *
     * @return 生成的语句
     */
    private SqlData releaseSqlReplace() {
        return releaseSqlCreateReplace(DaoConst.SQL_REPLACE, DaoConst.REPLACE, DaoConst.SQL_TYPE_CREATE);
    }

yanzg's avatar
yanzg committed
414 415 416
    /**
     * 生成创建的SQL语句
     *
yanzg's avatar
yanzg committed
417
     * @return 生成的语句
yanzg's avatar
yanzg committed
418 419
     */
    private SqlData releaseSqlCreate() {
yanzg's avatar
yanzg committed
420 421 422 423
        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
424
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
425 426 427
        String text = sqlModel.replace(DaoConst.CODE_TABLE, this.name);
        SqlData sql = new SqlData(sqlName, text);
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
428 429
        // 第一个增加的字段,不需要增加 ","
        String flag = StringHelper.EMPTY;
yanzg's avatar
yanzg committed
430
        if (this.getKeyType() == String.class) {
yanzg's avatar
yanzg committed
431 432
            sql.addParaConst(this.getKey().inputName, DaoConst.CODE_FIELD, this.getKey().name,
                    DaoConst.CODE_VALUES, DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
433 434
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
435
        }
yanzg's avatar
yanzg committed
436
        for (TableFieldVo field : this.getFields()) {
yanzg's avatar
yanzg committed
437 438
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + field.name,
                    DaoConst.CODE_VALUES, flag + DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
439 440
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
441 442 443 444 445 446 447
        }
        return sql;
    }

    /**
     * 生成修改的SQL语句
     *
yanzg's avatar
yanzg committed
448
     * @return 生成的语句
yanzg's avatar
yanzg committed
449 450
     */
    private SqlData releaseSqlUpdate() {
yanzg's avatar
yanzg committed
451
        TableFieldVo remove = this.getRemove();
yanzg's avatar
yanzg committed
452
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
453
        String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
454
        SqlData sql = new SqlData(DaoConst.UPDATE, text);
yanzg's avatar
yanzg committed
455
        sql.setSqlType(DaoConst.SQL_TYPE_UPDATE);
yanzg's avatar
yanzg committed
456

yanzg's avatar
yanzg committed
457
        // 主键字段操作
yanzg's avatar
yanzg committed
458
        sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_PRIMARY, this.getKey().name, this.getKey().name));
yanzg's avatar
yanzg committed
459
        sql.addConst(this.getKey().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, this.getKey().name));
yanzg's avatar
yanzg committed
460

yanzg's avatar
yanzg committed
461
        // 增加普通代码片段字段
yanzg's avatar
yanzg committed
462 463 464
        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
465
            sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
466
                    DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
467
            );
yanzg's avatar
yanzg committed
468
        }
yanzg's avatar
yanzg committed
469 470 471

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

yanzg's avatar
yanzg committed
475
        // 添加删除字段
yanzg's avatar
yanzg committed
476
        // addWhereRemove(sql);
yanzg's avatar
yanzg committed
477 478 479 480
        addUpdateVersion(sql);
        // 添加版本号条件
        if (getVersion() != null) {
            sql.addConst(getVersion().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, getVersion().name));
yanzg's avatar
yanzg committed
481 482 483 484 485 486 487
        }
        return sql;
    }

    /**
     * 生成删除的SQL语句
     *
yanzg's avatar
yanzg committed
488
     * @return 生成的语句
yanzg's avatar
yanzg committed
489
     */
yanzg's avatar
yanzg committed
490
    private SqlData releaseSqlRemove() {
yanzg's avatar
yanzg committed
491 492
        TableFieldVo remove = this.getRemove();
        if (remove != null) {
yanzg's avatar
yanzg committed
493
            // 生成添加的SQL语句
yanzg's avatar
yanzg committed
494
            String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
495
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
496
            sql.setSqlType(DaoConst.SQL_TYPE_REMOVE);
yanzg's avatar
yanzg committed
497 498

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

            // 设置删除时需要修改的字段的值
yanzg's avatar
yanzg committed
502
            for (TableFieldVo field : this.getFieldActionList(DaoConst.FIELD_REMOVE_UPDATE)) {
yanzg's avatar
yanzg committed
503
                sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
504
                        DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
505
                );
yanzg's avatar
yanzg committed
506
            }
yanzg's avatar
yanzg committed
507 508 509 510
            // 增加版本号字段的值
            addUpdateVersion(sql);
            // 生成逻辑删除WHERE条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
511 512
            return sql;
        } else {
yanzg's avatar
yanzg committed
513
            String text = DaoConst.SQL_REMOVE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
514
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
515 516
            // 生成删除语句Where条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
517 518 519 520
            return sql;
        }
    }

yanzg's avatar
yanzg committed
521
    private SqlData releaseSqlQuery(String sqlName, int sqlType) {
yanzg's avatar
yanzg committed
522
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
523
        String text = DaoConst.SQL_LOAD.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
524
        SqlData sql = new SqlData(sqlName, text);
yanzg's avatar
yanzg committed
525
        sql.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
526
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
527 528
        // 生成加载语句的WHERE条件
        addWhereField(sql, DaoConst.CODE_TAG, false);
yanzg's avatar
yanzg committed
529

yanzg's avatar
yanzg committed
530 531 532
        return sql;
    }

yanzg's avatar
yanzg committed
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
    /**
     * 生成加载的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
551 552 553
    /**
     * 当前当前表所有字段的等于SQL语句
     *
yanzg's avatar
yanzg committed
554 555 556 557
     * @param sql      SDL语句
     * @param tag      标记
     * @param isRemove 是否生成删除相关字段
     * @return 生成的语句
yanzg's avatar
yanzg committed
558
     */
yanzg's avatar
yanzg committed
559
    private void addWhereField(SqlData sql, String tag, boolean isRemove) {
yanzg's avatar
yanzg committed
560
        addWhereBase(sql, tag, isRemove, false);
yanzg's avatar
yanzg committed
561 562 563 564 565 566 567 568 569 570
        // 查询时,不能查询到非删除的字段
        addWhereRemove(sql);
    }

    /**
     * 对当前Sql语句进行扩展
     *
     * @param sql 需要扩展的SQL语句
     * @param tag 扩展标签
     */
yanzg's avatar
yanzg committed
571 572
    public void addWhereExtend(SqlData sql, String tag, boolean removeHistory) {
        addWhereBase(sql, tag, false, removeHistory);
yanzg's avatar
yanzg committed
573 574
    }

yanzg's avatar
yanzg committed
575 576
    private void addWhereBase(SqlData sql, String tag, boolean isRemove, boolean removeHistory) {
        addWhereFieldCommon(sql, this.getKey(), tag, removeHistory);
yanzg's avatar
yanzg committed
577 578 579 580 581 582 583 584 585 586 587 588

        // Where条件包含的字段
        List<TableFieldVo> fields;
        if (!isRemove) {
            // 所有字段
            fields = this.getFields();
        } else {
            // 非删除时需要更新的字段
            fields = this.getFieldActionList(DaoConst.FIELD_COMMON, DaoConst.FIELD_REMOVE_UPDATE);
        }
        // 添加普通的Where条件
        for (TableFieldVo field : fields) {
yanzg's avatar
yanzg committed
589
            addWhereFieldCommon(sql, field, tag, removeHistory);
yanzg's avatar
yanzg committed
590
        }
yanzg's avatar
yanzg committed
591
    }
yanzg's avatar
yanzg committed
592

yanzg's avatar
yanzg committed
593 594
    private void addWhereFieldCommon(SqlData sql, TableFieldVo field, String tag, boolean removeHistory) {
        addWhereFieldNotExtend(sql, field.inputName, String.format(DaoConst.CODE_WHERE_EQUALS, tag, field.name, DaoConst.CODE_PARA), removeHistory);
yanzg's avatar
yanzg committed
595 596 597
        // 添加in条件
        String sqlIn = String.format(DaoConst.CODE_WHERE_IN, tag, field.name, DaoConst.CODE_PARA);
        if (field.inputLName.endsWith(DaoConst.CODE_WHERE_IN_END)) {
yanzg's avatar
yanzg committed
598
            addWhereFieldNotExtend(sql, field.inputName + DaoConst.CODE_WHERE_IN_END_ES, sqlIn, removeHistory);
yanzg's avatar
yanzg committed
599
        } else {
yanzg's avatar
yanzg committed
600
            addWhereFieldNotExtend(sql, field.inputName + DaoConst.CODE_WHERE_IN_END, sqlIn, removeHistory);
yanzg's avatar
yanzg committed
601 602 603
        }
    }

yanzg's avatar
yanzg committed
604 605 606 607 608
    private void addWhereFieldNotExtend(SqlData sql, String inputName, String sqlWhere, boolean removeHistory) {
        SqlDataField field = sql.getField(inputName);
        if (field == null) {
            // 添加新的条件
            sql.add(inputName, sqlWhere);
yanzg's avatar
yanzg committed
609
        } else if (field != null && removeHistory) {
yanzg's avatar
yanzg committed
610 611 612
            // 删除历史条件
            sql.removeField(inputName);
            // 添加新的条件
yanzg's avatar
yanzg committed
613
            sql.add(inputName, sqlWhere);
yanzg's avatar
yanzg committed
614 615 616
        }
    }

yanzg's avatar
yanzg committed
617 618 619
    /**
     * 添加删除WHERE条件字段
     *
yanzg's avatar
yanzg committed
620
     * @param sql SQL语句实体
yanzg's avatar
yanzg committed
621 622 623 624
     */
    private void addWhereRemove(SqlData sql) {
        if (getRemove() != null) {
            sql.addParaConst(DaoConst.REMOVE_FLAG_INPUT,
yanzg's avatar
yanzg committed
625
                    DaoConst.CODE_WHERE,
yanzg's avatar
yanzg committed
626 627
                    String.format(DaoConst.CODE_WHERE_EQUALS_NOT_REMOVE, this.getRemove().name)
            );
yanzg's avatar
yanzg committed
628
        }
yanzg's avatar
yanzg committed
629 630 631 632 633 634 635 636 637 638
    }

    /**
     * 版本号进行累加
     *
     * @param sql 需要处理的SQL语句
     */
    private void addUpdateVersion(SqlData sql) {
        // 添加版本字段
        if (getVersion() != null) {
yanzg's avatar
yanzg committed
639
            sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_VERSION_FIELD, getVersion().name, getVersion().name));
yanzg's avatar
yanzg committed
640 641 642 643 644 645
        }
    }

    /**
     * 生成SQL语句
     *
yanzg's avatar
yanzg committed
646
     * @param sqlType     SQL语句类型
yanzg's avatar
yanzg committed
647 648 649 650 651
     * @param name        SQL语句名称
     * @param model       SQL语句模板
     * @param valueModel  值字段模板
     * @param valueFields 值字段
     * @param whereFields WHERE字段
yanzg's avatar
yanzg committed
652
     * @return 生成的SQL语句
yanzg's avatar
yanzg committed
653
     */
yanzg's avatar
yanzg committed
654 655
    private SqlData releaseSql(int sqlType, String name, String model, String valueModel, List<TableFieldVo> valueFields, List<TableFieldVo> whereFields) {
        // 生成修改的SQL语句
yanzg's avatar
yanzg committed
656
        SqlData sql = new SqlData(name, model.replace(DaoConst.CODE_TABLE, this.name));
yanzg's avatar
yanzg committed
657
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
658
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
659 660
        String flag = StringHelper.EMPTY;
        for (TableFieldVo field : valueFields) {
yanzg's avatar
yanzg committed
661
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + valueModel.replace(DaoConst.CODE_FIELD, field.name));
yanzg's avatar
yanzg committed
662
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
663 664
        }

yanzg's avatar
yanzg committed
665
        for (TableFieldVo field : whereFields) {
yanzg's avatar
yanzg committed
666
            sql.addConst(field.inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, field.name));
yanzg's avatar
yanzg committed
667 668
        }

yanzg's avatar
yanzg committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
        return sql;
    }

    /**
     * 根据来源字符串获取结束字符串
     *
     * @param fieldFrom 来源字符串
     * @return 返回字符串
     */
    private List<TableFieldVo> getFieldString(TableFieldString fieldFrom) {
        List<TableFieldVo> list = new ArrayList<>();
        for (String fieldName : fieldFrom.getFields()) {
            list.add(this.getField(fieldName));
        }
        return list;
yanzg's avatar
yanzg committed
684 685 686 687 688
    }

    /**
     * 生成根据某些字段不存在则保存的SQL语句
     *
yanzg's avatar
yanzg committed
689 690 691
     * @param tableStruct 表结构
     * @param sqlName     SQL语句
     * @param whereFields WHERE条件
yanzg's avatar
yanzg committed
692 693
     */
    public void addSaveWithSql(TableSqlCache tableStruct, String sqlName, TableFieldString whereFields) {
yanzg's avatar
yanzg committed
694 695 696 697 698 699 700 701 702 703 704
        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
705
        SqlData sqlData = this.releaseSql(DaoConst.SQL_TYPE_SAVE_WITH, sqlName, DaoConst.SQL_LOAD, StringHelper.EMPTY, new ArrayList<>(), whereFields);
yanzg's avatar
yanzg committed
706
        sqlData.addParaConst(DaoConst.CODE_FIELD_DEFAULT_NAME, DaoConst.CODE_FIELD, DaoConst.CODE_FIELD_DEFAULT);
yanzg's avatar
yanzg committed
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
        tableStruct.add(sqlData);
    }

    /**
     * 生成统计的SQL语句
     *
     * @param sqlTableData 需要生成的实体
     * @param whereFields  WHERE字段
     * @param updateFields 需要增加的值的字段
     */
    public void addGroupSql(TableSqlCache sqlTableData, TableFieldString whereFields, TableFieldString updateFields) {
        addGroupSql(sqlTableData, getFieldString(whereFields), getFieldString(updateFields));
    }

    /**
     * 生成统计的SQL语句
     *
     * @param sqlTableData 需要生成的实体
     * @param whereFields  WHERE字段
     * @param updateFields 需要增加的值的字段
     */
    private void addGroupSql(TableSqlCache sqlTableData, List<TableFieldVo> whereFields, List<TableFieldVo> updateFields) {
yanzg's avatar
yanzg committed
729 730 731 732 733
        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);

        sqlTableData.add(sqlLoad);
yanzg's avatar
yanzg committed
734
        sqlTableData.add(this.releaseSql(DaoConst.SQL_TYPE_ADD_GROUP, DaoConst.GROUP_ADD, DaoConst.SQL_UPDATE,
yanzg's avatar
yanzg committed
735
                DaoConst.CODE_GROUP_ADD, updateFields, this.getFieldActionList(DaoConst.FIELD_PRIMARY)));
yanzg's avatar
yanzg committed
736 737 738 739 740
    }

    /**
     * 生成判断数据是否存在的SQL语句
     *
yanzg's avatar
yanzg committed
741 742 743 744
     * @param sqlTableData   表结构
     * @param sqlName        SQL语句的名称
     * @param mustField      需要判断的字段
     * @param allowNullField 需要判断的字段
yanzg's avatar
yanzg committed
745
     */
yanzg's avatar
yanzg committed
746 747
    public void addExist(TableSqlCache sqlTableData, String sqlName, TableFieldString mustField, TableFieldString allowNullField) {
        // String[] fields
yanzg's avatar
yanzg committed
748 749
        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
750

yanzg's avatar
yanzg committed
751
        sql.setSqlType(DaoConst.SQL_TYPE_EXISTS);
yanzg's avatar
yanzg committed
752
        sql.addConst(this.getKey().inputName,
yanzg's avatar
yanzg committed
753 754
                String.format(DaoConst.CODE_WHERE_NOT_EQUALS_PARA, this.getKey().name)
        );
yanzg's avatar
yanzg committed
755

yanzg's avatar
yanzg committed
756 757 758 759 760 761 762 763
        // 必须判断的字段
        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
764 765
        }

yanzg's avatar
yanzg committed
766 767 768 769 770 771 772 773
        // 允许空值的字段
        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
774
        }
yanzg's avatar
yanzg committed
775
        addWhereRemove(sql);
yanzg's avatar
yanzg committed
776 777
        sqlTableData.add(sql);
    }
yanzg's avatar
yanzg committed
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816


    /**
     * 表结构累加
     *
     * @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 {
                T histor = mapFrom.get(key);
                histor.add(from);
            }
        }

        return tos;
    }


yanzg's avatar
yanzg committed
817
}