miemie vor 4 Jahren
Ursprung
Commit
3d38ddc4a9

+ 4 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/AbstractWrapper.java

@@ -386,6 +386,10 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
      */
     protected abstract Children instance();
 
+    protected final String formatParam(String sql, Object param, String mapping) {
+        return null; // todo
+    }
+
     /**
      * 格式化SQL
      *

+ 6 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/LambdaUpdateWrapper.java

@@ -75,9 +75,13 @@ public class LambdaUpdateWrapper<T> extends AbstractLambdaWrapper<T, LambdaUpdat
     }
 
     @Override
-    public LambdaUpdateWrapper<T> set(boolean condition, SFunction<T, ?> column, Object val) {
+    public LambdaUpdateWrapper<T> set(boolean condition, SFunction<T, ?> column, Object val, String mapping) {
         if (condition) {
-            sqlSet.add(String.format("%s=%s", columnToString(column), formatSql("{0}", val)));
+            String sql = formatSql("{0}", val);
+            if (StringUtils.isNotBlank(mapping)) {
+                sql = sql.substring(0, sql.length() - 1) + StringPool.COMMA + mapping + "}";
+            }
+            sqlSet.add(String.format("%s=%s", columnToString(column), sql));
         }
         return typedThis;
     }

+ 81 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/Update.java

@@ -15,6 +15,10 @@
  */
 package com.baomidou.mybatisplus.core.conditions.update;
 
+import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.TypeHandler;
+
 import java.io.Serializable;
 
 /**
@@ -38,7 +42,83 @@ public interface Update<Children, R> extends Serializable {
      * @param val       值
      * @return children
      */
