TableStruct.java 22.2 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.util.helper.StringHelper;
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 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    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();
            if (field.getField() == null && field.getGetMethod() == null) {
                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 84 85 86

        // 默认后台数据库字段和前台参数字段为字段名,字段类型为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();
        } else if (field.getGetMethod() != null) {
            annotation = field.getGetMethod().getAnnotation(TableAnnotation.class);
            fieldType = field.getGetMethod().getReturnType();
        }

        // 注解不为空,则修改后台数据库映射字段、字段类型
        if (annotation != null) {
yanzg's avatar
yanzg committed
87 88 89
            if (!StringHelper.isEmpty(annotation.value())) {
                fieldName = annotation.value();
            }
yanzg's avatar
yanzg committed
90 91 92 93 94 95 96 97 98 99 100 101
            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
102 103
        int resultActionType = getActionType(fieldAction, stringAction);
        if (resultActionType == DaoConst.FIELD_PRIMARY) {
yanzg's avatar
yanzg committed
104 105 106 107 108 109 110 111 112 113
            // 将历史主键添加到普通列,并且移除历史主键
            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
114 115
            boolean isTypeMany = resultActionType != DaoConst.FIELD_MD5
                    && resultActionType != DaoConst.FIELD_REMOVE
yanzg's avatar
yanzg committed
116 117 118 119
                    && resultActionType != DaoConst.FIELD_VERSION
                    && resultActionType != DaoConst.FIELD_COMMON;

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

yanzg's avatar
yanzg committed
137 138
    }

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

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

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

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

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

yanzg's avatar
yanzg committed
239 240 241
    /**
     * 获取表名
     *
yanzg's avatar
yanzg committed
242
     * @return 获取到的名称
yanzg's avatar
yanzg committed
243
     */
yanzg's avatar
yanzg committed
244
    public String getName() {
yanzg's avatar
yanzg committed
245
        return name;
yanzg's avatar
yanzg committed
246 247
    }

yanzg's avatar
yanzg committed
248 249 250
    /**
     * 设置表名
     *
yanzg's avatar
yanzg committed
251
     * @param name 设置的表名
yanzg's avatar
yanzg committed
252
     */
yanzg's avatar
yanzg committed
253
    public void setName(String name) {
yanzg's avatar
yanzg committed
254
        this.name = name;
yanzg's avatar
yanzg committed
255 256
    }

yanzg's avatar
yanzg committed
257 258 259
    /**
     * 主键
     *
yanzg's avatar
yanzg committed
260
     * @return 获取到的键值
yanzg's avatar
yanzg committed
261
     */
yanzg's avatar
yanzg committed
262
    public TableFieldVo getKey() {
yanzg's avatar
yanzg committed
263
        return getFieldAction(DaoConst.FIELD_PRIMARY);
yanzg's avatar
yanzg committed
264 265
    }

yanzg's avatar
yanzg committed
266 267 268
    /**
     * 主键名称
     *
yanzg's avatar
yanzg committed
269
     * @return 主键名称
yanzg's avatar
yanzg committed
270 271 272
     */
    public String getKeyName() {
        return this.getKey().inputName;
yanzg's avatar
yanzg committed
273 274
    }

yanzg's avatar
yanzg committed
275 276 277
    /**
     * 主键数据类型
     *
yanzg's avatar
yanzg committed
278
     * @return 主键类型
yanzg's avatar
yanzg committed
279 280 281
     */
    public Class<?> getKeyType() {
        return this.getKey().type;
yanzg's avatar
yanzg committed
282 283
    }

yanzg's avatar
yanzg committed
284 285 286
    /**
     * MD5缓存字段
     *
yanzg's avatar
yanzg committed
287
     * @return md5字段
yanzg's avatar
yanzg committed
288 289 290 291 292 293 294 295
     */
    public TableFieldVo getMd5Key() {
        return getFieldAction(DaoConst.FIELD_MD5);
    }

    /**
     * MD5缓存键值
     *
yanzg's avatar
yanzg committed
296
     * @return MD5名称
yanzg's avatar
yanzg committed
297
     */
yanzg's avatar
yanzg committed
298
    public String getMD5KeyName() {
yanzg's avatar
yanzg committed
299
        TableFieldVo md5Key = this.getMd5Key();
yanzg's avatar
yanzg committed
300
        return md5Key != null ? md5Key.inputName : null;
yanzg's avatar
yanzg committed
301 302
    }

yanzg's avatar
yanzg committed
303 304 305
    /**
     * 判断是否包含版本号字段
     *
yanzg's avatar
yanzg committed
306
     * @return 版本号字段
yanzg's avatar
yanzg committed
307 308 309 310 311 312 313 314
     */
    public TableFieldVo getVersion() {
        return getFieldAction(DaoConst.FIELD_VERSION);
    }

    /**
     * 判断是否包含remove字段
     *
yanzg's avatar
yanzg committed
315
     * @return 删除字段
yanzg's avatar
yanzg committed
316
     */
yanzg's avatar
yanzg committed
317
    public TableFieldVo getRemove() {
yanzg's avatar
yanzg committed
318
        return getFieldAction(DaoConst.FIELD_REMOVE);
yanzg's avatar
yanzg committed
319 320
    }

yanzg's avatar
yanzg committed
321 322 323 324 325 326 327 328 329 330

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

yanzg's avatar
yanzg committed
331
    /**
yanzg's avatar
yanzg committed
332
     * 获取某一列
yanzg's avatar
yanzg committed
333
     *
yanzg's avatar
yanzg committed
334
     * @param name 列名
yanzg's avatar
yanzg committed
335
     * @return 获取到的字段
yanzg's avatar
yanzg committed
336
     */
yanzg's avatar
yanzg committed
337 338 339 340 341 342 343 344 345 346
    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
347 348 349 350 351
    }

    /**
     * 通过表结构自动生成SQL语句
     *
yanzg's avatar
yanzg committed
352
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
353 354
     */
    public void init(TableSqlCache table) {
yanzg's avatar
yanzg committed
355
        table.setTable(this);
yanzg's avatar
yanzg committed
356 357
        if (!StringHelper.isEmpty(this.name)) {
            table.add(releaseSqlCreate(), releaseSqlUpdate(), releaseSqlRemove(), releaseSqlLoad());
yanzg's avatar
yanzg committed
358
        }
yanzg's avatar
yanzg committed
359 360 361 362 363 364
        initSaveWith(table);
        initAddGroup(table);
    }

    /**
     * 初始化SaveWith
yanzg's avatar
yanzg committed
365 366
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
367 368 369 370 371 372 373 374 375 376 377
     */
    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
