10 Commits 82759f3660 ... bb2e18c08d

Tác giả SHA1 Thông báo Ngày
  nieqiurong bb2e18c08d 发布3.5.10 4 tháng trước cách đây
  nieqiurong 841b24e9ce 改进安全加密处理器密钥获取. 4 tháng trước cách đây
  nieqiurong f18028c5fb 计划移除DataChangeRecorderInnerInterceptor与IllegalSQLInnerInterceptor插件. 4 tháng trước cách đây
  nieqiurong cef0bf60f4 新增版本更新日志. 4 tháng trước cách đây
  nieqiurong d36160b0a6 调整Mapper方法生成(默认单索引生成). 4 tháng trước cách đây
  nieqiurong e8c84edfb5 代码调整. 4 tháng trước cách đây
  nieqiurong 7ffc2e5ace 修复数据变动插件更新无主键报错. 4 tháng trước cách đây
  nieqiurong 19466562f0 支持字段文档注释控制是否生成(默认生成文档注释). 4 tháng trước cách đây
  nieqiurong 52d35a55f2 支持toString方法控制(默认lombok开启ToString生成). 4 tháng trước cách đây
  nieqiurong c8aa180291 支持表注解自定义处理. 4 tháng trước cách đây
28 tập tin đã thay đổi với 360 bổ sung107 xóa
  1. 26 0
      CHANGELOG.md
  2. 0 7
      changelog-temp.md
  3. 1 1
      gradle.properties
  4. 1 1
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java
  5. 0 6
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/IgnoreStrategy.java
  6. 87 0
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/DefaultTableAnnotationHandler.java
  7. 40 0
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/ITableAnnotationHandler.java
  8. 88 49
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/Entity.java
  9. 40 7
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/index/DefaultGenerateMapperLambdaMethodHandler.java
  10. 36 6
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/index/DefaultGenerateMapperMethodHandler.java
  11. 2 2
      mybatis-plus-generator/src/main/resources/templates/entity.java.btl
  12. 2 2
      mybatis-plus-generator/src/main/resources/templates/entity.java.ej
  13. 2 2
      mybatis-plus-generator/src/main/resources/templates/entity.java.ftl
  14. 2 2
      mybatis-plus-generator/src/main/resources/templates/entity.java.vm
  15. 2 2
      mybatis-plus-generator/src/main/resources/templates/entity.kt.btl
  16. 3 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.ej
  17. 3 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.ftl
  18. 3 1
      mybatis-plus-generator/src/main/resources/templates/entity.kt.vm
  19. 4 1
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  20. 2 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java
  21. 1 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/parser/cache/FstFactory.java
  22. 4 1
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  23. 2 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java
  24. 4 1
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java
  25. 2 0
      mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java
  26. 1 1
      settings.gradle
  27. 1 12
      spring-boot-starter/mybatis-plus-spring-boot-autoconfigure/src/main/java/com/baomidou/mybatisplus/autoconfigure/SafetyEncryptProcessor.java
  28. 1 1
      spring-boot-starter/mybatis-plus-spring-boot3-starter/build.gradle

+ 26 - 0
CHANGELOG.md

@@ -1,4 +1,30 @@
 # CHANGELOG
+## [v3.5.10] 2025.01.12
+- fix: 修复字段有`TableField`注解但未指定`value`值下全局`columnFormat`未生效问题
+- fix: 修复enjoy模板生成kotlin代码报错
+- fix: 修复enjoy模板生成字符串代码报错
+- fix: 修复springdoc生成注解未转义双引号
+- fix: 修复数据变动插件更新无主键报错
+- fix: 修复多表解析processJoins解析表出现越界
+- feat: TableName注解新增`properties`属性
+- feat: 支持@InterceptorIgnore注解在default方法上
+- feat: 适配jsqlparser5.1版本(5.0兼容版本请使用`mybatis-plus-jsqlparser-5.0`)
+- feat: 提供`InterceptorIgnoreHelper.execute`模板执行方法处理插件跳过策略(防止手动使用handle方法出现未清理线程资源造成的错误)
+- feat: 代码生成器全局package配置属性支持自定义模板信息获取
+- feat: 代码生成器新增表索引信息获取
+- feat: 代码生成器提供`Mapper.Builder.generateMapperMethodHandler`处理器基于索引生成索引方法
+- feat: 代码生成器Entity支持自定义Class注解和字段注解生成
+- feat: 代码生成器Entity支持lombok模式指定生成类注解
+- feat: 代码生成器Entity支持ToString`(Entity.Builder.toString(boolean))`方法控制生成 (默认生成,lombok模式下将会生成@ToString,低版本下lombok不生成,属于不兼容改动)
+- feat: 代码生成器Entity支持字段文档注释(`Entity.Builder.fieldUseJavaDoc(boolean)`)控制生成 (默认生成,低版本下,使用swagger或springdoc不会生成字段文档注释,属于不兼容改动)
+- feat: 重写动态语句生成(生成执行SQL将不再包含\n换行符)
+- feat: 安全加密处理器密钥获取支持环境变量与系统属性传入
+- feat: 升级mybatis至3.5.19
+- feat: 升级springboot至3.4.1
+- feat: 升级kotlin至2.1.0
+- 实用性低,检查语法不完善,计划移除IllegalSQLInnerInterceptor插件
+- 功能缺陷较多,计划移除DataChangeRecorderInnerInterceptor插件
+
 ## [v3.5.9] 2024.10.23
 - opt: 优化代码生成器支持可视化配置生成能力
 - opt: 解耦扩展包不再强制依赖 spring 开发框架

