10 Комити 82759f3660 ... bb2e18c08d

Аутор SHA1 Порука Датум
  nieqiurong bb2e18c08d 发布3.5.10 пре 11 месеци
  nieqiurong 841b24e9ce 改进安全加密处理器密钥获取. пре 11 месеци
  nieqiurong f18028c5fb 计划移除DataChangeRecorderInnerInterceptor与IllegalSQLInnerInterceptor插件. пре 11 месеци
  nieqiurong cef0bf60f4 新增版本更新日志. пре 11 месеци
  nieqiurong d36160b0a6 调整Mapper方法生成(默认单索引生成). пре 11 месеци
  nieqiurong e8c84edfb5 代码调整. пре 11 месеци
  nieqiurong 7ffc2e5ace 修复数据变动插件更新无主键报错. пре 11 месеци
  nieqiurong 19466562f0 支持字段文档注释控制是否生成(默认生成文档注释). пре 11 месеци
  nieqiurong 52d35a55f2 支持toString方法控制(默认lombok开启ToString生成). пре 11 месеци
  nieqiurong c8aa180291 支持表注解自定义处理. пре 11 месеци
28 измењених фајлова са 360 додато и 107 уклоњено
  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"