378 379
     *
     * @return 初始化的表SQL语句
yanzg's avatar
yanzg committed
380 381 382 383 384 385 386 387 388 389
     */
    private void initAddGroup(TableSqlCache table) {
        List<TableFieldVo> addGroupField = getFieldActionList(DaoConst.FIELD_ADD_GROUP);
        if (addGroupField == null || addGroupField.isEmpty()) {
            return;
        }
        List<TableFieldVo> commonField = getFieldActionList(DaoConst.FIELD_COMMON,
                DaoConst.FIELD_ADD_GROUP, DaoConst.FIELD_MD5,
                DaoConst.FIELD_REMOVE, DaoConst.FIELD_REMOVE_UPDATE, DaoConst.FIELD_CREATE);
        this.addGroupSql(table, commonField, addGroupField);
yanzg's avatar
yanzg committed
390 391 392 393 394
    }

    /**
     * 生成创建的SQL语句
     *
yanzg's avatar
yanzg committed
395
     * @return 生成的语句
yanzg's avatar
yanzg committed
396 397 398
     */
    private SqlData releaseSqlCreate() {
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
399
        String text = DaoConst.SQL_INSERT.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
400
        SqlData sql = new SqlData(DaoConst.CREATE, text);
yanzg's avatar
yanzg committed
401
        sql.setSqlType(DaoConst.SQL_TYPE_CREATE);
yanzg's avatar
yanzg committed
402 403
        // 第一个增加的字段,不需要增加 ","
        String flag = StringHelper.EMPTY;
yanzg's avatar
yanzg committed
404
        if (this.getKeyType() == String.class) {
yanzg's avatar
yanzg committed
405 406
            sql.addParaConst(this.getKey().inputName, DaoConst.CODE_FIELD, this.getKey().name,
                    DaoConst.CODE_VALUES, DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
407 408
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
409
        }
yanzg's avatar
yanzg committed
410
        for (TableFieldVo field : this.getFields()) {
yanzg's avatar
yanzg committed
411 412
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + field.name,
                    DaoConst.CODE_VALUES, flag + DaoConst.CODE_PARA
yanzg's avatar
yanzg committed
413 414
            );
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
415 416 417 418 419 420 421
        }
        return sql;
    }

    /**
     * 生成修改的SQL语句
     *
yanzg's avatar
yanzg committed
422
     * @return 生成的语句
yanzg's avatar
yanzg committed
423 424 425
     */
    private SqlData releaseSqlUpdate() {
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
426
        String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
427
        SqlData sql = new SqlData(DaoConst.UPDATE, text);
yanzg's avatar
yanzg committed
428
        sql.setSqlType(DaoConst.SQL_TYPE_UPDATE);
yanzg's avatar
yanzg committed
429

yanzg's avatar
yanzg committed
430
        // 主键字段操作
yanzg's avatar
yanzg committed
431
        sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_PRIMARY, this.getKey().name, this.getKey().name));
