Browse Source

TableInfo 初始化优化

miemie 5 years ago
parent
commit
48c443ee81

+ 15 - 15
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java

@@ -104,6 +104,10 @@ public class TableFieldInfo implements Constants {
      * <p>大字段可设置为 false 不加入 select 查询范围</p>
      */
     private boolean select = true;
+    /**
+     * 是否是逻辑删除字段
+     */
+    private boolean logicDelete = false;
     /**
      * 逻辑删除值
      */
@@ -159,7 +163,7 @@ public class TableFieldInfo implements Constants {
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
     public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, TableField tableField,
-                          Reflector reflector) {
+                          Reflector reflector, boolean existTableLogic) {
         field.setAccessible(true);
         this.field = field;
         this.version = field.getAnnotation(Version.class) != null;
@@ -187,7 +191,7 @@ public class TableFieldInfo implements Constants {
             el += (COMMA + "numericScale=" + numericScale);
         }
         this.el = el;
-        this.initLogicDelete(dbConfig, field);
+        this.initLogicDelete(dbConfig, field, existTableLogic);
 
         String column = tableField.value();
         if (StringUtils.isBlank(column)) {
@@ -242,7 +246,8 @@ public class TableFieldInfo implements Constants {
     /**
      * 不存在 TableField 注解时, 使用的构造函数
      */
-    public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Reflector reflector) {
+    public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Reflector reflector,
+                          boolean existTableLogic) {
         field.setAccessible(true);
         this.field = field;
         this.version = field.getAnnotation(Version.class) != null;
@@ -254,7 +259,7 @@ public class TableFieldInfo implements Constants {
         this.insertStrategy = dbConfig.getInsertStrategy();
         this.updateStrategy = dbConfig.getUpdateStrategy();
         this.whereStrategy = dbConfig.getSelectStrategy();
-        this.initLogicDelete(dbConfig, field);
+        this.initLogicDelete(dbConfig, field, existTableLogic);
 
         String column = this.property;
         if (tableInfo.isUnderCamel()) {
@@ -291,7 +296,7 @@ public class TableFieldInfo implements Constants {
      * @param dbConfig 数据库全局配置
      * @param field    字段属性对象
      */
-    private void initLogicDelete(GlobalConfig.DbConfig dbConfig, Field field) {
+    private void initLogicDelete(GlobalConfig.DbConfig dbConfig, Field field, boolean existTableLogic) {
         /* 获取注解属性,逻辑处理字段 */
         TableLogic tableLogic = field.getAnnotation(TableLogic.class);
         if (null != tableLogic) {
@@ -305,22 +310,17 @@ public class TableFieldInfo implements Constants {
             } else {
                 this.logicDeleteValue = dbConfig.getLogicDeleteValue();
             }
-        } else {
-            String globalLogicDeleteField = dbConfig.getLogicDeleteField();
-            if (StringUtils.isNotBlank(globalLogicDeleteField) && globalLogicDeleteField.equalsIgnoreCase(field.getName())) {
+            this.logicDelete = true;
+        } else if (!existTableLogic) {
+            String deleteField = dbConfig.getLogicDeleteField();
+            if (StringUtils.isNotBlank(deleteField) && this.property.equals(deleteField)) {
                 this.logicNotDeleteValue = dbConfig.getLogicNotDeleteValue();
                 this.logicDeleteValue = dbConfig.getLogicDeleteValue();
+                this.logicDelete = true;
             }
         }
     }
 
-    /**
-     * 是否启用了逻辑删除
-     */
-    public boolean isLogicDelete() {
-        return StringUtils.isNotBlank(logicDeleteValue) && StringUtils.isNotBlank(logicNotDeleteValue);
-    }
-
     /**
      * 获取 insert 时候插入值 sql 脚本片段
      * <p>insert into table (字段) values (值)</p>

+ 17 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfo.java

@@ -33,6 +33,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Predicate;
 
 import static java.util.stream.Collectors.joining;
@@ -157,6 +158,14 @@ public class TableInfo implements Constants {
     @Getter
     @Setter(AccessLevel.NONE)
     private TableFieldInfo versionFieldInfo;
+    /**
+     * 逻辑删除字段
+     *
+     * @since 3.3.3
+     */
+    @Getter
+    @Setter(AccessLevel.NONE)
+    private TableFieldInfo logicFieldInfo;
 
     public TableInfo(Class<?> entityType) {
         this.entityType = entityType;
@@ -419,9 +428,13 @@ public class TableInfo implements Constants {
 
     void setFieldList(List<TableFieldInfo> fieldList) {
         this.fieldList = fieldList;
+        AtomicInteger logicDeleted = new AtomicInteger();
+        AtomicInteger version = new AtomicInteger();
         fieldList.forEach(i -> {
             if (i.isLogicDelete()) {
                 this.logicDelete = true;
+                this.logicFieldInfo = i;
+                logicDeleted.getAndAdd(1);
             }
             if (i.isWithInsertFill()) {
                 this.withInsertFill = true;
@@ -432,8 +445,12 @@ public class TableInfo implements Constants {
             if (i.isVersion()) {
                 this.withVersion = true;
                 this.versionFieldInfo = i;
+                version.getAndAdd(1);
             }
         });
+        /* 校验字段合法性 */
+        Assert.isTrue(logicDeleted.get() <= 1, "@TableLogic not support more than one in Class: \"%s\"", entityType.getName());
+        Assert.isTrue(version.get() <= 1, "@Version not support more than one in Class: \"%s\"", entityType.getName());
     }
 
     public List<TableFieldInfo> getFieldList() {

+ 18 - 8
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java

@@ -246,6 +246,8 @@ public class TableInfoHelper {
         boolean isReadPK = false;
         // 是否存在 @TableId 注解
         boolean existTableId = isExistTableId(list);
+        // 是否存在 @TableLogic 注解
+        boolean existTableLogic = isExistTableLogic(list);
 
         List<TableFieldInfo> fieldList = new ArrayList<>(list.size());
         for (Field field : list) {
@@ -275,20 +277,16 @@ public class TableInfoHelper {
 
             /* 有 @TableField 注解的字段初始化 */
             if (tableField != null) {
-                fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector));
+                fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic));
                 continue;
             }
 
             /* 无 @TableField 注解的字段初始化 */
-            fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector));
+            fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic));
         }
 
-        /* 检查逻辑删除字段只能有最多一个 */
-        Assert.isTrue(fieldList.parallelStream().filter(TableFieldInfo::isLogicDelete).count() < 2L,
-            String.format("@TableLogic can't more than one in Class: \"%s\".", clazz.getName()));
-
-        /* 字段列表,不可变集合 */
-        tableInfo.setFieldList(Collections.unmodifiableList(fieldList));
+        /* 字段列表 */
+        tableInfo.setFieldList(fieldList);
 
         /* 未发现主键注解,提示警告信息 */
         if (!isReadPK) {
@@ -308,6 +306,18 @@ public class TableInfoHelper {
         return list.stream().anyMatch(field -> field.isAnnotationPresent(TableId.class));
     }
 
+    /**
+     * <p>
+     * 判断逻辑删除注解是否存在
+     * </p>
+     *
+     * @param list 字段列表
+     * @return true 为存在 @TableId 注解;
+     */
+    public static boolean isExistTableLogic(List<Field> list) {
+        return list.stream().anyMatch(field -> field.isAnnotationPresent(TableLogic.class));
+    }
+
     /**
      * <p>
      * 主键属性初始化

+ 52 - 0
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/metadata/TableInfoHelperTest.java

@@ -1,11 +1,16 @@
 package com.baomidou.mybatisplus.test.metadata;
 
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.config.GlobalConfig;
 import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
+import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
@@ -13,6 +18,8 @@ import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -104,6 +111,33 @@ class TableInfoHelperTest {
         assertThat(tableInfo.getKeyProperty()).isEqualTo("realId");
     }
 
+    @Test
+    void testVersion() {
+        Exception ex = null;
+        try {
+            TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), Versions.class);
+        } catch (Exception e) {
+            ex = e;
+        }
+        assertThat(ex).isNotNull();
+        assertThat(ex).isInstanceOf(MybatisPlusException.class);
+        System.out.println(ex.getMessage());
+    }
+
+    @Test
+    void testLogic() {
+        MybatisConfiguration configuration = new MybatisConfiguration();
+        GlobalConfig config = GlobalConfigUtils.defaults();
+        config.getDbConfig().setLogicDeleteField("logic");
+        GlobalConfigUtils.setGlobalConfig(configuration, config);
+        TableInfo tableInfo = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), Logic.class);
+        assertThat(tableInfo.isLogicDelete()).isTrue();
+        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
+        List<TableFieldInfo> logic = fieldList.stream().filter(TableFieldInfo::isLogicDelete).collect(Collectors.toList());
+        assertThat(logic.size()).isEqualTo(1);
+        assertThat(logic.get(0).getProperty()).isEqualTo("deleted");
+    }
+
     @Data
     private static class ModelFive {
 
@@ -120,4 +154,22 @@ class TableInfoHelperTest {
         @TableId
         private String realId;
     }
+
+    @Data
+    private static class Logic {
+
+        private Integer logic;
+
+        @TableLogic
+        private Integer deleted;
+    }
+
+    @Data
+    private static class Versions {
+
+        @Version
+        private Integer version1;
+        @Version
+        private Integer version2;
+    }
 }