Pārlūkot izejas kodu

fix: 初始化 TableInfo 中遇到多个字段有 @TableId 注解时未能抛出异常的问题
feat: 初始化 TableInfo 中遇到主键字段有 @TableField 注解则打印 warn 日志进行提醒
test: 补齐上述功能的test

miemie 5 gadi atpakaļ
vecāks
revīzija
87acd3a010

+ 13 - 4
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfo.java

@@ -184,6 +184,15 @@ public class TableInfo implements Constants {
         this.underCamel = configuration.isMapUnderscoreToCamelCase();
     }
 
+    /**
+     * 是否有主键
+     *
+     * @return 是否有
+     */
+    public boolean havePK() {
+        return StringUtils.isNotBlank(keyColumn);
+    }
+
     /**
      * 获取主键的 select sql 片段
      *
@@ -193,7 +202,7 @@ public class TableInfo implements Constants {
         if (sqlSelect != null) {
             return sqlSelect;
         }
-        if (StringUtils.isNotBlank(keyProperty)) {
+        if (havePK()) {
             sqlSelect = keyColumn;
             if (keyRelated) {
                 sqlSelect += (" AS " + keyProperty);
@@ -244,7 +253,7 @@ public class TableInfo implements Constants {
      */
     public String getKeyInsertSqlProperty(final String prefix, final boolean newLine) {
         final String newPrefix = prefix == null ? EMPTY : prefix;
-        if (StringUtils.isNotBlank(keyProperty)) {
+        if (havePK()) {
             if (idType == IdType.AUTO) {
                 return EMPTY;
             }
@@ -261,7 +270,7 @@ public class TableInfo implements Constants {
      * @return sql 脚本片段
      */
     public String getKeyInsertSqlColumn(final boolean newLine) {
-        if (StringUtils.isNotBlank(keyColumn)) {
+        if (havePK()) {
             if (idType == IdType.AUTO) {
                 return EMPTY;
             }
@@ -396,7 +405,7 @@ public class TableInfo implements Constants {
         if (autoInitResultMap && null == resultMap) {
             String id = currentNamespace + DOT + MYBATIS_PLUS + UNDERSCORE + entityType.getSimpleName();
             List<ResultMapping> resultMappings = new ArrayList<>();
-            if (keyType != null) {
+            if (havePK()) {
                 ResultMapping idMapping = new ResultMapping.Builder(configuration, keyProperty, keyColumn, keyType)
                     .flags(Collections.singletonList(ResultFlag.ID)).build();
                 resultMappings.add(idMapping);

+ 64 - 69
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java

@@ -261,19 +261,25 @@ public class TableInfoHelper {
             if (excludeProperty.contains(field.getName())) {
                 continue;
             }
-            /*
-             * 主键ID 初始化
-             */
-            if (!isReadPK) {
-                if (existTableId) {
-                    isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, clazz, reflector);
-                } else {
-                    isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, clazz, reflector);
+
+            /* 主键ID 初始化 */
+            if (existTableId) {
+                TableId tableId = field.getAnnotation(TableId.class);
+                if (tableId != null) {
+                    if (isReadPK) {
+                        throw ExceptionUtils.mpe("@TableId can't more than one in Class: \"%s\".", clazz.getName());
+                    } else {
+                        isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, tableId, reflector);
+                        continue;
+                    }
                 }
+            } else if (!isReadPK) {
+                isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, reflector);
                 if (isReadPK) {
                     continue;
                 }
             }
+
             /* 有 @TableField 注解的字段初始化 */
             if (initTableFieldWithAnnotation(dbConfig, tableInfo, fieldList, field)) {
                 continue;
@@ -285,14 +291,14 @@ public class TableInfoHelper {
 
         /* 检查逻辑删除字段只能有最多一个 */
         Assert.isTrue(fieldList.parallelStream().filter(TableFieldInfo::isLogicDelete).count() < 2L,
-            String.format("annotation of @TableLogic can't more than one in class : %s.", clazz.getName()));
+            String.format("@TableLogic can't more than one in Class: \"%s\".", clazz.getName()));
 
         /* 字段列表,不可变集合 */
         tableInfo.setFieldList(Collections.unmodifiableList(fieldList));
 
         /* 未发现主键注解,提示警告信息 */
-        if (StringUtils.isBlank(tableInfo.getKeyColumn())) {
-            logger.warn(String.format("Warn: Could not find @TableId in Class: %s.", clazz.getName()));
+        if (!isReadPK) {
+            logger.warn(String.format("Can not find table primary key in Class: \"%s\".", clazz.getName()));
         }
     }
 
@@ -316,48 +322,44 @@ public class TableInfoHelper {
      * @param dbConfig  全局配置信息
      * @param tableInfo 表信息
      * @param field     字段
-     * @param clazz     实体类
+     * @param tableId   注解
      * @param reflector Reflector
-     * @return true 继续下一个属性判断,返回 continue;
      */
     private static boolean initTableIdWithAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo,
-                                                     Field field, Class<?> clazz, Reflector reflector) {
-        TableId tableId = field.getAnnotation(TableId.class);
+                                                     Field field, TableId tableId, Reflector reflector) {
         boolean underCamel = tableInfo.isUnderCamel();
-        if (tableId != null) {
-            if (StringUtils.isBlank(tableInfo.getKeyColumn())) {
-                /* 主键策略( 注解 > 全局 ) */
-                // 设置 Sequence 其他策略无效
-                if (IdType.NONE == tableId.type()) {
-                    tableInfo.setIdType(dbConfig.getIdType());
-                } else {
-                    tableInfo.setIdType(tableId.type());
-                }
+        final String property = field.getName();
+        if (field.getAnnotation(TableField.class) != null) {
+            logger.warn(String.format("This \"%s\" is the table primary key by @TableId annotation in Class: \"%s\",So @TableField annotation will not work!",
+                property, tableInfo.getEntityType().getName()));
+        }
+        /* 主键策略( 注解 > 全局 ) */
+        // 设置 Sequence 其他策略无效
+        if (IdType.NONE == tableId.type()) {
+            tableInfo.setIdType(dbConfig.getIdType());
+        } else {
+            tableInfo.setIdType(tableId.type());
+        }
 
-                /* 字段 */
-                String column = field.getName();
-                if (StringUtils.isNotBlank(tableId.value())) {
-                    column = tableId.value();
-                } else {
-                    // 开启字段下划线申明
-                    if (underCamel) {
-                        column = StringUtils.camelToUnderline(column);
-                    }
-                    // 全局大写命名
-                    if (dbConfig.isCapitalMode()) {
-                        column = column.toUpperCase();
-                    }
-                }
-                tableInfo.setKeyRelated(checkRelated(underCamel, field.getName(), column))
-                    .setKeyColumn(column)
-                    .setKeyProperty(field.getName())
-                    .setKeyType(reflector.getGetterType(field.getName()));
-                return true;
-            } else {
-                throwExceptionId(clazz);
+        /* 字段 */
+        String column = property;
+        if (StringUtils.isNotBlank(tableId.value())) {
+            column = tableId.value();
+        } else {
+            // 开启字段下划线申明
+            if (underCamel) {
+                column = StringUtils.camelToUnderline(column);
+            }
+            // 全局大写命名
+            if (dbConfig.isCapitalMode()) {
+                column = column.toUpperCase();
             }
         }
-        return false;
+        tableInfo.setKeyRelated(checkRelated(underCamel, property, column))
+            .setKeyColumn(column)
+            .setKeyProperty(property)
+            .setKeyType(reflector.getGetterType(property));
+        return true;
     }
 
     /**
@@ -367,27 +369,27 @@ public class TableInfoHelper {
      *
      * @param tableInfo 表信息
      * @param field     字段
-     * @param clazz     实体类
      * @param reflector Reflector
      * @return true 继续下一个属性判断,返回 continue;
      */
     private static boolean initTableIdWithoutAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo,
-                                                        Field field, Class<?> clazz, Reflector reflector) {
-        String column = field.getName();
-        if (dbConfig.isCapitalMode()) {
-            column = column.toUpperCase();
-        }
-        if (DEFAULT_ID_NAME.equalsIgnoreCase(column)) {
-            if (StringUtils.isBlank(tableInfo.getKeyColumn())) {
-                tableInfo.setKeyRelated(checkRelated(tableInfo.isUnderCamel(), field.getName(), column))
-                    .setIdType(dbConfig.getIdType())
-                    .setKeyColumn(column)
-                    .setKeyProperty(field.getName())
-                    .setKeyType(reflector.getGetterType(field.getName()));
-                return true;
-            } else {
-                throwExceptionId(clazz);
+                                                        Field field, Reflector reflector) {
+        final String property = field.getName();
+        if (DEFAULT_ID_NAME.equalsIgnoreCase(property)) {
+            if (field.getAnnotation(TableField.class) != null) {
+                logger.warn(String.format("This \"%s\" is the table primary key by default name for `id` in Class: \"%s\",So @TableField will not work!",
+                    property, tableInfo.getEntityType().getName()));
+            }
+            String column = property;
+            if (dbConfig.isCapitalMode()) {
+                column = column.toUpperCase();
             }
+            tableInfo.setKeyRelated(checkRelated(tableInfo.isUnderCamel(), property, column))
+                .setIdType(dbConfig.getIdType())
+                .setKeyColumn(column)
+                .setKeyProperty(property)
+                .setKeyType(reflector.getGetterType(property));
+            return true;
         }
         return false;
     }
@@ -440,13 +442,6 @@ public class TableInfoHelper {
         }
     }
 
-    /**
-     * 发现设置多个主键注解抛出异常
-     */
-    private static void throwExceptionId(Class<?> clazz) {
-        throw ExceptionUtils.mpe("There must be only one, Discover multiple @TableId annotation in %s", clazz.getName());
-    }
-
     /**
      * <p>
      * 获取该类的所有属性列表

+ 50 - 8
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelperTest.java

@@ -3,14 +3,16 @@ package com.baomidou.mybatisplus.core.metadata;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 class TableInfoHelperTest {
 
     @Data
@@ -62,17 +64,57 @@ class TableInfoHelperTest {
 
     @Test
     void testIsExistTableId() {
-        Assertions.assertTrue(TableInfoHelper.isExistTableId(Arrays.asList(ModelOne.class.getDeclaredFields())));
-        Assertions.assertFalse(TableInfoHelper.isExistTableId(Arrays.asList(ModelTwo.class.getDeclaredFields())));
+        assertThat(TableInfoHelper.isExistTableId(Arrays.asList(ModelOne.class.getDeclaredFields()))).isTrue();
+        assertThat(TableInfoHelper.isExistTableId(Arrays.asList(ModelTwo.class.getDeclaredFields()))).isFalse();
     }
 
     @Test
-    void testExcludeProperty(){
+    void testExcludeProperty() {
         TableInfo tableInfo = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ModelThree.class);
-        Assertions.assertEquals(tableInfo.getFieldList().size(), 2);
-        tableInfo.getFieldList().forEach(field -> Assertions.assertNotEquals("test", field.getProperty()));
+        assertThat(tableInfo.havePK()).isTrue();
+        assertThat(tableInfo.getKeyProperty()).isEqualTo("id");
+        assertThat(tableInfo.getFieldList().size()).isEqualTo(2);
+        assertThat(tableInfo.getFieldList()).noneMatch(i -> i.getProperty().equals("test"));
+
         tableInfo = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ModelFour.class);
-        Assertions.assertEquals(tableInfo.getFieldList().size(), 2);
-        tableInfo.getFieldList().forEach(field -> Assertions.assertNotEquals("test", field.getProperty()));
+        assertThat(tableInfo.getFieldList().size()).isEqualTo(2);
+        assertThat(tableInfo.getFieldList()).noneMatch(i -> i.getProperty().equals("test"));
+    }
+
+    @Test
+    void testMoreTableId() {
+        Exception ex = null;
+        try {
+            TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ModelFive.class);
+        } catch (Exception e) {
+            ex = e;
+        }
+        assertThat(ex).isNotNull();
+        assertThat(ex).isInstanceOf(MybatisPlusException.class);
+        System.out.println(ex.getMessage());
+    }
+
+    @Test
+    void testPriorityTableId() {
+        TableInfo tableInfo = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ModelSex.class);
+        assertThat(tableInfo.havePK()).isTrue();
+        assertThat(tableInfo.getKeyProperty()).isEqualTo("realId");
+    }
+
+    @Data
+    private static class ModelFive {
+
+        @TableId
+        private String id1;
+
+        @TableId
+        private String id2;
+    }
+
+    @Data
+    private static class ModelSex {
+
+        @TableId
+        private String realId;
     }
 }