yanzg's avatar
yanzg committed
432
        sql.addConst(this.getKey().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, this.getKey().name));
yanzg's avatar
yanzg committed
433

yanzg's avatar
yanzg committed
434
        // 增加普通代码片段字段
yanzg's avatar
yanzg committed
435 436 437
        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
438
            sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
439
                    DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
440
            );
yanzg's avatar
yanzg committed
441
        }
yanzg's avatar
yanzg committed
442
        // 添加删除字段
yanzg's avatar
yanzg committed
443 444 445 446 447
        addWhereRemove(sql);
        addUpdateVersion(sql);
        // 添加版本号条件
        if (getVersion() != null) {
            sql.addConst(getVersion().inputName, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, getVersion().name));
yanzg's avatar
yanzg committed
448 449 450 451 452 453 454
        }
        return sql;
    }

    /**
     * 生成删除的SQL语句
     *
yanzg's avatar
yanzg committed
455
     * @return 生成的语句
yanzg's avatar
yanzg committed
456
     */
yanzg's avatar
yanzg committed
457
    private SqlData releaseSqlRemove() {
yanzg's avatar
yanzg committed
458
        if (this.getRemove() != null) {
yanzg's avatar
yanzg committed
459
            // 生成添加的SQL语句
yanzg's avatar
yanzg committed
460
            String text = DaoConst.SQL_UPDATE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
461
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
462
            sql.setSqlType(DaoConst.SQL_TYPE_REMOVE);
yanzg's avatar
yanzg committed
463 464

            // 设置删除字段标记
yanzg's avatar
yanzg committed
465
            sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_REMOVE, this.getRemove().name));
yanzg's avatar
yanzg committed
466 467

            // 设置删除时需要修改的字段的值
yanzg's avatar
yanzg committed
468
            for (TableFieldVo field : this.getFieldActionList(DaoConst.FIELD_REMOVE_UPDATE)) {
yanzg's avatar
yanzg committed
469
                sql.addParaConst(field.inputName,
yanzg's avatar
yanzg committed
470
                        DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_FIELD_PARA, field.name)
yanzg's avatar
yanzg committed
471
                );
yanzg's avatar
yanzg committed
472
            }
yanzg's avatar
yanzg committed
473 474 475 476
            // 增加版本号字段的值
            addUpdateVersion(sql);
            // 生成逻辑删除WHERE条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