+ 0 - 7
changelog-temp.md

@@ -1,7 +0,0 @@
-- opt: 优化代码生成器支持可视化配置生成能力
-- opt: 解耦扩展包不再强制依赖 spring 开发框架
-- opt: 拆分jsqlparser支持模块,提供mybatis-plus-jsqlparser(支持最新jsqlparser)与mybatis-plus-jsqlparser-4.9模块, 默认不携带,升级后需要自行引入.
-- feat: 重构 service 模块抽象为 CrudRepository 不再建议使用 IService 避免业务层数据混乱
-- feat: 新增 solon 启动插件支持
-- feat: 升级SpringBoot3.3.4
-- feat: 升级velocity2.4

+ 1 - 1
gradle.properties

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

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java

@@ -175,7 +175,7 @@ public class MybatisMapperProxy<T> implements InvocationHandler, Serializable {
                     Class<?> mapperInterface = mybatisMapperProxy.getMapperInterface();
                     IgnoreStrategy ignoreStrategy = InterceptorIgnoreHelper.findIgnoreStrategy(mapperInterface, method);
                     if (ignoreStrategy == null) {
-                        ignoreStrategy = IgnoreStrategy.DEFAULT;
+                        ignoreStrategy = IgnoreStrategy.builder().build();
                     }
                     InterceptorIgnoreHelper.handle(ignoreStrategy);
                     return methodHandle.bindTo(proxy).invokeWithArguments(args);

+ 0 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/IgnoreStrategy.java

@@ -25,12 +25,6 @@ import java.util.Map;
 @Setter
 @Builder
 public class IgnoreStrategy {
-
-    /**
-     * @since 3.5.10
-     */
-    public static final IgnoreStrategy DEFAULT = IgnoreStrategy.builder().build();
-
     private Boolean tenantLine;
     private Boolean dynamicTableName;
     private Boolean blockAttack;

+ 87 - 0
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/DefaultTableAnnotationHandler.java

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011-2024, 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.generator;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.generator.config.GlobalConfig;
+import com.baomidou.mybatisplus.generator.config.builder.Entity;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.model.ClassAnnotationAttributes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 表注解处理器
+ *
+ * @author nieqiurong
+ * @since 3.5.10
+ */
+public class DefaultTableAnnotationHandler implements ITableAnnotationHandler {
+
+    @Override
+    public List<ClassAnnotationAttributes> handle(TableInfo tableInfo, Entity entity) {
+        List<ClassAnnotationAttributes> annotationAttributesList = new ArrayList<>();
+        GlobalConfig globalConfig = tableInfo.getGlobalConfig();
+        String comment = tableInfo.getComment();
+        if (StringUtils.isBlank(comment)) {
+            comment = StringPool.EMPTY;
+        }
+        boolean kotlin = globalConfig.isKotlin();
+        if (!kotlin) {
+            // 原先kt模板没有处理这些,作为兼容项
+            if (entity.isChain()) {
+                annotationAttributesList.add(new ClassAnnotationAttributes("@Accessors(chain = true)", "lombok.experimental.Accessors"));
+            }
+            if (entity.isLombok()) {
+                if (entity.isDefaultLombok()) {
+                    // 原先lombok默认只有这两个
+                    annotationAttributesList.add(new ClassAnnotationAttributes("@Getter", "lombok.Getter"));
+                    annotationAttributesList.add(new ClassAnnotationAttributes("@Setter", "lombok.Setter"));
+                    if (entity.isToString()) {
+                        annotationAttributesList.add(new ClassAnnotationAttributes("@ToString", "lombok.ToString"));
+                    }
+                }
+            }
+        }
+        if (tableInfo.isConvert()) {
+            String schemaName = tableInfo.getSchemaName();
+            if (StringUtils.isBlank(schemaName)) {
+                schemaName = StringPool.EMPTY;
+            } else {
+                schemaName = schemaName + StringPool.DOT;
+            }
+            //@TableName("${schemaName}${table.name}")
+            String displayName = String.format("@TableName(\"%s%s\")", schemaName, tableInfo.getName());
+            annotationAttributesList.add(new ClassAnnotationAttributes(TableName.class, displayName));
+        }
+        if (globalConfig.isSwagger()) {
+            //@ApiModel(value = "${entity}对象", description = "${table.comment!}")
+            String displayName = String.format("@ApiModel(value = \"%s对象\", description = \"%s\")", tableInfo.getEntityName(), comment);
+            annotationAttributesList.add(new ClassAnnotationAttributes(
+                displayName, "io.swagger.annotations.ApiModel", "io.swagger.annotations.ApiModelProperty"));
+        }
+        if (globalConfig.isSpringdoc()) {
+            //@Schema(name = "${entity}", description = "${table.comment!}")
+            String displayName = String.format("@Schema(name = \"%s\", description = \"%s\")", tableInfo.getEntityName(), comment);
+            annotationAttributesList.add(new ClassAnnotationAttributes(displayName, "io.swagger.v3.oas.annotations.media.Schema"));
+        }
+        return annotationAttributesList;
+    }
+
+}

+ 40 - 0
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/ITableAnnotationHandler.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011-2024, 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.generator;
+
+import com.baomidou.mybatisplus.generator.config.builder.Entity;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.model.ClassAnnotationAttributes;
+
+import java.util.List;
+
+/**
+ * 表注解处理器
+ *
+ * @author nieqiurong
+ * @since 3.5.10
+ */
+public interface ITableAnnotationHandler {
+
+    /**
+     * 处理字段级注解
+     *
+     * @param tableInfo 表信息
+     * @return 注解信息
+     */
+    List<ClassAnnotationAttributes> handle(TableInfo tableInfo, Entity entity);
+
+}

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

@@ -18,13 +18,13 @@ package com.baomidou.mybatisplus.generator.config.builder;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.core.handlers.AnnotationHandler;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.generator.DefaultTableAnnotationHandler;
 import com.baomidou.mybatisplus.generator.DefaultTableFieldAnnotationHandler;
 import com.baomidou.mybatisplus.generator.IFill;
+import com.baomidou.mybatisplus.generator.ITableAnnotationHandler;
 import com.baomidou.mybatisplus.generator.ITableFieldAnnotationHandler;
 import com.baomidou.mybatisplus.generator.ITemplate;
 import com.baomidou.mybatisplus.generator.config.ConstVal;
@@ -77,7 +77,7 @@ public class Entity implements ITemplate {
     private String javaTemplate = ConstVal.TEMPLATE_ENTITY_JAVA;
 
     /**
-     * Kotlin模板默认
+     * Kotlin模板默认路径
      */
     @Getter
     private String kotlinTemplate = ConstVal.TEMPLATE_ENTITY_KT;
@@ -233,10 +233,34 @@ public class Entity implements ITemplate {
     private boolean generate = true;
 
     /**
-     * 默认lombok (兼容属性只有Getter和Setter)
+     * 默认lombok(低版本属性默认只有Getter和Setter)
+     * <p>当升级至3.5.10后,默认启用@ToString,如果不需要,可通过{@link Builder#toString(boolean)}关闭</p>
+     *
+     * @since 3.5.10
      */
+    @Getter
     private boolean defaultLombok = true;
 
+    /**
+     * 是否生成ToString
+     * <p>低版本下,lombok没有处理ToString逻辑,现在处理生成@ToString</p>
+     * <p>支持控制toString方法是否生成</p>
+     *
+     * @since 3.5.10
+     */
+    @Getter
+    private boolean toString = true;
+
+
+    /**
+     * 启用字段文档注释 (当注释字段注释不为空才生效)
+     * <p>低版本下,如果是启用swagger或者springdoc时,不会生成,现在统一修改为生成文档注释</p>
+     *
+     * @since 3.5.10
+     */
+    @Getter
+    private boolean fieldUseJavaDoc = true;
+
     /**
      * 实体类注解
      *
@@ -245,6 +269,13 @@ public class Entity implements ITemplate {
     @Getter
     private final List<ClassAnnotationAttributes> classAnnotations = new ArrayList<>();
 
+    /**
+     * 表注解处理器
+     *
+     * @since 3.5.10
+     */
+    private ITableAnnotationHandler tableAnnotationHandler = new DefaultTableAnnotationHandler();
+
     /**
      * 字段注解处理器
      *
@@ -371,46 +402,18 @@ public class Entity implements ITemplate {
         data.put("entityLombokModel", this.lombok);
         data.put("entityBooleanColumnRemoveIsPrefix", this.booleanColumnRemoveIsPrefix);
         data.put("superEntityClass", ClassUtils.getSimpleName(this.superClass));
-        GlobalConfig globalConfig = tableInfo.getGlobalConfig();
-        String comment = tableInfo.getComment();
         Set<String> importPackages = new HashSet<>(tableInfo.getImportPackages());
-        if (StringUtils.isBlank(comment)) {
-            comment = StringPool.EMPTY;
-        }
-        boolean kotlin = globalConfig.isKotlin();
-        if (!kotlin) {
-            // 原先kt模板没有处理这些,作为兼容项
-            if (chain) {
-                this.classAnnotations.add(new ClassAnnotationAttributes("@Accessors(chain = true)", "lombok.experimental.Accessors"));
-            }
-            if (lombok && defaultLombok) {
-                // 原先lombok默认只有这两个
-                this.classAnnotations.add(new ClassAnnotationAttributes("@Getter", "lombok.Getter"));
-                this.classAnnotations.add(new ClassAnnotationAttributes("@Setter", "lombok.Setter"));
+        List<ClassAnnotationAttributes> classAnnotationAttributes = new ArrayList<>(this.getClassAnnotations());
+        if (tableAnnotationHandler != null) {
+            List<ClassAnnotationAttributes> classAnnotationAttributesList = tableAnnotationHandler.handle(tableInfo, this);
+            if (classAnnotationAttributesList != null && !classAnnotationAttributesList.isEmpty()) {
+                classAnnotationAttributes.addAll(classAnnotationAttributesList);
             }
         }
-        if (tableInfo.isConvert()) {
-            String schemaName = tableInfo.getSchemaName();
-            if (StringUtils.isBlank(schemaName)) {
-                schemaName = StringPool.EMPTY;
-            } else {
-                schemaName = schemaName + StringPool.DOT;
-            }
-            //@TableName("${schemaName}${table.name}")
-            String displayName = String.format("@TableName(\"%s%s\")", schemaName, tableInfo.getName());
-            this.classAnnotations.add(new ClassAnnotationAttributes(TableName.class, displayName));
-        }
-        if (globalConfig.isSwagger()) {
-            //@ApiModel(value = "${entity}对象", description = "${table.comment!}")
-            String displayName = String.format("@ApiModel(value = \"%s对象\", description = \"%s\")", tableInfo.getEntityName(), comment);
-            this.classAnnotations.add(new ClassAnnotationAttributes(
-                displayName, "io.swagger.annotations.ApiModel", "io.swagger.annotations.ApiModelProperty"));
-        }
-        if (globalConfig.isSpringdoc()) {
-            //@Schema(name = "${entity}", description = "${table.comment!}")
-            String displayName = String.format("@Schema(name = \"%s\", description = \"%s\")", tableInfo.getEntityName(), comment);
-            this.classAnnotations.add(new ClassAnnotationAttributes(displayName, "io.swagger.v3.oas.annotations.media.Schema"));
-        }
+        classAnnotationAttributes.forEach(attributes -> {
+            attributes.handleDisplayName(tableInfo);
+            importPackages.addAll(attributes.getImportPackages());
+        });
         if (tableFieldAnnotationHandler != null) {
             tableInfo.getFields().forEach(tableField -> {
                 List<AnnotationAttributes> annotationAttributes = tableFieldAnnotationHandler.handle(tableInfo, tableField);
@@ -420,15 +423,11 @@ public class Entity implements ITemplate {
                 }
             });
         }
-        this.classAnnotations.forEach(attributes -> {
-            attributes.handleDisplayName(tableInfo);
-            importPackages.addAll(attributes.getImportPackages());
-        });
-        //TODO 外部暂时不要使用此属性,内置模板暂时使用
-        data.put("useJavaDoc", !(globalConfig.isSwagger() || globalConfig.isSpringdoc()));
-        data.put("entityClassAnnotations", this.classAnnotations.stream()
+        data.put("entityFieldUseJavaDoc", fieldUseJavaDoc);
+        data.put("entityClassAnnotations", classAnnotationAttributes.stream()
             .sorted(Comparator.comparingInt(s -> s.getDisplayName().length())).collect(Collectors.toList()));
         data.put("importEntityPackages", importPackages.stream().sorted().collect(Collectors.toList()));
+        data.put("entityToString", this.toString);
         return data;
     }
 
@@ -508,6 +507,7 @@ public class Entity implements ITemplate {
 
         /**
          * 开启lombok模型 (默认添加Getter和Setter)
+         * <p>自3.5.10开始,默认添加ToString搭配,如果想关闭可通过{@link #toString(boolean)}关闭</p>
          *
          * @return this
          * @since 3.5.0
@@ -518,7 +518,10 @@ public class Entity implements ITemplate {
         }
 
         /**
-         * 开启lombok模型 (这里会把注解属性都加入进去,无论是否启用{@link GlobalConfig#isKotlin()})
+         * 开启lombok模型 (会把注解属性都加入进去,无论是否启用{@link GlobalConfig#isKotlin()})
+         * <p>注意如果通过此方法开启lombok模型,默认的lombok注解(get,set,toString)都将不会生成,请自行控制添加</p>
+         * <p>由{@link #toString(boolean)}控制的也会失效</p>
+         * 使用@Data示例: enableLombok(new ClassAnnotationAttributes("@Data","lombok.Data"))
          *
          * @param attributes 注解属性集合
          * @return this
@@ -803,6 +806,42 @@ public class Entity implements ITemplate {
             return this;
         }
 
+        /**
+         * 指定表注解处理器
+         * @param tableAnnotationHandler 表注解处理器
+         * @since 3.5.10
+         * @return this
+         */
+        public Builder tableAnnotationHandler(@NotNull ITableAnnotationHandler tableAnnotationHandler){
+            this.entity.tableAnnotationHandler = tableAnnotationHandler;
+            return this;
+        }
+
+        /**
+         * 设置是否生成ToString方法
+         *
+         * @param toString 是否生成
+         * @return this
+         * @since 3.5.10
+         */
+        public Builder toString(boolean toString) {
+            this.entity.toString = toString;
+            return this;
+        }
+
+        /**
+         * 设置字段是否生成文档注释
+         *
+         * @param fieldUseJavaDoc 是否生成文档注释
+         * @return this
+         * @since 3.5.10
+         */
+        public Builder fieldUseJavaDoc(boolean fieldUseJavaDoc) {
+            this.entity.fieldUseJavaDoc = fieldUseJavaDoc;
+            return this;
+        }
+
+
         public Entity get() {
             String superClass = this.entity.superClass;
             if (StringUtils.isNotBlank(superClass)) {

+ 40 - 7
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/index/DefaultGenerateMapperLambdaMethodHandler.java

@@ -16,10 +16,13 @@
 package com.baomidou.mybatisplus.generator.index;
 
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper;
 import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper;
 import com.baomidou.mybatisplus.generator.config.GlobalConfig;
+import com.baomidou.mybatisplus.generator.config.StrategyConfig;
+import com.baomidou.mybatisplus.generator.config.builder.Entity;
 import com.baomidou.mybatisplus.generator.config.po.TableField;
 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
 import com.baomidou.mybatisplus.generator.jdbc.DatabaseMetaDataWrapper;
@@ -35,28 +38,47 @@ import java.util.stream.Collectors;
 
 /**
  * 使用Lambda方式生成索引方法
+ * <p>复合索引下,第一个字段不会判空,后续字段会进行判空处理,也就是只能保证第一个字段不传递空,无法解决掉索引中间项传递为空的情况</p>
+ * <p>由于需求不一样,默认只处理单字段索引,如果默认复合索引的方案符合你的要求,你可以考虑{@link #singleIndex}设置成false</p>
  *
  * @author nieqiurong
  * @since 3.5.10
  */
 public class DefaultGenerateMapperLambdaMethodHandler extends AbstractMapperMethodHandler {
 
+    /**
+     * 只生成单索引字段方法(默认true)
+     * <p>当设置为true时,代表会过滤掉复合索引</p>
+     */
+    private final boolean singleIndex;
+
+    public DefaultGenerateMapperLambdaMethodHandler() {
+        this(true);
+    }
+
+    public DefaultGenerateMapperLambdaMethodHandler(boolean singleIndex) {
+        this.singleIndex = singleIndex;
+    }
+
     @Override
     public List<MapperMethod> getMethodList(TableInfo tableInfo) {
         Map<String, List<DatabaseMetaDataWrapper.Index>> indexlistMap = tableInfo.getIndexList().stream()
             .collect(Collectors.groupingBy(DatabaseMetaDataWrapper.Index::getName));
         String entityName = tableInfo.getEntityName();
         GlobalConfig globalConfig = tableInfo.getGlobalConfig();
+        StrategyConfig strategyConfig = tableInfo.getStrategyConfig();
+        Entity entity = strategyConfig.entity();
         Set<Map.Entry<String, List<DatabaseMetaDataWrapper.Index>>> entrySet = indexlistMap.entrySet();
         List<MapperMethod> methodList = new ArrayList<>();
         for (Map.Entry<String, List<DatabaseMetaDataWrapper.Index>> entry : entrySet) {
             String indexName = entry.getKey();
             List<DatabaseMetaDataWrapper.Index> indexList = entry.getValue();
             int indexSize = indexList.size();
-            if ("PRIMARY".equals(indexName)) {
-                if (indexSize == 1) {
-                    continue;
-                }
+            if (this.singleIndex && indexSize > 1) {
+                continue;
+            }
+            if ("PRIMARY".equals(indexName) && indexSize == 1) {
+                continue;
             }
             Map<String, TableField> tableFieldMap = tableInfo.getTableFieldMap();
             StringBuilder baseMethodNameBuilder = new StringBuilder();
@@ -70,6 +92,10 @@ public class DefaultGenerateMapperLambdaMethodHandler extends AbstractMapperMeth
                     uniqueKey = true;
                 }
                 TableField tableField = tableFieldMap.get(index.getColumnName());
+                if (index.getColumnName().equals(entity.getLogicDeleteColumnName())
+                    || tableField.getPropertyName().equals(entity.getLogicDeletePropertyName())) {
+                    continue;
+                }
                 tableFieldList.add(tableField);
                 baseMethodNameBuilder.append(tableField.getCapitalName());
                 if (indexSize > 1) {
@@ -96,8 +122,11 @@ public class DefaultGenerateMapperLambdaMethodHandler extends AbstractMapperMeth
                     argsBuilder.append(", ");
                 }
             }
-            boolean returnList = (indexSize > 1 || !uniqueKey);
             String baseMethodName = baseMethodNameBuilder.toString();
+            if (StringUtils.isBlank(baseMethodName)) {
+                continue;
+            }
+            boolean returnList = (indexSize > 1 || !uniqueKey);
             String args = argsBuilder.toString();
             String baseWrapper = baseWrapperBuilder.toString();
             if (globalConfig.isKotlin()) {
@@ -142,8 +171,12 @@ public class DefaultGenerateMapperLambdaMethodHandler extends AbstractMapperMeth
     public Set<String> getImportPackages(TableInfo tableInfo) {
         GlobalConfig globalConfig = tableInfo.getGlobalConfig();
         Set<String> imports = new HashSet<>();
-        imports.add(ObjectUtils.class.getName());
-        imports.add(List.class.getName());
+        if (!singleIndex) {
+            imports.add(ObjectUtils.class.getName());
+        }
+        if (!globalConfig.isKotlin()) {
+            imports.add(List.class.getName());
+        }
         if (globalConfig.isKotlin()) {
             imports.add(KtQueryWrapper.class.getName());
             imports.add(KtUpdateWrapper.class.getName());

+ 36 - 6
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/index/DefaultGenerateMapperMethodHandler.java

@@ -16,6 +16,7 @@
 package com.baomidou.mybatisplus.generator.index;
 
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.generator.config.GlobalConfig;
 import com.baomidou.mybatisplus.generator.config.builder.Entity;
@@ -34,6 +35,8 @@ import java.util.stream.Collectors;
 
 /**
  * 按字符串或者字符串常量方法生成查询条件
+ * <p>复合索引下,第一个字段不会判空,后续字段会进行判空处理,也就是只能保证第一个字段不传递空,无法解决掉索引中间项传递为空的情况</p>
+ * <p>由于需求不一样,默认只处理单字段索引,如果默认复合索引的方案符合你的要求,你可以考虑{@link #singleIndex}设置成false</p>
  *
  * @author nieqiurong
  * @see Entity.Builder#enableColumnConstant()
@@ -41,6 +44,20 @@ import java.util.stream.Collectors;
  */
 public class DefaultGenerateMapperMethodHandler extends AbstractMapperMethodHandler {
 
+    /**
+     * 只生成单索引字段方法(默认true)
+     * <p>当设置为true时,代表会过滤掉复合索引</p>
+     */
+    private final boolean singleIndex;
+
+    public DefaultGenerateMapperMethodHandler() {
+        this(true);
+    }
+
+    public DefaultGenerateMapperMethodHandler(boolean singleIndex) {
+        this.singleIndex = singleIndex;
+    }
+
     @Override
     public List<MapperMethod> getMethodList(TableInfo tableInfo) {
         Map<String, List<DatabaseMetaDataWrapper.Index>> indexlistMap = tableInfo.getIndexList().stream()
@@ -55,10 +72,11 @@ public class DefaultGenerateMapperMethodHandler extends AbstractMapperMethodHand
             String indexName = entry.getKey();
             List<DatabaseMetaDataWrapper.Index> indexList = entry.getValue();
             int indexSize = indexList.size();
-            if ("PRIMARY".equals(indexName)) {
-                if (indexSize == 1) {
-                    continue;
-                }
+            if (this.singleIndex && indexSize > 1) {
+                continue;
+            }
+            if ("PRIMARY".equals(indexName) && indexSize == 1) {
+                continue;
             }
             List<TableField> tableFieldList = new ArrayList<>();
             Map<String, TableField> tableFieldMap = tableInfo.getTableFieldMap();
@@ -72,6 +90,10 @@ public class DefaultGenerateMapperMethodHandler extends AbstractMapperMethodHand
                     uniqueKey = true;
                 }
                 TableField tableField = tableFieldMap.get(index.getColumnName());
+                if (index.getColumnName().equals(entity.getLogicDeleteColumnName())
+                    || tableField.getPropertyName().equals(entity.getLogicDeletePropertyName())) {
+                    continue;
+                }
                 tableFieldList.add(tableField);
                 baseMethodNameBuilder.append(tableField.getCapitalName());
                 if (indexSize > 1) {
@@ -101,6 +123,9 @@ public class DefaultGenerateMapperMethodHandler extends AbstractMapperMethodHand
                 }
             }
             String baseMethodName = baseMethodNameBuilder.toString();
+            if (StringUtils.isBlank(baseMethodNameBuilder)) {
+                continue;
+            }
             String args = argsBuilder.toString();
             String baseWrapper = baseWrapperBuilder.toString();
             boolean returnList = (indexSize > 1 || !uniqueKey);
@@ -145,9 +170,14 @@ public class DefaultGenerateMapperMethodHandler extends AbstractMapperMethodHand
 
     @Override
     public Set<String> getImportPackages(TableInfo tableInfo) {
+        GlobalConfig globalConfig = tableInfo.getGlobalConfig();
         Set<String> imports = new HashSet<>();
-        imports.add(ObjectUtils.class.getName());
-        imports.add(List.class.getName());
+        if (!singleIndex) {
+            imports.add(ObjectUtils.class.getName());
+        }
+        if (!globalConfig.isKotlin()) {
+            imports.add(List.class.getName());
+        }
         imports.add(Wrappers.class.getName());
         return imports;
     }

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

@@ -38,7 +38,7 @@ public class ${entity} {
     }
     %>
     <% if(isNotEmpty(field.comment)){ %>
-        <% if(useJavaDoc){ %>
+        <% if(entityFieldUseJavaDoc){ %>
     /**
      * ${field.comment}
      */
@@ -94,7 +94,7 @@ public class ${entity} {
     <% } %>
     }
 <% } %>
-<% if(!entityLombokModel){ %>
+<% if(!entityLombokModel && entityToString){ %>
 
     @Override
     public String toString() {

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

@@ -35,7 +35,7 @@ public class #(entity) {
 #set(keyPropertyName = field.propertyName)
 #end
 #if(field.comment != null)
-  #if(useJavaDoc)
+  #if(entityFieldUseJavaDoc)
     /**
      * #(field.comment)
      */
@@ -90,7 +90,7 @@ public class #(entity) {
   #end
     }
 #end
-#if(!entityLombokModel)
+#if(!entityLombokModel && entityToString)
 
     @Override
     public String toString() {

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

@@ -34,7 +34,7 @@ public class ${entity} {
     </#if>
 
     <#if field.comment!?length gt 0>
-        <#if useJavaDoc>
+        <#if entityFieldUseJavaDoc>
     /**
      * ${field.comment}
      */
@@ -87,7 +87,7 @@ public class ${entity} {
     </#if>
     }
 </#if>
-<#if !entityLombokModel>
+<#if !entityLombokModel && entityToString>
 
     @Override
     public String toString() {

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

@@ -35,7 +35,7 @@ public class ${entity} {
 #set($keyPropertyName=${field.propertyName})
 #end
 #if("$!field.comment" != "")
-  #if(${useJavaDoc})
+  #if(${entityFieldUseJavaDoc})
     /**
      * ${field.comment}
      */
@@ -90,7 +90,7 @@ public class ${entity} {
   #end
     }
 #end
-#if(!${entityLombokModel})
+#if(!${entityLombokModel} && ${entityToString})
 
     @Override
     public String toString() {

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

@@ -33,7 +33,7 @@ class ${entity} {
     }
     %>
     <% if(isNotEmpty(field.comment)){ %>
-        <% if(useJavaDoc){ %>
+        <% if(entityFieldUseJavaDoc){ %>
     /**
      * ${field.comment}
      */
@@ -68,7 +68,7 @@ class ${entity} {
     }
 
 <% } %>
-<% if(!entityLombokModel){ %>
+<% if(entityToString){ %>
     @Override
     override fun toString(): String  {
         return "${entity}{" +

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

@@ -31,7 +31,7 @@ class #(entity) {
 #set(keyPropertyName = field.propertyName)
 #end
 #if(field.comment != null)
-    #if(useJavaDoc)
+    #if(entityFieldUseJavaDoc)
     /**
      * #(field.comment)
      */
@@ -68,6 +68,7 @@ class #(entity) {
     }
 
 #end
+#if(entityToString)
     override fun toString(): String {
         return "#(entity){" +
 #for(field : table.fields)
@@ -79,4 +80,5 @@ class #(entity) {
 #end
         "}"
     }
+#end
 }

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

@@ -31,7 +31,7 @@ class ${entity} {
     <#assign keyPropertyName="${field.propertyName}"/>
 </#if>
 <#if field.comment!?length gt 0>
-    <#if useJavaDoc>
+    <#if entityFieldUseJavaDoc>
     /**
      * ${field.comment}
      */
@@ -68,6 +68,7 @@ class ${entity} {
     }
 
 </#if>
+<#if entityToString>
     override fun toString(): String {
         return "${entity}{" +
 <#list table.fields as field>
@@ -79,4 +80,5 @@ class ${entity} {
 </#list>
         "}"
     }
+</#if>
 }

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

@@ -31,7 +31,7 @@ class ${entity} {
 #set($keyPropertyName=${field.propertyName})
 #end
 #if("$!field.comment" != "")
-    #if(${useJavaDoc})
+    #if(${entityFieldUseJavaDoc})
     /**
      * ${field.comment}
      */
@@ -68,6 +68,7 @@ class ${entity} {
     }
 
 #end
+#if(${entityToString})
     override fun toString(): String {
         return "${entity}{" +
 #foreach($field in ${table.fields})
@@ -79,4 +80,5 @@ class ${entity} {
 #end
         "}"
     }
+#end
 }

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

@@ -36,6 +36,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import net.sf.jsqlparser.statement.select.Values;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
@@ -120,8 +121,10 @@ import net.sf.jsqlparser.statement.update.UpdateSet;
  * </p>
  *
  * @author yuxiaobin
+ * @deprecated 3.5.10 问题太多,计划移除
  * @date 2022-8-21
  */
+@Deprecated
 public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
 
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -663,7 +666,7 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
             selectItems.add(new SelectItem<>(column));
         }
         TableInfo tableInfo = getTableInfoByTableName(tableName);
-        if (tableInfo == null) {
+        if (tableInfo == null || StringUtils.isBlank(tableInfo.getKeyColumn())) {
             return Columns2SelectItemsResult.build(selectItems, 0);
         }
         Column pk = new Column(tableInfo.getKeyColumn());

+ 2 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java

@@ -85,8 +85,10 @@ import java.util.concurrent.ConcurrentHashMap;
  * <p>7.where条件使用了 使用子查询</p>
  *
  * @author willenfoo
+ * @deprecated 3.5.10 实用性不高,语法分析太差,计划移除
  * @since 3.4.0
  */
+@Deprecated
 public class IllegalSQLInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
 
     /**

+ 1 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/parser/cache/FstFactory.java

@@ -73,6 +73,7 @@ public class FstFactory {
         conf.registerClass(net.sf.jsqlparser.expression.OracleNamedFunctionParameter.class);
         conf.registerClass(net.sf.jsqlparser.expression.OrderByClause.class);
         conf.registerClass(net.sf.jsqlparser.expression.OverlapsCondition.class);
+        conf.registerClass(net.sf.jsqlparser.expression.Parenthesis.class);
         conf.registerClass(net.sf.jsqlparser.expression.PartitionByClause.class);
         conf.registerClass(net.sf.jsqlparser.expression.RangeExpression.class);
         conf.registerClass(net.sf.jsqlparser.expression.RowConstructor.class);

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

@@ -36,6 +36,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import net.sf.jsqlparser.statement.select.Values;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
@@ -120,8 +121,10 @@ import net.sf.jsqlparser.statement.update.UpdateSet;
  * </p>
  *
  * @author yuxiaobin
+ * @deprecated 3.5.10 问题太多,计划移除
  * @date 2022-8-21
  */
+@Deprecated
 public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
 
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -663,7 +666,7 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
             selectItems.add(new SelectItem<>(column));
         }
         TableInfo tableInfo = getTableInfoByTableName(tableName);
-        if (tableInfo == null) {
+        if (tableInfo == null || StringUtils.isBlank(tableInfo.getKeyColumn())) {
             return Columns2SelectItemsResult.build(selectItems, 0);
         }
         Column pk = new Column(tableInfo.getKeyColumn());

+ 2 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java

@@ -84,8 +84,10 @@ import java.util.concurrent.ConcurrentHashMap;
  * <p>7.where条件使用了 使用子查询</p>
  *
  * @author willenfoo
+ * @deprecated 3.5.10 实用性不高,语法分析太差,计划移除
  * @since 3.4.0
  */
+@Deprecated
 public class IllegalSQLInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
 
     /**

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

@@ -36,6 +36,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import net.sf.jsqlparser.statement.select.Values;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
@@ -120,8 +121,10 @@ import net.sf.jsqlparser.statement.update.UpdateSet;
  * </p>
  *
  * @author yuxiaobin
+ * @deprecated 3.5.10 问题太多,计划移除
  * @date 2022-8-21
  */
+@Deprecated
 public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
 
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -663,7 +666,7 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
             selectItems.add(new SelectItem<>(column));
         }
         TableInfo tableInfo = getTableInfoByTableName(tableName);
-        if (tableInfo == null) {
+        if (tableInfo == null || StringUtils.isBlank(tableInfo.getKeyColumn())) {
             return Columns2SelectItemsResult.build(selectItems, 0);
         }
         Column pk = new Column(tableInfo.getKeyColumn());

+ 2 - 0
mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java

@@ -84,8 +84,10 @@ import java.util.concurrent.ConcurrentHashMap;
  * <p>7.where条件使用了 使用子查询</p>
  *
  * @author willenfoo
+ * @deprecated 3.5.10 实用性不高,语法分析太差,计划移除
  * @since 3.4.0
  */
+@Deprecated
 public class IllegalSQLInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
 
     /**

+ 1 - 1
settings.gradle

@@ -8,7 +8,7 @@ buildscript {
 
     dependencies {
         //noinspection DifferentKotlinGradleVersion
-        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20"
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0"
         classpath "io.freefair.gradle:lombok-plugin:8.10"
         classpath "tech.yanand.maven-central-publish:tech.yanand.maven-central-publish.gradle.plugin:1.1.0"
     }

+ 1 - 12
spring-boot-starter/mybatis-plus-spring-boot-autoconfigure/src/main/java/com/baomidou/mybatisplus/autoconfigure/SafetyEncryptProcessor.java

@@ -24,7 +24,6 @@ import org.springframework.boot.env.OriginTrackedMapPropertySource;
 import org.springframework.core.env.ConfigurableEnvironment;
 import org.springframework.core.env.MapPropertySource;
 import org.springframework.core.env.PropertySource;
-import org.springframework.core.env.SimpleCommandLinePropertySource;
 
 import java.util.HashMap;
 
@@ -38,17 +37,7 @@ public class SafetyEncryptProcessor implements EnvironmentPostProcessor {
 
     @Override
     public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
-        /**
-         * 命令行中获取密钥
-         */
-        String mpwKey = null;
-        for (PropertySource<?> ps : environment.getPropertySources()) {
-            if (ps instanceof SimpleCommandLinePropertySource) {
-                SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;
-                mpwKey = source.getProperty("mpw.key");
-                break;
-            }
-        }
+        String mpwKey = environment.getProperty("mpw.key");
         /**
          * 处理加密内容
          */

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

@@ -14,7 +14,7 @@ dependencies {
     implementation "org.springframework.boot:spring-boot-configuration-processor"
     implementation "org.springframework.boot:spring-boot-autoconfigure-processor"
     implementation "${lib['mybatis-thymeleaf']}"
-    implementation "${lib.'mybatis-velocity'}"
+    implementation "org.mybatis.scripting:mybatis-velocity:2.3.0"
     implementation "${lib.'mybatis-freemarker'}"
     implementation "org.springframework.cloud:spring-cloud-commons:4.1.4"
     testImplementation "org.springframework.boot:spring-boot-starter-test"