瀏覽代碼

改进参数提取.

nieqiurong 1 月之前
父節點
當前提交
c7679155ed

+ 94 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/assist/AbstractSqlRunner.java

@@ -0,0 +1,94 @@
+/*
+ * 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.core.assist;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import org.apache.ibatis.parsing.GenericTokenParser;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * @author nieqiurong
+ * @since 3.5.12
+ */
+public abstract class AbstractSqlRunner implements ISqlRunner {
+
+    /**
+     * 默认分词处理器
+     *
+     * @since 3.5.12
+     */
+    private static final GenericTokenParser DEFAULT_TOKEN_PARSER = new GenericTokenParser("{", "}", content -> "#{" + content + "}");
+
+    /**
+     * 校验索引正则
+     *
+     * @since 3.5.12
+     */
+    private final Pattern pattern = Pattern.compile("^\\d+$");
+
+    /**
+     * 获取执行语句
+     *
+     * @param sql  原始sql
+     * @param args 参数
+     * @return 执行语句
+     * @since 3.5.12
+     */
+    protected String parse(String sql, Object... args) {
+        if (args != null && args.length == 1) {
+            Object arg = args[0];
+            Class<?> clazz = arg.getClass();
+            return new GenericTokenParser("{", "}", content -> {
+                if (pattern.matcher(content).matches()) {
+                    if (arg instanceof Collection || clazz.isArray()) {
+                        return "#{arg0[" + content + "]}";
+                    }
+                    return "#{" + content + "}";
+                } else {
+                    return "#{arg0." + content + "}";
+                }
+            }).parse(sql);
+        }
+        return DEFAULT_TOKEN_PARSER.parse(sql);
+    }
+
+    /**
+     * 获取参数列表
+     *
+     * @param args 参数(单参数时,支持使用Map,List,Array,JavaBean访问)
+     * @return 参数map
+     * @since 3.5.12
+     */
+    protected Map<String, Object> getParams(Object... args) {
+        if (args != null && args.length > 0) {
+            Map<String, Object> params = CollectionUtils.newHashMapWithExpectedSize(args.length);
+            for (int i = 0; i < args.length; i++) {
+                Object arg = args[i];
+                if (i == 0) {
+                    params.put("arg0", arg);
+                }
+                params.put(String.valueOf(i), arg);
+            }
+            return params;
+        }
+        return new HashMap<>();
+    }
+
+}

+ 0 - 87
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/assist/ISqlRunner.java

@@ -17,16 +17,7 @@ package com.baomidou.mybatisplus.core.assist;
 
 import com.baomidou.mybatisplus.core.injector.SqlRunnerInjector;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import org.apache.ibatis.parsing.GenericTokenParser;
-import org.apache.ibatis.reflection.MetaObject;
-import org.apache.ibatis.reflection.SystemMetaObject;
-import org.apache.ibatis.type.SimpleTypeRegistry;
 