477 478
            return sql;
        } else {
yanzg's avatar
yanzg committed
479
            String text = DaoConst.SQL_REMOVE.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
480
            SqlData sql = new SqlData(DaoConst.REMOVE, text);
yanzg's avatar
yanzg committed
481 482
            // 生成删除语句Where条件
            addWhereField(sql, DaoConst.CODE_TAG, true);
yanzg's avatar
yanzg committed
483 484 485 486 487 488 489
            return sql;
        }
    }

    /**
     * 生成加载的SQL语句
     *
yanzg's avatar
yanzg committed
490
     * @return 生成的语句
yanzg's avatar
yanzg committed
491 492 493
     */
    private SqlData releaseSqlLoad() {
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
494
        String text = DaoConst.SQL_LOAD.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
495
        SqlData sql = new SqlData(DaoConst.LOAD, text);
yanzg's avatar
yanzg committed
496
        sql.setSqlType(DaoConst.SQL_TYPE_LOAD);
yanzg's avatar
yanzg committed
497 498
        // 生成加载语句的WHERE条件
        addWhereField(sql, DaoConst.CODE_TAG, false);
yanzg's avatar
yanzg committed
499 500 501 502 503 504
        return sql;
    }

    /**
     * 当前当前表所有字段的等于SQL语句
     *
yanzg's avatar
yanzg committed
505 506 507 508
     * @param sql      SDL语句
     * @param tag      标记
     * @param isRemove 是否生成删除相关字段
     * @return 生成的语句
yanzg's avatar
yanzg committed
509
     */
yanzg's avatar
yanzg committed
510
    private void addWhereField(SqlData sql, String tag, boolean isRemove) {
yanzg's avatar
yanzg committed
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
        sql.add(this.getKey().inputName,
                String.format(DaoConst.CODE_WHERE_EQUALS, tag, this.getKey().name, DaoConst.CODE_PARA)
        );

        // 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) {
            sql.add(field.inputName,
                    String.format(DaoConst.CODE_WHERE_EQUALS, tag, field.name, DaoConst.CODE_PARA)
            );
yanzg's avatar
yanzg committed
529
        }
yanzg's avatar
yanzg committed
530 531 532
        // 查询时,不能查询到非删除的字段
        addWhereRemove(sql);
    }
yanzg's avatar
yanzg committed
533

yanzg's avatar
yanzg committed
534 535 536
    /**
     * 添加删除WHERE条件字段
     *
yanzg's avatar
yanzg committed
537
     * @param sql SQL语句实体
yanzg's avatar
yanzg committed
538 539 540 541
     */
    private void addWhereRemove(SqlData sql) {
        if (getRemove() != null) {
            sql.addParaConst(DaoConst.REMOVE_FLAG_INPUT,
yanzg's avatar
yanzg committed
542
                    DaoConst.CODE_WHERE,
yanzg's avatar
yanzg committed
543 544
                    String.format(DaoConst.CODE_WHERE_EQUALS_NOT_REMOVE, this.getRemove().name)
            );
yanzg's avatar
yanzg committed
545
        }
yanzg's avatar
yanzg committed
546 547 548 549 550 551 552 553 554 555
    }

    /**
     * 版本号进行累加
     *
     * @param sql 需要处理的SQL语句
     */
    private void addUpdateVersion(SqlData sql) {
        // 添加版本字段
        if (getVersion() != null) {
yanzg's avatar
yanzg committed
556
            sql.addCode(DaoConst.CODE_FIELD, String.format(DaoConst.CODE_UPDATE_VERSION_FIELD, getVersion().name, getVersion().name));
yanzg's avatar
yanzg committed
557 558 559 560 561 562
        }
    }

    /**
     * 生成SQL语句
     *
yanzg's avatar
yanzg committed
563
     * @param sqlType     SQL语句类型
yanzg's avatar
yanzg committed
564 565 566 567 568
     * @param name        SQL语句名称
     * @param model       SQL语句模板
     * @param valueModel  值字段模板
     * @param valueFields 值字段
     * @param whereFields WHERE字段
yanzg's avatar
yanzg committed
569
     * @return 生成的SQL语句
yanzg's avatar
yanzg committed
570
     */
