14 Commits 02750cd7ce ... ad123d4704

Autor SHA1 Nachricht Datum
  nieqiurong ad123d4704 调整pom生成. vor 2 Monaten
  nieqiurong 40a781e449 更新快照. vor 2 Monaten
  nieqiurong 06a78c5d4c 调整Hive2Dialect方言. vor 2 Monaten
  nieqiurong 4a05e6236a 调整Kotlin单元测试. vor 2 Monaten
  dongwei d4ff30c4de 增加支持hive2分页查询功能 vor 2 Monaten
  nieqiurong 53650e30db 调整数据比较. vor 2 Monaten
  nieqiurong 1da47664ea 增加快照仓库. vor 2 Monaten
  yuxiaobin c479af1cc2 Merge pull request #6563 from musicguoke/patch-1 vor 3 Monaten
  nieqiurong ecd46793b0 启用kotlin单元测试. vor 3 Monaten
  nieqiurong 72b880c947 导包区分处理. vor 3 Monaten
  nieqiurong b494e71a2b 更新日志. vor 3 Monaten
  nieqiurong d21b78e848 支持Serial注解. vor 3 Monaten
  musicguoke 131333284c Update DataChangeRecorderInnerInterceptor.java vor 7 Monaten
  musicguoke ae617948f8 Update DataChangeRecorderInnerInterceptor.java vor 7 Monaten
48 geänderte Dateien mit 670 neuen und 138 gelöschten Zeilen
  1. 10 0
      build.gradle
  2. 19 0
      changelog-temp.md
  3. 1 1
      gradle.properties
  4. 4 0
      mybatis-plus-annotation/src/main/java/com/baomidou/mybatisplus/annotation/DbType.java
  5. 2 0
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/DialectFactory.java
  6. 40 0
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/Hive2Dialect.java
  7. 2 0
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/JdbcUtils.java
  8. 31 4
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/Entity.java
  9. 44 3
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/Mapper.java
  10. 2 2
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/po/TableField.java
  11. 11 0
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/po/TableInfo.java
  12. 8 1
      mybatis-plus-generator/src/main/resources/templates/entity.java.btl
  13. 8 1
      mybatis-plus-generator/src/main/resources/templates/entity.java.ej
  14. 8 1
      mybatis-plus-generator/src/main/resources/templates/entity.java.ftl
  15. 8 1
      mybatis-plus-generator/src/main/resources/templates/entity.java.vm
  16. 5 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.btl
  17. 5 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.ej
  18. 5 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.ftl
  19. 5 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.vm
  20. 6 5
      mybatis-plus-generator/src/main/resources/templates/mapper.java.btl
  21. 5 5
      mybatis-plus-generator/src/main/resources/templates/mapper.java.ej
  22. 6 6
      mybatis-plus-generator/src/main/resources/templates/mapper.java.ftl
  23. 5 6
      mybatis-plus-generator/src/main/resources/templates/mapper.java.vm
  24. 4 4
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java
  25. 14 16
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  26. 30 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java
  27. 4 4
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java
  28. 14 16
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  29. 30 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java
  30. 1 1
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-common/src/main/java/com/baomidou/mybatisplus/jsqlparser/JsqlParserThreadPool.java
  31. 4 4
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java
  32. 14 16
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  33. 30 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java
  34. 0 1
      mybatis-plus-spring/src/test/kotlin/com/baomidou/mybatisplus/test/kotlin/BaseDbTest.kt
  35. 18 0
      mybatis-plus/build.gradle
  36. 10 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/pom/GeneratePomTest.java
  37. 50 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/KtTestConfig.kt
  38. 110 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/MetaObjectHandlerTest.kt
  39. 20 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/MyMetaObjectHandler.kt
  40. 37 4
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/KtH2UserTest.kt
  41. 12 5
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/entity/KtH2User.kt
  42. 9 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/mapper/KtUserMapper.kt
  43. 7 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/service/KtH2UserService.kt
  44. 12 0
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/service/impl/KtH2UserServiceImpl.kt
  45. 0 7
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/mapper/KtUserMapper.kt
  46. 0 7
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/KtH2UserService.kt
  47. 0 12
      mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/impl/KtH2UserServiceImpl.kt
  48. 0 1
      spring-boot-starter/mybatis-plus-spring-boot-autoconfigure/build.gradle

+ 10 - 0
build.gradle

@@ -189,6 +189,16 @@ subprojects {
                 name = "Local"
                 url = layout.buildDirectory.dir('repos/bundles')
             }
+            maven {
+                def userName = System.getProperty("un")
+                def passWord = System.getProperty("ps")
+                name = "snapshots"
+                url = "https://central.sonatype.com/repository/maven-snapshots/"
+                credentials {
+                    username userName
+                    password passWord
+                }
+            }
         }
 
         // use example : ./gradlew clean build publish publishToMavenCentralPortal -DauthToken='xxxxxx' -x test

+ 19 - 0
changelog-temp.md