-import java.lang.reflect.Array;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -45,13 +36,6 @@ import java.util.Map;
  */
 public interface ISqlRunner {
 
-    /**
-     * 默认分词处理器
-     *
-     * @since 3.5.12
-     */
-    GenericTokenParser TOKEN_PARSER = new GenericTokenParser("{", "}", content -> "#{" + content + "}");
-
     /**
      * INSERT 语句
      */
@@ -185,75 +169,4 @@ public interface ISqlRunner {
      * @return 分页数据
      */
     <E extends IPage<Map<String, Object>>> E selectPage(E page, String sql, Object... args);
-
-
-    /**
-     * 获取执行语句
-     *
-     * @param sql 原始sql
-     * @return 执行语句
-     * @since 3.5.12
-     */
-    default String parse(String sql) {
-        return TOKEN_PARSER.parse(sql);
-    }
-
-    /**
-     * 获取参数列表
-     *
-     * @param args 参数(单参数时,支持使用Map,List,Array,JavaBean访问)
-     * @return 参数map
-     * @since 3.5.12
-     */
-    @SuppressWarnings("rawtypes")
-    default Map<String, Object> getParams(Object... args) {
-        if (args != null && args.length > 0) {
-            if (args.length == 1) {
-                // 暂定支持 Map,Collection,Array,JavaBean
-                Object arg = args[0];
-                if (arg instanceof Map) {
-                    //noinspection unchecked
-                    return new HashMap<String, Object>((Map) arg);
-                }
-                if (arg instanceof Collection) {
-                    Collection<?> collection = (Collection<?>) arg;
-                    Map<String, Object> params = new HashMap<>(CollectionUtils.newHashMapWithExpectedSize(collection.size()));
-                    Iterator<?> iterator = collection.iterator();
-                    int index = 0;
-                    while (iterator.hasNext()) {
-                        params.put(String.valueOf(index), iterator.next());
-                        index++;
-                    }
-                    return params;
-                }
-                Class<?> cls = arg.getClass();
-                if (cls.isArray()) {
-                    int length = Array.getLength(arg);
-                    Map<String, Object> params = new HashMap<>(CollectionUtils.newHashMapWithExpectedSize(length));
-                    for (int i = 0; i < length; i++) {
-                        params.put(String.valueOf(i), Array.get(arg, i));
-                    }
-                    return params;
-                }
-                if (!(cls.isPrimitive()
-                    || SimpleTypeRegistry.isSimpleType(cls)
-                    || cls.isEnum())
-                ) {
-                    MetaObject metaObject = SystemMetaObject.forObject(arg);
-                    String[] getterNames = metaObject.getGetterNames();
-                    Map<String, Object> params = new HashMap<>(CollectionUtils.newHashMapWithExpectedSize(getterNames.length));
-                    for (String getterName : getterNames) {
-                        params.put(getterName, metaObject.getValue(getterName));
-                    }
-                    return params;
-                }
-            }
-            Map<String, Object> params = CollectionUtils.newHashMapWithExpectedSize(args.length);
-            for (int i = 0; i < args.length; i++) {
-                params.put(String.valueOf(i), args[i]);
-            }
-            return params;
-        }
-        return new HashMap<>();
-    }
 }

+ 4 - 4
mybatis-plus-spring/src/main/java/com/baomidou/mybatisplus/extension/toolkit/SqlRunner.java

@@ -15,7 +15,7 @@
  */
 package com.baomidou.mybatisplus.extension.toolkit;
 
-import com.baomidou.mybatisplus.core.assist.ISqlRunner;
+import com.baomidou.mybatisplus.core.assist.AbstractSqlRunner;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
@@ -43,7 +43,7 @@ import java.util.Optional;
  * @author Caratacus, nieqiurong
  * @since 2016-12-11
  */
-public class SqlRunner implements ISqlRunner {
+public class SqlRunner extends AbstractSqlRunner {
 
     /**
      * 日志对象
@@ -147,7 +147,7 @@ public class SqlRunner implements ISqlRunner {
      */
     private Map<String, Object> sqlMap(String sql, Object... args) {
         Map<String, Object> sqlMap = getParams(args);
-        sqlMap.put(SQL, parse(sql));
+        sqlMap.put(SQL, parse(sql, args));
         return sqlMap;
     }
 
@@ -162,7 +162,7 @@ public class SqlRunner implements ISqlRunner {
     private Map<String, Object> sqlMap(String sql, IPage<?> page, Object... args) {
         Map<String, Object> sqlMap = getParams(args);
         sqlMap.put(PAGE, page);
-        sqlMap.put(SQL, parse(sql));
+        sqlMap.put(SQL, parse(sql, args));
         return sqlMap;
     }
 

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/uuid/UUIDEntityTest.java

@@ -1,5 +1,7 @@
 package com.baomidou.mybatisplus.test.uuid;
 
+import com.baomidou.mybatisplus.core.config.GlobalConfig;
+import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
 import com.baomidou.mybatisplus.test.BaseDbTest;
 import org.apache.ibatis.session.Configuration;
 import org.junit.jupiter.api.Assertions;
@@ -55,6 +57,7 @@ public class UUIDEntityTest extends BaseDbTest<UUIDEntityMapper> {
         doTest(m -> Assertions.assertDoesNotThrow(()-> m.deleteById(new UUIDEntity(){})));
         doTest(m -> Assertions.assertDoesNotThrow(()-> m.deleteById(new DeleteByIdDto<>(UUID.randomUUID()))));
         doTest(m -> Assertions.assertDoesNotThrow(()-> m.deleteById(new DeleteByIdDto<>(UUID.randomUUID().toString()))));
+        doTest(m -> Assertions.assertDoesNotThrow(()-> SqlRunner.db(UUIDEntity.class).delete("delete from entity where id = {0}", UUID.randomUUID())));
     }
 
 
@@ -79,4 +82,9 @@ public class UUIDEntityTest extends BaseDbTest<UUIDEntityMapper> {
                 "PRIMARY KEY (id)" +
                 ")");
     }
+
+    @Override
+    protected GlobalConfig globalConfig() {
+        return super.globalConfig().setEnableSqlRunner(true);
+    }
 }