yanzg's avatar
yanzg committed
571
    private SqlData releaseSql(int sqlType, String name, String model, String valueModel, List<TableFieldVo> valueFields, List<TableFieldVo> whereFields) {
yanzg's avatar
yanzg committed
572 573
        // 参数字段
        List<String> paraFields = new ArrayList<String>();
yanzg's avatar
yanzg committed
574
        // 生成修改的SQL语句
yanzg's avatar
yanzg committed
575
        SqlData sql = new SqlData(name, model.replace(DaoConst.CODE_TABLE, this.name));
yanzg's avatar
yanzg committed
576
        sql.setSqlType(sqlType);
yanzg's avatar
yanzg committed
577
        // 生成添加的SQL语句
yanzg's avatar
yanzg committed
578 579
        String flag = StringHelper.EMPTY;
        for (TableFieldVo field : valueFields) {
yanzg's avatar
yanzg committed
580
            sql.addParaConst(field.inputName, DaoConst.CODE_FIELD, flag + valueModel.replace(DaoConst.CODE_FIELD, field.name));
yanzg's avatar
yanzg committed
581
            flag = DaoConst.CODE_SPLIT;
yanzg's avatar
yanzg committed
582 583
        }

yanzg's avatar
yanzg committed
584
        for (TableFieldVo field : whereFields) {
yanzg's avatar
yanzg committed
585
            sql.addParaConst(field.inputName, DaoConst.CODE_WHERE, String.format(DaoConst.CODE_WHERE_EQUALS_PARA, field.name));
yanzg's avatar
yanzg committed
586 587
        }

yanzg's avatar
yanzg committed
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
        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
603 604 605 606 607
    }

    /**
     * 生成根据某些字段不存在则保存的SQL语句
     *
yanzg's avatar
yanzg committed
608 609 610
     * @param tableStruct 表结构
     * @param sqlName     SQL语句
     * @param whereFields WHERE条件
yanzg's avatar
yanzg committed
611 612
     */
    public void addSaveWithSql(TableSqlCache tableStruct, String sqlName, TableFieldString whereFields) {
yanzg's avatar
yanzg committed
613 614 615 616 617 618 619 620 621 622 623
        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
624
        SqlData sqlData = this.releaseSql(DaoConst.SQL_TYPE_SAVE_WITH, sqlName, DaoConst.SQL_LOAD, StringHelper.EMPTY, new ArrayList<>(), whereFields);
yanzg's avatar
yanzg committed
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
        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
647
        sqlTableData.add(this.releaseSql(DaoConst.SQL_TYPE_ADD_GROUP, DaoConst.GROUP_QUERY, DaoConst.SQL_LOAD,
yanzg's avatar
yanzg committed
648
                StringHelper.EMPTY, new ArrayList<>(), whereFields));
yanzg's avatar
yanzg committed
649
        sqlTableData.add(this.releaseSql(DaoConst.SQL_TYPE_ADD_GROUP, DaoConst.GROUP_ADD, DaoConst.SQL_UPDATE,
yanzg's avatar
yanzg committed
650
                DaoConst.CODE_GROUP_ADD, updateFields, this.getFieldActionList(DaoConst.FIELD_PRIMARY)));
yanzg's avatar
yanzg committed
651 652 653 654 655
    }

    /**
     * 生成判断数据是否存在的SQL语句
     *
yanzg's avatar
yanzg committed
656 657 658
     * @param sqlTableData 表结构
     * @param sqlName      SQL语句的名称
     * @param fields       需要判断的字段
yanzg's avatar
yanzg committed
659 660
     */
    public void addExist(TableSqlCache sqlTableData, String sqlName, String[] fields) {
yanzg's avatar
yanzg committed
661
        String text = DaoConst.SQL_LOAD.replace(DaoConst.CODE_TABLE, this.name);
yanzg's avatar
yanzg committed
662
        SqlData sql = new SqlData(sqlName, text);
yanzg's avatar
yanzg committed
663
        sql.setSqlType(DaoConst.SQL_TYPE_EXISTS);
yanzg's avatar
yanzg committed
664
        sql.addConst(this.getKey().inputName,
yanzg's avatar
yanzg committed
665 666
                String.format(DaoConst.CODE_WHERE_NOT_EQUALS_PARA, this.getKey().name)
        );
yanzg's avatar
yanzg committed
667 668 669

        for (String fieldName : fields) {
            TableFieldVo field = this.getField(fieldName);
yanzg's avatar
yanzg committed
670
            sql.addConst(field.inputName,
yanzg's avatar
yanzg committed
671
                    String.format(DaoConst.CODE_WHERE_EQUALS_NOT_EMPTY_PARA, field.name)
yanzg's avatar
yanzg committed
672
            );
yanzg's avatar
yanzg committed
673
        }
yanzg's avatar
yanzg committed
674
        addWhereRemove(sql);
yanzg's avatar
yanzg committed
675 676 677
        sqlTableData.add(sql);
    }
}