@@ -0,0 +1,19 @@
+- fix: 修复链式模型生成错误
+- fix: 修复`UUID`主键执行批量删除错
+- fix: 修复`Kotlin`使用`select(predicate)`方法错误
+- fix: 修复`AbstractCaffeineJsqlParseCache`异步产生的错误
+- fix: 修复动态SQL解析包含SQL注释(--或#)导致的合并错误
+- fix: 修复`DataChangeRecorderInnerInterceptor`数据比较出现强转异常
+- feat: 支持生成器`Entity`指定`serialVersionUID`添加`@Serial`注解
+- feat: 支持生成器`Entity`注解(字段,类注解)自定义处理
+- feat: 支持生成器`Entity`导包自定义处理
+- feat: 支持崖山数据库
+- feat: 支持`Hive2`分页
+- feat: 升级`Gradle`至8.10
+- opt: 调整`DbType#GAUSS`数据库名为gauss
+- opt: 调整`JsqlParser`解析线程池指定
+- opt: 移除过时的`FieldStrategy.IGNORED`
+- opt: 移除过时的`GlobalConfig.DbConfig#selectStrategy`
+- opt: 移除过时的`MybatisSqlSessionFactoryBean#typeEnumsPackage`
+- doc: 修正`DdlHelper`中注释错误
+-

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-APP_VERSION=3.5.10.1
+APP_VERSION=3.5.11-SNAPSHOT
 APP_GROUP=com.baomidou
 signing.keyId=1FD337F9
 signing.password=243194995

+ 4 - 0
mybatis-plus-annotation/src/main/java/com/baomidou/mybatisplus/annotation/DbType.java

@@ -226,6 +226,10 @@ public enum DbType {
      * yasdb
      */
     YASDB("yasdb", "崖山数据库"),
+    /**
+     * Hadoop的数据仓库
+     */
+    HIVE2("hive2", "Hadoop数据仓库"),
     /**
      * UNKNOWN DB
      */

+ 2 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/DialectFactory.java

@@ -73,6 +73,8 @@ public class DialectFactory {
             } else if (dbType == DbType.TRINO
                 || dbType == DbType.PRESTO) {
                 dialect = new TrinoDialect();
+            } else if (dbType == DbType.HIVE2) {
+                dialect = new Hive2Dialect();
             }
             DIALECT_ENUM_MAP.put(dbType, dialect);
         }

+ 40 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/Hive2Dialect.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011-2025, baomidou (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.baomidou.mybatisplus.extension.plugins.pagination.dialects;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.DialectModel;
+
+/**
+ * Hive2分页方言
+ *
+ * @author dongwei
+ * @since 3.5.11
+ */
+public class Hive2Dialect implements IDialect {
+
+    @Override
+    public DialectModel buildPaginationSql(String originalSql, long offset, long limit) {
+        long firstParam = offset + 1;
+        String sql = "SELECT a.* FROM (SELECT TMP_PAGE.*,ROW_NUMBER() OVER() AS ROW_ID FROM ( "
+            + originalSql +
+            " ) TMP_PAGE) a OFFSET "
+            + firstParam
+            + " ROWS FETCH NEXT "
+            + limit + " ROWS ONLY";
+        return new DialectModel(sql);
+    }
+
+}

+ 2 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/JdbcUtils.java

@@ -153,6 +153,8 @@ public class JdbcUtils {
             return DbType.DUCKDB;
         } else if (url.contains(":yasdb:")) {
             return DbType.YASDB;
+        } else if (url.contains(":hive2:") || url.contains(":inceptor2:")) {
+            return DbType.HIVE2;
         } else {
             logger.warn("The jdbcUrl is " + jdbcUrl + ", Mybatis Plus Cannot Read Database type or The Database's Not Supported!");
             return DbType.OTHER;

+ 31 - 4
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/Entity.java

@@ -114,6 +114,14 @@ public class Entity implements ITemplate {
     @Getter
     private boolean serialVersionUID = true;
 
+    /**
+     * 是否启用 {@link java.io.Serial} (需JAVA 14) 注解
+     *
+     * @since 3.5.11
+     */
+    @Getter
+    private boolean serialAnnotation;
+
     /**
      * 【实体】是否生成字段常量(默认 false)<br>
      * -----------------------------------<br>
@@ -287,14 +295,14 @@ public class Entity implements ITemplate {
     /**
      * 导包处理方法
      *
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     private Function<Set<String>, List<String>> importPackageFunction;
 
     /**
      * 处理类注解方法 (含类与字段)
      *
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     private Function<List<? extends AnnotationAttributes>, List<AnnotationAttributes>> annotationAttributesFunction;
 
@@ -412,6 +420,7 @@ public class Entity implements ITemplate {
         data.put("versionFieldName", this.versionColumnName);
         data.put("activeRecord", this.activeRecord);
         data.put("entitySerialVersionUID", this.serialVersionUID);
+        data.put("entitySerialAnnotation", this.serialAnnotation);
         data.put("entityColumnConstant", this.columnConstant);
         data.put("entityBuilderModel", this.chain);
         data.put("chainModel", this.chain);
@@ -444,6 +453,12 @@ public class Entity implements ITemplate {
             classAnnotationAttributes.stream().sorted(Comparator.comparingInt(s -> s.getDisplayName().length())).collect(Collectors.toList()));
         data.put("importEntityPackages", importPackageFunction != null ? importPackageFunction.apply(importPackages) :
             importPackages.stream().sorted().collect(Collectors.toList()));
+        Set<String> javaPackages = importPackages.stream().filter(pkg -> pkg.startsWith("java")).collect(Collectors.toSet());
+        data.put("importEntityJavaPackages", importPackageFunction != null ? importPackageFunction.apply(javaPackages) :
+            javaPackages.stream().sorted().collect(Collectors.toList()));
+        Set<String> frameworkPackages = importPackages.stream().filter(pkg -> !pkg.startsWith("java")).collect(Collectors.toSet());
+        data.put("importEntityFrameworkPackages", importPackageFunction != null ? importPackageFunction.apply(frameworkPackages) :
+            frameworkPackages.stream().sorted().collect(Collectors.toList()));
         data.put("entityToString", this.toString);
         return data;
     }
@@ -500,6 +515,18 @@ public class Entity implements ITemplate {
             return this;
         }
 
+        /**
+         * 启用生成 {@link java.io.Serial} (需JAVA 14)
+         * <p>当开启了 {@link #serialVersionUID} 时,会增加 {@link java.io.Serial} 注解在此字段上</p>
+         *
+         * @return this
+         * @since 3.5.11
+         */
+        public Builder enableSerialAnnotation() {
+            this.entity.serialAnnotation = true;
+            return this;
+        }
+
         /**
          * 开启生成字段常量
          *
@@ -863,7 +890,7 @@ public class Entity implements ITemplate {
          *
          * @param importPackageFunction 导包处理
          * @return this
-         * @since 3.5.10.2
+         * @since 3.5.11
          */
         public Builder importPackageFunction(Function<Set<String>, List<String>> importPackageFunction) {
             this.entity.importPackageFunction = importPackageFunction;
@@ -875,7 +902,7 @@ public class Entity implements ITemplate {
          *
          * @param annotationAttributesFunction 注解处理
          * @return this
-         * @since 3.5.10.2
+         * @since 3.5.11
          */
         public Builder annotationAttributesFunction(Function<List<? extends AnnotationAttributes>, List<AnnotationAttributes>> annotationAttributesFunction) {
             this.entity.annotationAttributesFunction = annotationAttributesFunction;

+ 44 - 3
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/Mapper.java

@@ -15,8 +15,11 @@
  */
 package com.baomidou.mybatisplus.generator.config.builder;
 
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.generator.ITemplate;
 import com.baomidou.mybatisplus.generator.config.ConstVal;
+import com.baomidou.mybatisplus.generator.config.PackageConfig;
 import com.baomidou.mybatisplus.generator.config.StrategyConfig;
 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
 import com.baomidou.mybatisplus.generator.function.ConverterFileName;
@@ -33,9 +36,12 @@ import org.slf4j.LoggerFactory;
 import java.lang.annotation.Annotation;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 控制器属性配置
@@ -172,6 +178,14 @@ public class Mapper implements ITemplate {
      */
     private IGenerateMapperMethodHandler generateMapperMethodHandler;
 
+    /**
+     * 导包处理方法
+     *
+     * @since 3.5.11
+     */
+    private Function<Set<String>, List<String>> importPackageFunction;
+
+
     @Override
     @NotNull
     public Map<String, Object> renderData(@NotNull TableInfo tableInfo) {
@@ -192,12 +206,25 @@ public class Mapper implements ITemplate {
         data.put("generateMapperXml", this.generateMapperXml);
         data.put("generateMapper", this.generateMapper);
         List<MapperMethod> methodList = null;
-        Set<String> importPackages = null;
+        Set<String> importPackages = new HashSet<>();
         if (generateMapperMethodHandler != null) {
             methodList = generateMapperMethodHandler.getMethodList(tableInfo);
-            importPackages = generateMapperMethodHandler.getImportPackages(tableInfo);
+            importPackages.addAll(generateMapperMethodHandler.getImportPackages(tableInfo));
+        }
+        if(StringUtils.isNotBlank(superClass)){
+            importPackages.add(superClass);
         }
-        data.put("importPackages", importPackages == null ? Collections.emptySet() : importPackages);
+        if (mapperAnnotationClass != null) {
+            importPackages.add(mapperAnnotationClass.getName());
+        }
+        PackageConfig packageConfig = tableInfo.getPackageConfig();
+        String entityPackage = packageConfig.getPackageInfo(null, ConstVal.ENTITY) + StringPool.DOT + tableInfo.getEntityName();
+        importPackages.add(entityPackage);
+        Set<String> javaPackages = importPackages.stream().filter(pkg -> pkg.startsWith("java")).collect(Collectors.toSet());
+        Set<String> frameworkPackages = importPackages.stream().filter(pkg -> !pkg.startsWith("java")).collect(Collectors.toSet());
+        data.put("importPackages", importPackageFunction != null ? importPackageFunction.apply(importPackages) : importPackages.stream().sorted().collect(Collectors.toList()));
+        data.put("importMapperFrameworkPackages", importPackageFunction != null ? importPackageFunction.apply(frameworkPackages) : frameworkPackages.stream().sorted().collect(Collectors.toList()));
+        data.put("importMapperJavaPackages", importPackageFunction != null ? importPackageFunction.apply(javaPackages) : javaPackages.stream().sorted().collect(Collectors.toList()));
         data.put("mapperMethodList", methodList == null ? Collections.emptyList() : methodList);
         return data;
     }
@@ -428,6 +455,20 @@ public class Mapper implements ITemplate {
             return this;
         }
 
+
+        /**
+         * 导包处理方法
+         *
+         * @param importPackageFunction 导包处理
+         * @return this
+         * @since 3.5.11
+         */
+        public Builder importPackageFunction(Function<Set<String>, List<String>> importPackageFunction) {
+            this.mapper.importPackageFunction = importPackageFunction;
+            return this;
+        }
+
+
         @NotNull
         public Mapper get() {
             return this.mapper;

+ 2 - 2
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/po/TableField.java

@@ -143,7 +143,7 @@ public class TableField {
     /**
      * 字段注解处理
      *
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     private Function<List<? extends AnnotationAttributes>, List<AnnotationAttributes>> annotationAttributesFunction;
 
@@ -393,7 +393,7 @@ public class TableField {
 
     /**
      * @param annotationAttributesList 注解属性集合
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public void addAnnotationAttributesList(@NotNull List<AnnotationAttributes> annotationAttributesList, Function<List<? extends AnnotationAttributes>, List<AnnotationAttributes>> annotationAttributesFunction) {
         this.annotationAttributesList.addAll(annotationAttributesList);

+ 11 - 0
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/po/TableInfo.java

@@ -18,6 +18,7 @@ package com.baomidou.mybatisplus.generator.config.po;
 import com.baomidou.mybatisplus.annotation.*;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.generator.config.GlobalConfig;
+import com.baomidou.mybatisplus.generator.config.PackageConfig;
 import com.baomidou.mybatisplus.generator.config.StrategyConfig;
 import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
 import com.baomidou.mybatisplus.generator.config.builder.Entity;
@@ -162,6 +163,12 @@ public class TableInfo {
     @Setter
     private String schemaName;
 
+    /**
+     * @since 3.5.11
+     */
+    @Getter
+    private PackageConfig packageConfig;
+
     /**
      * 构造方法
      *
@@ -173,6 +180,7 @@ public class TableInfo {
         this.strategyConfig = configBuilder.getStrategyConfig();
         this.globalConfig = configBuilder.getGlobalConfig();
         this.entity = configBuilder.getStrategyConfig().entity();
+        this.packageConfig = configBuilder.getPackageConfig();
         this.name = name;
     }
 
@@ -263,6 +271,9 @@ public class TableInfo {
         }
         if (entity.isSerialVersionUID() || entity.isActiveRecord()) {
             this.importPackages.add(Serializable.class.getCanonicalName());
+            if (entity.isSerialAnnotation()) {
+                this.importPackages.add("java.io.Serial");
+            }
         }
         if (this.isConvert()) {
             this.importPackages.add(TableName.class.getCanonicalName());

+ 8 - 1
mybatis-plus-generator/src/main/resources/templates/entity.java.btl

@@ -1,6 +1,10 @@
 package ${package.Entity};
 
-<% for(pkg in importEntityPackages){ %>
+<% for(pkg in importEntityFrameworkPackages){ %>
+import ${pkg};
+<% } %>
+
+<% for(pkg in importEntityJavaPackages){ %>
 import ${pkg};
 <% } %>
 
@@ -26,6 +30,9 @@ public class ${entity} {
 <% } %>
 <% if(entitySerialVersionUID){ %>
 
+    <% if(entitySerialAnnotation) { %>
+    @Serial
+    <% } %>
     private static final long serialVersionUID = 1L;
 <% } %>
 <% var keyPropertyName; %>

+ 8 - 1
mybatis-plus-generator/src/main/resources/templates/entity.java.ej

@@ -1,6 +1,10 @@
 package #(package.Entity);
 
-#for(pkg : importEntityPackages)
+#for(pkg : importEntityFrameworkPackages)
+import #(pkg);
+#end
+
+#for(pkg : importEntityJavaPackages)
 import #(pkg);
 #end
 
@@ -26,6 +30,9 @@ public class #(entity) {
 #end
 #if(entitySerialVersionUID)
 
+    #if(entitySerialAnnotation)
+    @Serial
+    #end
     private static final long serialVersionUID = 1L;
 #end
 ### ----------  BEGIN 字段循环遍历  ----------

+ 8 - 1
mybatis-plus-generator/src/main/resources/templates/entity.java.ftl

@@ -1,6 +1,10 @@
 package ${package.Entity};
 
-<#list importEntityPackages as pkg>
+<#list importEntityFrameworkPackages as pkg>
+import ${pkg};
+</#list>
+
+<#list importEntityJavaPackages as pkg>
 import ${pkg};
 </#list>
 /**
@@ -25,6 +29,9 @@ public class ${entity} {
 </#if>
 <#if entitySerialVersionUID>
 
+    <#if entitySerialAnnotation>
+    @Serial
+    </#if>
     private static final long serialVersionUID = 1L;
 </#if>
 <#-- ----------  BEGIN 字段循环遍历  ---------->

+ 8 - 1
mybatis-plus-generator/src/main/resources/templates/entity.java.vm

@@ -1,6 +1,10 @@
 package ${package.Entity};
 
-#foreach($pkg in ${importEntityPackages})
+#foreach($pkg in ${importEntityFrameworkPackages})
+import ${pkg};
+#end
+
+#foreach($pkg in ${importEntityJavaPackages})
 import ${pkg};
 #end
 
@@ -26,6 +30,9 @@ public class ${entity} {
 #end
 #if(${entitySerialVersionUID})
 
+    #if(${entitySerialAnnotation})
+    @Serial
+    #end
     private static final long serialVersionUID = 1L;
 #end
 ## ----------  BEGIN 字段循环遍历  ----------

+ 5 - 1
mybatis-plus-generator/src/main/resources/templates/entity.kt.btl

@@ -1,6 +1,10 @@
 package ${package.Entity}
 
-<% for(pkg in importEntityPackages){ %>
+<% for(pkg in importEntityFrameworkPackages){ %>
+import ${pkg};
+<% } %>
+
+<% for(pkg in importEntityJavaPackages){ %>
 import ${pkg};
 <% } %>
 

+ 5 - 1
mybatis-plus-generator/src/main/resources/templates/entity.kt.ej

@@ -1,6 +1,10 @@
 package #(package.Entity);
 
-#for(pkg : importEntityPackages)
+#for(pkg : importEntityFrameworkPackages)
+import #(pkg);
+#end
+
+#for(pkg : importEntityJavaPackages)
 import #(pkg);
 #end
 

+ 5 - 1
mybatis-plus-generator/src/main/resources/templates/entity.kt.ftl

@@ -1,6 +1,10 @@
 package ${package.Entity}
 
-<#list importEntityPackages as pkg>
+<#list importEntityFrameworkPackages as pkg>
+import ${pkg}
+</#list>
+
+<#list importEntityJavaPackages as pkg>
 import ${pkg}
 </#list>
 

+ 5 - 1
mybatis-plus-generator/src/main/resources/templates/entity.kt.vm

@@ -1,6 +1,10 @@
 package ${package.Entity};
 
-#foreach($pkg in ${importEntityPackages})
+#foreach($pkg in ${importEntityFrameworkPackages})
+import ${pkg};
+#end
+
+#foreach($pkg in ${importEntityJavaPackages})
 import ${pkg};
 #end
 

+ 6 - 5
mybatis-plus-generator/src/main/resources/templates/mapper.java.btl

@@ -1,12 +1,13 @@
 package ${package.Mapper};
 
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-<% for(pkg in importPackages){ %>
+<% for(pkg in importMapperFrameworkPackages){ %>
+import ${pkg};
+<% } %>
+<% if(isNotEmpty(importMapperJavaPackages)){ %>
+
+<% for(pkg in importMapperJavaPackages){ %>
 import ${pkg};
 <% } %>
-<% if(mapperAnnotationClass!=null){ %>
-import ${mapperAnnotationClass.name};
 <% } %>
 
 /**

+ 5 - 5
mybatis-plus-generator/src/main/resources/templates/mapper.java.ej

@@ -1,13 +1,13 @@
 package #(package.Mapper);
 
-import #(package.Entity).#(entity);
-import #(superMapperClassPackage);
+#for(pkg : importMapperFrameworkPackages)
+import #(pkg);
+#end
+#if(!importMapperJavaPackages.isEmpty())
 
-#for(pkg : importPackages)
+#for(pkg : importMapperJavaPackages)
 import #(pkg);
 #end
-#if(mapperAnnotationClass)
-import #(mapperAnnotationClass.name);
 #end
 
 /**

+ 6 - 6
mybatis-plus-generator/src/main/resources/templates/mapper.java.ftl

@@ -1,13 +1,13 @@
 package ${package.Mapper};
 
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-
-<#list importPackages as pkg>
+<#list importMapperFrameworkPackages as pkg>
 import ${pkg};
 </#list>
-<#if mapperAnnotationClass??>
-import ${mapperAnnotationClass.name};
+<#if importMapperJavaPackages?size !=0>
+
+  <#list importMapperJavaPackages as pkg>
+import ${pkg};
+   </#list>
 </#if>
 
 /**

+ 5 - 6
mybatis-plus-generator/src/main/resources/templates/mapper.java.vm

@@ -1,14 +1,13 @@
 package ${package.Mapper};
 
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-
-#foreach($pkg in ${importPackages})
+#foreach($pkg in ${importMapperFrameworkPackages})
 import ${pkg};
 #end
+#if($importMapperJavaPackages.size()>0)
 
-#if(${mapperAnnotationClass})
-import ${mapperAnnotationClass.name};
+#foreach($pkg in ${importMapperJavaPackages})
+import ${pkg};
+#end
 #end
 
 /**

+ 4 - 4
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java

@@ -47,7 +47,7 @@ public class JsqlParserGlobal {
      *
      * @see java.util.concurrent.ThreadPoolExecutor
      * @since 3.5.6
-     * @deprecated 3.5.10.2 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
+     * @deprecated 3.5.11 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
      */
     @Deprecated
     public static ExecutorService executorService;
@@ -65,7 +65,7 @@ public class JsqlParserGlobal {
      * 设置解析线程池
      *
      * @param executorService 线程池 (自行控制线程池关闭)
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService) {
         JsqlParserGlobal.executorService = executorService;
@@ -76,7 +76,7 @@ public class JsqlParserGlobal {
      *
      * @param executorService 线程池 (自行控制线程池关闭)
      * @param addShutdownHook 是否注册退出关闭钩子
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService, boolean addShutdownHook) {
         JsqlParserGlobal.executorService = executorService;
@@ -89,7 +89,7 @@ public class JsqlParserGlobal {
      * 获取解析线程池(如果未自定义则返回默认的解析线程池)
      *
      * @return 解析线程池
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static ExecutorService getExecutorService() {
         return JsqlParserGlobal.executorService == null ? JsqlParserThreadPool.getDefaultThreadPoolExecutor() : JsqlParserGlobal.executorService;

+ 14 - 16
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java

@@ -863,26 +863,24 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         private Object originalValue;
         private Object updateValue;
 
-        @SuppressWarnings("rawtypes")
+        @SuppressWarnings({"rawtypes", "unchecked"})
         public boolean isDataChanged(Object updateValue) {
-            if (!Objects.equals(originalValue, updateValue)) {
-                if (originalValue instanceof Clob) {
-                    String originalStr = convertClob((Clob) originalValue);
-                    setOriginalValue(originalStr);
-                    return !originalStr.equals(updateValue);
-                }
-                if (originalValue instanceof Comparable) {
-                    Comparable original = (Comparable) originalValue;
+            if (Objects.equals(originalValue, updateValue)) {
+                return false;
+            }
+            if (originalValue instanceof Clob) {
+                String originalStr = convertClob((Clob) originalValue);
+                setOriginalValue(originalStr);
+                return !originalStr.equals(updateValue);
+            }
+            if (originalValue instanceof Comparable) {
+                Comparable original = (Comparable) originalValue;
+                if (original.getClass().isInstance(updateValue)) {
                     Comparable update = (Comparable) updateValue;
-                    try {
-                        return update == null || original.compareTo(update) != 0;
-                    } catch (Exception e) {
-                        return true;
-                    }
+                    return original.compareTo(update) != 0;
                 }
-                return true;
             }
-            return false;
+            return true;
         }
 
         public static String convertClob(Clob clobObj) {

+ 30 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java

@@ -9,6 +9,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.lang.reflect.Field;
+import java.math.BigDecimal;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -60,4 +61,33 @@ class DataChangeRecorderInnerInterceptorTest {
         Assertions.assertFalse(operationResult.isRecordStatus());
         Assertions.assertNull(operationResult.getChangedData());
     }
+
+    @Test
+    void isDataChangedTest() {
+        var columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        Assertions.assertFalse(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new Object());
+        Assertions.assertTrue(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new BigDecimal("0"));
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertTrue(columnChangeResult.isDataChanged("0"));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(0));
+
+        Assertions.assertFalse(columnChangeResult.isDataChanged(new BigDecimal("0") {}));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(new BigDecimal("1") {}));
+    }
+
 }

+ 4 - 4
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java

@@ -47,7 +47,7 @@ public class JsqlParserGlobal {
      *
      * @see java.util.concurrent.ThreadPoolExecutor
      * @since 3.5.6
-     * @deprecated 3.5.10.2 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
+     * @deprecated 3.5.11 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
      */
     @Deprecated
     public static ExecutorService executorService;
@@ -65,7 +65,7 @@ public class JsqlParserGlobal {
      * 设置解析线程池
      *
      * @param executorService 线程池 (自行控制线程池关闭)
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService) {
         JsqlParserGlobal.executorService = executorService;
@@ -76,7 +76,7 @@ public class JsqlParserGlobal {
      *
      * @param executorService 线程池 (自行控制线程池关闭)
      * @param addShutdownHook 是否注册退出关闭钩子
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService, boolean addShutdownHook) {
         JsqlParserGlobal.executorService = executorService;
@@ -89,7 +89,7 @@ public class JsqlParserGlobal {
      * 获取解析线程池(如果未自定义则返回默认的解析线程池)
      *
      * @return 解析线程池
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static ExecutorService getExecutorService() {
         return JsqlParserGlobal.executorService == null ? JsqlParserThreadPool.getDefaultThreadPoolExecutor() : JsqlParserGlobal.executorService;

+ 14 - 16
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java

@@ -863,26 +863,24 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         private Object originalValue;
         private Object updateValue;
 
-        @SuppressWarnings("rawtypes")
+        @SuppressWarnings({"rawtypes", "unchecked"})
         public boolean isDataChanged(Object updateValue) {
-            if (!Objects.equals(originalValue, updateValue)) {
-                if (originalValue instanceof Clob) {
-                    String originalStr = convertClob((Clob) originalValue);
-                    setOriginalValue(originalStr);
-                    return !originalStr.equals(updateValue);
-                }
-                if (originalValue instanceof Comparable) {
-                    Comparable original = (Comparable) originalValue;
+            if (Objects.equals(originalValue, updateValue)) {
+                return false;
+            }
+            if (originalValue instanceof Clob) {
+                String originalStr = convertClob((Clob) originalValue);
+                setOriginalValue(originalStr);
+                return !originalStr.equals(updateValue);
+            }
+            if (originalValue instanceof Comparable) {
+                Comparable original = (Comparable) originalValue;
+                if (original.getClass().isInstance(updateValue)) {
                     Comparable update = (Comparable) updateValue;
-                    try {
-                        return update == null || original.compareTo(update) != 0;
-                    } catch (Exception e) {
-                        return true;
-                    }
+                    return original.compareTo(update) != 0;
                 }
-                return true;
             }
-            return false;
+            return true;
         }
 
         public static String convertClob(Clob clobObj) {

+ 30 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java

@@ -9,6 +9,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.lang.reflect.Field;
+import java.math.BigDecimal;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -60,4 +61,33 @@ class DataChangeRecorderInnerInterceptorTest {
         Assertions.assertFalse(operationResult.isRecordStatus());
         Assertions.assertNull(operationResult.getChangedData());
     }
+
+    @Test
+    void isDataChangedTest() {
+        var columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        Assertions.assertFalse(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new Object());
+        Assertions.assertTrue(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new BigDecimal("0"));
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertTrue(columnChangeResult.isDataChanged("0"));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(0));
+
+        Assertions.assertFalse(columnChangeResult.isDataChanged(new BigDecimal("0") {}));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(new BigDecimal("1") {}));
+    }
+
 }

+ 1 - 1
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-common/src/main/java/com/baomidou/mybatisplus/jsqlparser/JsqlParserThreadPool.java

@@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit;
  * <p>当没指定解析线程池时,默认使用一个固定长度的线程作为解析线程池.</p>
  *
  * @author nieqiurong
- * @since 3.5.10.2
+ * @since 3.5.11
  */
 public class JsqlParserThreadPool {
 

+ 4 - 4
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/parser/JsqlParserGlobal.java

@@ -47,7 +47,7 @@ public class JsqlParserGlobal {
      *
      * @see java.util.concurrent.ThreadPoolExecutor
      * @since 3.5.6
-     * @deprecated 3.5.10.2 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
+     * @deprecated 3.5.11 后面不再公开此属性,请使用{@link #setExecutorService(ExecutorService)}} 或 {@link #setExecutorService(ExecutorService, boolean)}
      */
     @Deprecated
     public static ExecutorService executorService;
@@ -65,7 +65,7 @@ public class JsqlParserGlobal {
      * 设置解析线程池
      *
      * @param executorService 线程池 (自行控制线程池关闭)
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService) {
         JsqlParserGlobal.executorService = executorService;
@@ -76,7 +76,7 @@ public class JsqlParserGlobal {
      *
      * @param executorService 线程池 (自行控制线程池关闭)
      * @param addShutdownHook 是否注册退出关闭钩子
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static void setExecutorService(ExecutorService executorService, boolean addShutdownHook) {
         JsqlParserGlobal.executorService = executorService;
@@ -89,7 +89,7 @@ public class JsqlParserGlobal {
      * 获取解析线程池(如果未自定义则返回默认的解析线程池)
      *
      * @return 解析线程池
-     * @since 3.5.10.2
+     * @since 3.5.11
      */
     public static ExecutorService getExecutorService() {
         return JsqlParserGlobal.executorService == null ? JsqlParserThreadPool.getDefaultThreadPoolExecutor() : JsqlParserGlobal.executorService;

+ 14 - 16
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java

@@ -863,26 +863,24 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         private Object originalValue;
         private Object updateValue;
 
-        @SuppressWarnings("rawtypes")
+        @SuppressWarnings({"rawtypes", "unchecked"})
         public boolean isDataChanged(Object updateValue) {
-            if (!Objects.equals(originalValue, updateValue)) {
-                if (originalValue instanceof Clob) {
-                    String originalStr = convertClob((Clob) originalValue);
-                    setOriginalValue(originalStr);
-                    return !originalStr.equals(updateValue);
-                }
-                if (originalValue instanceof Comparable) {
-                    Comparable original = (Comparable) originalValue;
+            if (Objects.equals(originalValue, updateValue)) {
+                return false;
+            }
+            if (originalValue instanceof Clob) {
+                String originalStr = convertClob((Clob) originalValue);
+                setOriginalValue(originalStr);
+                return !originalStr.equals(updateValue);
+            }
+            if (originalValue instanceof Comparable) {
+                Comparable original = (Comparable) originalValue;
+                if (original.getClass().isInstance(updateValue)) {
                     Comparable update = (Comparable) updateValue;
-                    try {
-                        return update == null || original.compareTo(update) != 0;
-                    } catch (Exception e) {
-                        return true;
-                    }
+                    return original.compareTo(update) != 0;
                 }
-                return true;
             }
-            return false;
+            return true;
         }
 
         public static String convertClob(Clob clobObj) {

+ 30 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/test/java/com/baomidou/mybatisplus/test/extension/plugins/inner/DataChangeRecorderInnerInterceptorTest.java

@@ -9,6 +9,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.lang.reflect.Field;
+import java.math.BigDecimal;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -60,4 +61,33 @@ class DataChangeRecorderInnerInterceptorTest {
         Assertions.assertFalse(operationResult.isRecordStatus());
         Assertions.assertNull(operationResult.getChangedData());
     }
+
+    @Test
+    void isDataChangedTest() {
+        var columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        Assertions.assertFalse(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new Object());
+        Assertions.assertTrue(columnChangeResult.isDataChanged(null));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(new BigDecimal("0"));
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertFalse(columnChangeResult.isDataChanged(BigDecimal.ZERO));
+
+        columnChangeResult = new DataChangeRecorderInnerInterceptor.DataColumnChangeResult();
+        columnChangeResult.setOriginalValue(BigDecimal.ZERO);
+        Assertions.assertTrue(columnChangeResult.isDataChanged("0"));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(0));
+
+        Assertions.assertFalse(columnChangeResult.isDataChanged(new BigDecimal("0") {}));
+        Assertions.assertTrue(columnChangeResult.isDataChanged(new BigDecimal("1") {}));
+    }
+
 }

+ 0 - 1
mybatis-plus-spring/src/test/kotlin/com/baomidou/mybatisplus/test/kotlin/BaseDbTest.kt

@@ -36,7 +36,6 @@ abstract class BaseDbTest<T> : TypeReference<T>() {
     protected var jdbcTemplate: JdbcTemplate
 
     init {
-        SqlRunner.DEFAULT.close()
         val ds = dataSource()
         val tableSql = tableSql()
         val tableDataSql = tableDataSql()

+ 18 - 0
mybatis-plus/build.gradle

@@ -1,3 +1,19 @@
+apply plugin: 'kotlin'
+
+compileKotlin{
+    kotlinOptions.jvmTarget = "1.8"
+}
+
+compileTestKotlin {
+    kotlinOptions {
+        freeCompilerArgs = ['-Xjvm-default=all']
+    }
+}
+
+configurations {
+    testImplementation.exclude module: 'mybatis-plus-jsqlparser-4.9'
+}
+
 dependencies {
     api project(":mybatis-plus-core")
     api project(":mybatis-plus-annotation")
@@ -6,6 +22,8 @@ dependencies {
     api "${lib.mybatis}"
 
     implementation "${lib."mybatis-spring"}"
+    implementation "${lib."kotlin-stdlib-jdk8"}"
+    implementation project(":mybatis-plus-jsqlparser-support:mybatis-plus-jsqlparser-4.9")
 
     testImplementation "${lib.'spring-web'}"
 

+ 10 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/pom/GeneratePomTest.java

@@ -44,6 +44,16 @@ class GeneratePomTest {
             Dependency extension = dependenciesMap.get("mybatis-plus-spring");
             Assertions.assertEquals("compile", extension.getScope());
             Assertions.assertFalse(extension.isOptional());
+            Dependency mybatisSpring = dependenciesMap.get("mybatis-spring");
+            Assertions.assertEquals("compile", mybatisSpring.getScope());
+            Assertions.assertTrue(mybatisSpring.isOptional());
+            Dependency kotlinStdlib = dependenciesMap.get("kotlin-stdlib-jdk8");
+            Assertions.assertEquals("compile", kotlinStdlib.getScope());
+            Assertions.assertTrue(kotlinStdlib.isOptional());
+            Dependency jsqlparserLib = dependenciesMap.get("mybatis-plus-jsqlparser-4.9");
+            Assertions.assertEquals("compile", jsqlparserLib.getScope());
+            Assertions.assertTrue(jsqlparserLib.isOptional());
+
         }
     }
 

+ 50 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/KtTestConfig.kt

@@ -0,0 +1,50 @@
+package com.baomidou.mybatisplus.test.h2
+
+import com.baomidou.mybatisplus.core.MybatisConfiguration
+import com.baomidou.mybatisplus.core.config.GlobalConfig
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
+import com.baomidou.mybatisplus.test.h2.config.DBConfig
+import org.apache.ibatis.session.ExecutorType
+import org.apache.ibatis.session.SqlSessionFactory
+import org.apache.ibatis.type.EnumOrdinalTypeHandler
+import org.apache.ibatis.type.JdbcType
+import org.mybatis.spring.annotation.MapperScan
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+import org.springframework.context.annotation.Import
+import javax.sql.DataSource
+
+/**
+ * @author nieqiurong
+ */
+@Configuration
+@Import(DBConfig::class)
+@ComponentScan("com.baomidou.mybatisplus.test.h2.kotlin")
+@MapperScan("com.baomidou.mybatisplus.test.h2.kotlin.mapper")
+open class KtTestConfig {
+
+    @Bean("sqlSessionFactory")
+    open fun sqlSessionFactory(dataSource: DataSource): SqlSessionFactory? {
+        val sqlSessionFactory = MybatisSqlSessionFactoryBean()
+        sqlSessionFactory.setDataSource(dataSource)
+        val configuration = MybatisConfiguration()
+        configuration.jdbcTypeForNull = JdbcType.NULL
+        configuration.isMapUnderscoreToCamelCase = true
+        configuration.defaultExecutorType = ExecutorType.REUSE
+        configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler::class.java) //默认枚举处理
+        sqlSessionFactory.configuration = configuration
+        val mybatisPlusInterceptor = MybatisPlusInterceptor()
+        mybatisPlusInterceptor.addInnerInterceptor(PaginationInnerInterceptor())
+        sqlSessionFactory.setPlugins(mybatisPlusInterceptor)
+        val globalConfig = GlobalConfig()
+        globalConfig.setMetaObjectHandler(MyMetaObjectHandler())
+        globalConfig.setSqlInjector(DefaultSqlInjector())
+        sqlSessionFactory.setGlobalConfig(globalConfig)
+        return sqlSessionFactory.getObject()
+    }
+
+}

+ 110 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/MetaObjectHandlerTest.kt

@@ -0,0 +1,110 @@
+package com.baomidou.mybatisplus.test.h2
+
+import com.baomidou.mybatisplus.annotation.FieldFill
+import com.baomidou.mybatisplus.annotation.TableField
+import com.baomidou.mybatisplus.core.MybatisConfiguration
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper
+import org.apache.ibatis.builder.MapperBuilderAssistant
+import org.apache.ibatis.reflection.MetaObject
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Test
+import java.math.BigDecimal
+import java.math.BigInteger
+import java.sql.Time
+import java.sql.Timestamp
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.util.*
+
+/**
+ *
+ * @author nieqiurong
+ */
+class MetaObjectHandlerTest {
+
+    @Test
+    fun println() {
+        val clzs = arrayOf(
+            String::class, Long::class, Int::class, Double::class, Float::class,
+            Short::class, Byte::class, Boolean::class, Date::class,
+            Time::class,
+            Timestamp::class, java.sql.Date::class, LocalDate::class, LocalDateTime::class, BigInteger::class,
+            BigDecimal::class, BigInteger::class
+        )
+        for (clz in clzs) {
+            println("kotlinType:" + clz.simpleName + "----->" + "JavaObjectType:" + clz.javaObjectType.name + "---->" + "JavaType:" + clz.java.name)
+        }
+    }
+
+    @Test
+    fun test() {
+        val configuration = MybatisConfiguration()
+        val mapperBuilderAssistant = MapperBuilderAssistant(configuration, "")
+        val tableInfo = TableInfoHelper.initTableInfo(mapperBuilderAssistant, Demo::class.java)
+        for (tableFieldInfo in tableInfo.fieldList) {
+            println(tableFieldInfo.property + "----->" + tableFieldInfo.propertyType.name)
+        }
+        val demo = Demo()
+        val metaObjectHandler = object : MetaObjectHandler {
+            override fun insertFill(metaObject: MetaObject) {
+                this.strictInsertFill(metaObject, "testString", String::class.java, "123")
+                this.strictInsertFill(metaObject, "testLong", Long::class.javaObjectType, 123456L)
+                this.strictInsertFill(metaObject, "testInt", Int::class.javaObjectType, 123)
+                this.strictInsertFill(
+                    metaObject,
+                    "testLocalDateTime",
+                    LocalDateTime::class.javaObjectType,
+                    LocalDateTime.now()
+                )
+                this.strictInsertFill(metaObject, "testBoolean", Boolean::class.javaObjectType, false)
+                this.strictInsertFill(metaObject, "testDate", Date::class.javaObjectType, Date())
+                this.strictInsertFill(metaObject, "testLocalDate", LocalDate::class.javaObjectType, LocalDate.now())
+            }
+
+            override fun updateFill(metaObject: MetaObject) {
+
+            }
+        }
+        val metaObject: MetaObject = configuration.newMetaObject(demo)
+        metaObjectHandler.insertFill(metaObject)
+        Assertions.assertNotNull(demo.testString)
+        Assertions.assertNotNull(demo.testInt)
+        Assertions.assertNotNull(demo.testLong)
+        Assertions.assertNotNull(demo.testDate)
+        Assertions.assertNotNull(demo.testLocalDateTime)
+        Assertions.assertNotNull(demo.testBoolean)
+        Assertions.assertNotNull(demo.testLocalDate)
+        println(demo)
+    }
+
+}
+
+class Demo {
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testString: String? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testInt: Int? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testLong: Long? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testDate: Date? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testLocalDateTime: LocalDateTime? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testBoolean: Boolean? = null
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    var testLocalDate: LocalDate? = null
+
+    override fun toString(): String {
+        return "Demo(testBoolean=$testBoolean, testString=$testString, testInt=$testInt, testLong=$testLong, testDate=$testDate, testLocalDateTime=$testLocalDateTime, testLocalDate=$testLocalDate)"
+    }
+
+}

+ 20 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/MyMetaObjectHandler.kt

@@ -0,0 +1,20 @@
+package com.baomidou.mybatisplus.test.h2
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
+import org.apache.ibatis.reflection.MetaObject
+import java.time.LocalDateTime
+
+/**
+ * @author nieqiurong
+ */
+class MyMetaObjectHandler : MetaObjectHandler {
+
+    override fun insertFill(metaObject: MetaObject) {
+        this.strictInsertFill(metaObject, "createdDt", LocalDateTime::class.javaObjectType, LocalDateTime.now())
+    }
+
+    override fun updateFill(metaObject: MetaObject) {
+        this.strictUpdateFill(metaObject, "lastUpdatedDt", LocalDateTime::class.javaObjectType, LocalDateTime.now())
+    }
+
+}

+ 37 - 4
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/KtH2UserTest.kt → mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/KtH2UserTest.kt

@@ -1,8 +1,9 @@
-package com.baomidou.mybatisplus.test.h2
+package com.baomidou.mybatisplus.test.h2.kotlin
 
-import com.baomidou.mybatisplus.test.h2.entity.KtH2User
+import com.baomidou.mybatisplus.test.h2.KtTestConfig
+import com.baomidou.mybatisplus.test.h2.kotlin.entity.KtH2User
 import com.baomidou.mybatisplus.test.h2.enums.AgeEnum
-import com.baomidou.mybatisplus.test.h2.service.KtH2UserService
+import com.baomidou.mybatisplus.test.h2.kotlin.service.KtH2UserService
 import org.junit.jupiter.api.Assertions
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.extension.ExtendWith
@@ -17,12 +18,44 @@ import org.springframework.test.context.junit.jupiter.SpringExtension
  * @since 2020/10/18
  */
 @ExtendWith(SpringExtension::class)
-@ContextConfiguration(locations = ["classpath:h2/spring-test-h2.xml"])
+@ContextConfiguration(classes = [KtTestConfig::class])
 class KtH2UserTest {
+
     @Autowired
     private lateinit var userService: KtH2UserService
 
 
+    @Test
+    fun testSave() {
+        val user = KtH2User()
+        user.age = AgeEnum.ONE
+        user.name = "Demo"
+        userService.save(user)
+        Assertions.assertNotNull(user.createdDt)
+    }
+
+    @Test
+    fun testUpdate() {
+        val user = KtH2User()
+        user.age = AgeEnum.ONE
+        user.name = "Demo"
+        userService.save(user)
+        user.name = "Update"
+        userService.updateById(user)
+        Assertions.assertNotNull(user.lastUpdatedDt)
+    }
+
+    @Test
+    fun testDelete() {
+        val user = KtH2User()
+        user.age = AgeEnum.ONE
+        user.name = "Delete"
+        userService.save(user)
+        userService.removeById(user)
+        Assertions.assertNull(userService.getById(user.testId))
+    }
+
+
     @Test
     fun testServiceImplInnerKtChain() {
         var tomcat = userService.ktQuery().eq(KtH2User::name, "Tomcat").one()

+ 12 - 5
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/entity/KtH2User.kt → mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/entity/KtH2User.kt

@@ -1,16 +1,17 @@
-package com.baomidou.mybatisplus.test.h2.entity
+package com.baomidou.mybatisplus.test.h2.kotlin.entity
 
-import com.baomidou.mybatisplus.annotation.TableField
-import com.baomidou.mybatisplus.annotation.TableLogic
-import com.baomidou.mybatisplus.annotation.TableName
-import com.baomidou.mybatisplus.annotation.Version
+import com.baomidou.mybatisplus.annotation.*
 import com.baomidou.mybatisplus.test.h2.enums.AgeEnum
 import java.math.BigDecimal
+import java.time.LocalDateTime
 import java.util.*
 
 @TableName("h2user")
 class KtH2User {
 
+    @TableId
+    var testId: Long? = null
+
     var name: String? = null
 
     var age: AgeEnum? = null
@@ -31,4 +32,10 @@ class KtH2User {
     @TableLogic
     val deleted: Int? = null
 
+    @TableField(fill = FieldFill.INSERT)
+    var createdDt: LocalDateTime? = null
+
+    @TableField(fill = FieldFill.UPDATE)
+    var lastUpdatedDt: LocalDateTime? = null
+
 }

+ 9 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/mapper/KtUserMapper.kt

@@ -0,0 +1,9 @@
+package com.baomidou.mybatisplus.test.h2.kotlin.mapper
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper
+import com.baomidou.mybatisplus.test.h2.kotlin.entity.KtH2User
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface KtUserMapper : BaseMapper<KtH2User> {
+}

+ 7 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/service/KtH2UserService.kt

@@ -0,0 +1,7 @@
+package com.baomidou.mybatisplus.test.h2.kotlin.service
+
+import com.baomidou.mybatisplus.extension.service.IService
+import com.baomidou.mybatisplus.test.h2.kotlin.entity.KtH2User
+
+interface KtH2UserService : IService<KtH2User> {
+}

+ 12 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/kotlin/service/impl/KtH2UserServiceImpl.kt

@@ -0,0 +1,12 @@
+package com.baomidou.mybatisplus.test.h2.kotlin.service.impl
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
+import com.baomidou.mybatisplus.test.h2.kotlin.entity.KtH2User
+import com.baomidou.mybatisplus.test.h2.kotlin.mapper.KtUserMapper
+import com.baomidou.mybatisplus.test.h2.kotlin.service.KtH2UserService
+import org.springframework.stereotype.Service
+
+@Service
+class KtH2UserServiceImpl : ServiceImpl<KtUserMapper, KtH2User>(), KtH2UserService {
+
+}

+ 0 - 7
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/mapper/KtUserMapper.kt

@@ -1,7 +0,0 @@
-package com.baomidou.mybatisplus.test.h2.mapper
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper
-import com.baomidou.mybatisplus.test.h2.entity.KtH2User
-
-interface KtUserMapper : BaseMapper<KtH2User> {
-}

+ 0 - 7
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/KtH2UserService.kt

@@ -1,7 +0,0 @@
-package com.baomidou.mybatisplus.test.h2.service
-
-import com.baomidou.mybatisplus.extension.service.IService
-import com.baomidou.mybatisplus.test.h2.entity.KtH2User
-
-interface KtH2UserService : IService<KtH2User> {
-}

+ 0 - 12
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/impl/KtH2UserServiceImpl.kt

@@ -1,12 +0,0 @@
-package com.baomidou.mybatisplus.test.h2.service.impl
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
-import com.baomidou.mybatisplus.test.h2.entity.KtH2User
-import com.baomidou.mybatisplus.test.h2.mapper.KtUserMapper
-import com.baomidou.mybatisplus.test.h2.service.KtH2UserService
-import org.springframework.stereotype.Service
-
-@Service
-class KtH2UserServiceImpl : ServiceImpl<KtUserMapper, KtH2User>(), KtH2UserService {
-
-}

+ 0 - 1
spring-boot-starter/mybatis-plus-spring-boot-autoconfigure/build.gradle

@@ -1,7 +1,6 @@
 dependencies {
     implementation project(":mybatis-plus")
     implementation "${lib."mybatis-spring"}"
-    implementation "${lib."mybatis-spring"}"
     implementation "org.springframework.boot:spring-boot-autoconfigure:${springBootVersion}"
     implementation "org.springframework.boot:spring-boot-starter-jdbc:${springBootVersion}"
     annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}"