-    Children set(boolean condition, R column, Object val);
+    default Children set(boolean condition, R column, Object val) {
+        return set(condition, column, val, null, null, null);
+    }
+
+    /**
+     * ignore
+     */
+    default Children set(R column, Object val, Class<? extends TypeHandler> typeHandler) {
+        return set(true, column, val, typeHandler, null, null);
+    }
+
+    /**
+     * 设置 更新 SQL 的 SET 片段
+     *
+     * @param condition 是否加入 set
+     * @param column    字段
+     * @param val       值
+     * @return children
+     */
+    default Children set(boolean condition, R column, Object val, Class<? extends TypeHandler> typeHandler) {
+        return set(condition, column, val, typeHandler, null, null);
+    }
+
+    /**
+     * ignore
+     */
+    default Children set(R column, Object val, Class<? extends TypeHandler> typeHandler, JdbcType jdbcType) {
+        return set(true, column, val, typeHandler, jdbcType, null);
+    }
+
+    /**
+     * ignore
+     */
+    default Children set(boolean condition, R column, Object val, Class<? extends TypeHandler> typeHandler, JdbcType jdbcType) {
+        return set(condition, column, val, typeHandler, jdbcType, null);
+    }
+
+    /**
+     * ignore
+     */
+    default Children set(R column, Object val, Class<? extends TypeHandler> typeHandler, JdbcType jdbcType, Integer numericScale) {
+        return set(true, column, val, typeHandler, jdbcType, numericScale);
+    }
+
+    /**
+     * 设置 更新 SQL 的 SET 片段
+     *
+     * @param condition 是否加入 set
+     * @param column    字段
+     * @param val       值
+     * @return children
+     */
+    default Children set(boolean condition, R column, Object val, Class<? extends TypeHandler> typeHandler, JdbcType jdbcType, Integer numericScale) {
+        String mapping = null;
+        if (condition) {
+            mapping = SqlScriptUtils.convertParamMapping(typeHandler, jdbcType, numericScale);
+        }
+        return set(condition, column, val, mapping);
+    }
+
+    /**
+     * ignore
+     */
+    default Children set(R column, Object val, String mapping) {
+        return set(true, column, val, mapping);
+    }
+
+    /**
+     * 设置 更新 SQL 的 SET 片段
+     *
+     * @param condition 是否加入 set
+     * @param column    字段
+     * @param val       值
+     * @param mapping   例: javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler
+     * @return children
+     */
+    Children set(boolean condition, R column, Object val, String mapping);
 
     /**
      * ignore

+ 6 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/UpdateWrapper.java

@@ -75,9 +75,13 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
     }
 
     @Override
-    public UpdateWrapper<T> set(boolean condition, String column, Object val) {
+    public UpdateWrapper<T> set(boolean condition, String column, Object val, String mapping) {
         if (condition) {
-            sqlSet.add(String.format("%s=%s", column, formatSql("{0}", val)));
+            String sql = formatSql("{0}", val);
+            if (StringUtils.isNotBlank(mapping)) {
+                sql = sql.substring(0, sql.length() - 1) + StringPool.COMMA + mapping + "}";
+            }
+            sqlSet.add(String.format("%s=%s", column, sql));
         }
         return typedThis;
     }

+ 65 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/sql/SqlScriptUtils.java

@@ -17,6 +17,8 @@ package com.baomidou.mybatisplus.core.toolkit.sql;
 
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.TypeHandler;
 
 /**
  * <p>
@@ -155,7 +157,24 @@ public abstract class SqlScriptUtils implements Constants {
      * @return 脚本
      */
     public static String safeParam(final String param) {
-        return HASH_LEFT_BRACE + param + RIGHT_BRACE;
+        return safeParam(param, null);
+    }
+
+    /**
+     * <p>
+     * 安全入参:  #{入参,mapping}
+     * </p>
+     *
+     * @param param   入参
+     * @param mapping 映射
+     * @return 脚本
+     */
+    public static String safeParam(final String param, final String mapping) {
+        String target = HASH_LEFT_BRACE + param;
+        if (StringUtils.isBlank(mapping)) {
+            return target + RIGHT_BRACE;
+        }
+        return target + COMMA + mapping + RIGHT_BRACE;
     }
 
     /**
@@ -169,4 +188,49 @@ public abstract class SqlScriptUtils implements Constants {
     public static String unSafeParam(final String param) {
         return DOLLAR_LEFT_BRACE + param + RIGHT_BRACE;
     }
+
+    public static String mappingTypeHandler(Class<? extends TypeHandler> typeHandler) {
+        if (typeHandler != null) {
+            return "typeHandler=" + typeHandler.getName();
+        }
+        return null;
+    }
+
+    public static String mappingJdbcType(JdbcType jdbcType) {
+        if (jdbcType != null) {
+            return "jdbcType=" + jdbcType.name();
+        }
+        return null;
+    }
+
+    public static String mappingNumericScale(Integer numericScale) {
+        if (numericScale != null) {
+            return "numericScale=" + numericScale;
+        }
+        return null;
+    }
+
+    public static String convertParamMapping(Class<? extends TypeHandler> typeHandler, JdbcType jdbcType, Integer numericScale) {
+        if (typeHandler == null && jdbcType == null && numericScale == null) {
+            return null;
+        }
+        String mapping = null;
+        if (typeHandler != null) {
+            mapping = mappingTypeHandler(typeHandler);
+        }
+        if (jdbcType != null) {
+            mapping = appendMapping(mapping, mappingJdbcType(jdbcType));
+        }
+        if (numericScale != null) {
+            mapping = appendMapping(mapping, mappingNumericScale(numericScale));
+        }
+        return mapping;
+    }
+
+    private static String appendMapping(String mapping, String other) {
+        if (mapping != null) {
+            return mapping + COMMA + other;
+        }
+        return other;
+    }
 }

+ 11 - 35
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/WrapperTest.java → mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/conditions/QueryWrapperTest.java

@@ -1,34 +1,24 @@
-/*
- * Copyright (c) 2011-2019, hubin (jobob@qq.com).
- * <p>
- * 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
- * <p>
- * https://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.test;
+package com.baomidou.mybatisplus.core.conditions;
 
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.test.User;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
-import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.time.LocalDate;
 import java.util.*;
 
-class WrapperTest {
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author miemie
+ * @since 2021-01-27
+ */
+class QueryWrapperTest {
 
     private void log(String message) {
         System.out.println(message);
@@ -38,7 +28,7 @@ class WrapperTest {
         System.out.printf(" ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓   ->(%s)<-   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓%n", explain);
         System.out.println(wrapper.getSqlSegment());
         System.out.println(wrapper.getTargetSql());
-        Assertions.assertThat(wrapper.getTargetSql().trim()).isEqualTo(targetSql);
+        assertThat(wrapper.getTargetSql().trim()).isEqualTo(targetSql);
     }
 
     private <T> void logParams(QueryWrapper<T> wrapper) {
@@ -170,7 +160,7 @@ class WrapperTest {
     void testFunc() {
         QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
             .isNull("nullColumn").or().isNotNull("notNullColumn")
-            .orderByAsc("id").orderByDesc("name","name2")
+            .orderByAsc("id").orderByDesc("name", "name2")
             .groupBy("id").groupBy("name", "id2", "name2")
             .in("inColl", getList()).or().notIn("notInColl", getList())
             .in("inArray").notIn("notInArray", 1, 2, 3)
@@ -249,18 +239,4 @@ class WrapperTest {
         map.put("nullColumn", null);
         return map;
     }
-
-//    public void test() {
-//        String sql = new QueryWrapper()
-//            .where("b.age > 18", condition ->
-//                condition.and("b.type = 'rabid'")
-//                    .or(nested -> nested.apply("name='12'").and("age=1"))
-//                    .notIn("ads,2112,212")
-//                    .last("LIMIT 1")
-//            ).sqlSegment();
-//
-//        log(sql);
-//        assertEquals("WHERE b.age > 18 AND b.type = 'rabid' OR ( name='12' AND age=1 ) NOT IN ( ads,2112,212 ) LIMIT 1", sql);
-//    }
-
 }

+ 34 - 0
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/conditions/UpdateWrapperTest.java

@@ -0,0 +1,34 @@
+package com.baomidou.mybatisplus.core.conditions;
+
+import com.baomidou.mybatisplus.core.conditions.update.Update;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.test.User;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.StringTypeHandler;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author miemie
+ * @since 2021-01-27
+ */
+class UpdateWrapperTest {
+
+    private void logSqlSet(String explain, Update<?, ?> wrapper, String targetSql) {
+        System.out.printf(" ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓   ->(%s)<-   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓%n", explain);
+        System.out.println(wrapper.getSqlSet());
+        Assertions.assertThat(wrapper.getSqlSet().trim()).isEqualTo(targetSql);
+    }
+
+    @Test
+    void test1() {
+        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
+            .set("name", "a", StringTypeHandler.class)
+            .set("name", "a", StringTypeHandler.class, JdbcType.VARCHAR)
+            .set("name", "a", StringTypeHandler.class, JdbcType.VARCHAR, 2);
+        logSqlSet("ss", wrapper,
+            "name=#{ew.paramNameValuePairs.MPGENVAL1,typeHandler=org.apache.ibatis.type.StringTypeHandler}," +
+                "name=#{ew.paramNameValuePairs.MPGENVAL2,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR}," +
+                "name=#{ew.paramNameValuePairs.MPGENVAL3,typeHandler=org.apache.ibatis.type.StringTypeHandler,jdbcType=VARCHAR,numericScale=2}");
+    }
+}

+ 21 - 0
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/toolkit/sql/SqlScriptUtilsTest.java

@@ -0,0 +1,21 @@
+package com.baomidou.mybatisplus.core.toolkit.sql;
+
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.LocalDateTypeHandler;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author miemie
+ * @since 2021-01-27
+ */
+class SqlScriptUtilsTest {
+
+    @Test
+    void convertParamMapping() {
+        assertThat(SqlScriptUtils.convertParamMapping(LocalDateTypeHandler.class, JdbcType.DATE,2))
+            .isEqualTo("typeHandler=org.apache.ibatis.type.LocalDateTypeHandler,jdbcType=DATE,numericScale=2");
+    }
+}

+ 2 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/conditions/update/LambdaUpdateChainWrapper.java

@@ -41,8 +41,8 @@ public class LambdaUpdateChainWrapper<T> extends AbstractChainWrapper<T, SFuncti
     }
 
     @Override
-    public LambdaUpdateChainWrapper<T> set(boolean condition, SFunction<T, ?> column, Object val) {
-        wrapperChildren.set(condition, column, val);
+    public LambdaUpdateChainWrapper<T> set(boolean condition, SFunction<T, ?> column, Object val, String mapping) {
+        wrapperChildren.set(condition, column, val,mapping);
         return typedThis;
     }
 

+ 2 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/conditions/update/UpdateChainWrapper.java

@@ -40,8 +40,8 @@ public class UpdateChainWrapper<T> extends AbstractChainWrapper<T, String, Updat
     }
 
     @Override
-    public UpdateChainWrapper<T> set(boolean condition, String column, Object val) {
-        wrapperChildren.set(condition, column, val);
+    public UpdateChainWrapper<T> set(boolean condition, String column, Object val, String mapping) {
+        wrapperChildren.set(condition, column, val, mapping);
         return typedThis;
     }
 

+ 2 - 2
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtUpdateChainWrapper.kt

@@ -39,8 +39,8 @@ class KtUpdateChainWrapper<T : Any>(
         super.wrapperChildren = KtUpdateWrapper(entity)
     }
 
-    override fun set(condition: Boolean, column: KProperty<*>, value: Any?): KtUpdateChainWrapper<T> {
-        wrapperChildren.set(condition, column, value)
+    override fun set(condition: Boolean, column: KProperty<*>, value: Any?, mapping: String?): KtUpdateChainWrapper<T> {
+        wrapperChildren.set(condition, column, value, mapping)
         return typedThis
     }
 

+ 6 - 2
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtUpdateWrapper.kt

@@ -74,9 +74,13 @@ class KtUpdateWrapper<T : Any> : AbstractKtWrapper<T, KtUpdateWrapper<T>>, Updat
         return typedThis
     }
 
-    override fun set(condition: Boolean, column: KProperty<*>, value: Any?): KtUpdateWrapper<T> {
+    override fun set(condition: Boolean, column: KProperty<*>, value: Any?, mapping: String?): KtUpdateWrapper<T> {
         if (condition) {
-            sqlSet.add(String.format("%s=%s", columnToString(column), formatSql("{0}", value)))
+            var sql = formatSql("{0}", value)
+            if (StringUtils.isNotBlank(mapping)) {
+                sql = sql.substring(0, sql.length - 1) + StringPool.COMMA + mapping + "}"
+            }
+            sqlSet.add(String.format("%s=%s", columnToString(column), sql))
         }
         return typedThis
     }