From 5fc53fb69c634306a287860d96d949fe9c1c2bb1 Mon Sep 17 00:00:00 2001 From: youbeiwuhuan Date: Wed, 12 Jul 2023 23:46:25 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fastmybatis/core/FastmybatisContext.java | 100 +++++- .../fastmybatis/core/mapper/UpdateMapper.java | 93 +++++- .../core/update/ModifyAttrsRecordHandler.java | 40 +++ .../update/ModifyAttrsRecordProxyFactory.java | 89 ++++++ .../core/update/UpdateWrapper.java | 16 + .../fastmybatis/core/util/ClassUtil.java | 38 ++- .../fastmybatis/core/util/ConvertUtil.java | 298 ++++++++++++++++++ .../gitee/fastmybatis/core/util/DateUtil.java | 287 +++++++++++++++++ .../fastmybatis/core/util/StringUtil.java | 143 +++++++++ .../fastmybatis/core/util/UpdateEntity.java | 23 ++ .../fastmybatis-demo-springmvc/pom.xml | 2 +- .../test/java/com/myapp/TUserMapperTest.java | 18 ++ 12 files changed, 1112 insertions(+), 35 deletions(-) create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordHandler.java create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordProxyFactory.java create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/UpdateWrapper.java create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/UpdateEntity.java diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java index 268c4ef..7467d01 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java @@ -7,16 +7,18 @@ import com.gitee.fastmybatis.core.ext.spi.MapperBuilder; import com.gitee.fastmybatis.core.ext.spi.SpiContext; import com.gitee.fastmybatis.core.mapper.CrudMapper; import com.gitee.fastmybatis.core.mapper.Mapper; -import com.gitee.fastmybatis.core.mapper.SchMapper; +import com.gitee.fastmybatis.core.update.ModifyAttrsRecordProxyFactory; +import com.gitee.fastmybatis.core.update.UpdateWrapper; import com.gitee.fastmybatis.core.util.ClassUtil; +import com.gitee.fastmybatis.core.util.ConvertUtil; +import com.gitee.fastmybatis.core.util.StringUtil; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import java.lang.reflect.Field; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; /** * @author thc @@ -33,6 +35,7 @@ public class FastmybatisContext { /** * 设置逻辑删除时额外需要更新的字段 + * * @param equalColumns 待更新字段 * @see com.gitee.fastmybatis.core.mapper.DeleteMapper#deleteByIds(Collection, EqualColumn...) deleteByIds * @see com.gitee.fastmybatis.core.mapper.DeleteMapper#deleteByColumn(String, Object, EqualColumn...) deleteByColumn @@ -65,6 +68,7 @@ public class FastmybatisContext { /** * 获取实体类对应的数据库主键名称 + * * @param entityClass 实体类class * @return 返回数据库主键名称 */ @@ -78,6 +82,7 @@ public class FastmybatisContext { /** * 获取实体类对应的数据库主键名称 + * * @param mapperClass mapperClass * @return 返回数据库主键名称 */ @@ -88,6 +93,7 @@ public class FastmybatisContext { /** * 获取实体类主键对应的JAVA字段名称 + * * @param entityClass 实体类class * @return 返回主键java字段名称 */ @@ -109,6 +115,12 @@ public class FastmybatisContext { if (entity == null) { return null; } + + + if (entity instanceof UpdateWrapper) { + return getPkValueByGetter(entity); + } + Class entityClass = entity.getClass(); String pkJavaName = getPkJavaName(entityClass); Field field = ClassUtil.findField(entityClass, pkJavaName); @@ -124,4 +136,82 @@ public class FastmybatisContext { } } + private static Object getPkValueByGetter(Object entity) { + Class entityClass = entity.getClass(); + if (entity instanceof UpdateWrapper) { + entityClass = ModifyAttrsRecordProxyFactory.getSrcClass(entity.getClass()); + } + + String pkJavaName = getPkJavaName(entityClass); + Field field = ClassUtil.findField(entityClass, pkJavaName); + if (field == null) { + return null; + } + + Class idType = field.getType(); + + Method setter = ClassUtil.findMethod(entityClass, "get" + StringUtil.firstCharToUpperCase(pkJavaName), null); + + if (setter == null) { + return null; + } + setter.setAccessible(true); + try { + return setter.invoke(entity, null); + } catch (IllegalAccessException e) { + LOG.error("反射出错", e); + } catch (InvocationTargetException e) { + LOG.error("反射出错", e); + } + return null; + } + + public static void setPkValue(T entity, Object id) { + setPkValue(entity, entity.getClass(), id); + } + + public static void setPkValue(Object entity, Class entityClass, Object id) { + + String pkJavaName = getPkJavaName(entityClass); + Field field = ClassUtil.findField(entityClass, pkJavaName); + if (field == null) { + return; + } + + Class idType = field.getType(); + + Method setter = ClassUtil.findMethod(entityClass, "set" + StringUtil.firstCharToUpperCase(pkJavaName), new Class[]{idType}); + + if (setter == null) { + return; + } + setter.setAccessible(true); + try { + setter.invoke(entity, new Object[]{ConvertUtil.convert(id, idType)}); + } catch (IllegalAccessException e) { + LOG.error("反射出错", e); + } catch (InvocationTargetException e) { + LOG.error("反射出错", e); + } + } + + public static Set getIgnoreProperties(Class srcClass, Set includeProperties) { + if (null == includeProperties) { + includeProperties = Collections.emptySet(); + } + + + Set IgnoreProperties = new HashSet<>(); + + Field[] fields = srcClass.getDeclaredFields(); + for (Field field : fields) { + if (!includeProperties.contains(field.getName())) { + IgnoreProperties.add(field.getName()); + } + } + + + return IgnoreProperties; + + } } diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java index dc98df3..2b2465e 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java @@ -1,11 +1,12 @@ package com.gitee.fastmybatis.core.mapper; +import com.gitee.fastmybatis.core.FastmybatisContext; import com.gitee.fastmybatis.core.query.Query; +import com.gitee.fastmybatis.core.update.ModifyAttrsRecordProxyFactory; +import com.gitee.fastmybatis.core.update.UpdateWrapper; import org.apache.ibatis.annotations.Param; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 具备更新功能的Mapper @@ -32,17 +33,18 @@ public interface UpdateMapper extends Mapper { /** * 根据条件更新
- *
-     *{@literal
+     * 
+     * {@literal
      * Query query = new Query().eq("state", 2);
      * TUser user = new TUser();
      * user.setUsername("李四");
      * int i = mapper.updateByQuery(user, query);
      * }
      * 对应SQL: UPDATE `t_user` SET `username`=? WHERE state = ?
-     *
- * @param entity 待更新的数据 - * @param query 更新条件 + *
+ * + * @param entity 待更新的数据 + * @param query 更新条件 * @param ignoreProperties 指定忽略更新的字段,可以是实体类属性名,也可以是数据库字段名 * @return 受影响行数 */ @@ -53,8 +55,8 @@ public interface UpdateMapper extends Mapper { /** * 根据条件更新
- *
-     *{@literal
+     * 
+     * {@literal
      * Query query = new Query().eq("state", 2);
      * TUser user = new TUser();
      * user.setUsername("李四");
@@ -63,18 +65,79 @@ public interface UpdateMapper extends Mapper {
      * int i = mapper.updateByQuery(user, query, Arrays.asList("addTime"));
      * }
      * 对应SQL: UPDATE `t_user` SET `username`=? WHERE state = ?
-     *
- * @param entity 待更新的数据 - * @param query 更新条件 + *
+ * + * @param entity 待更新的数据 + * @param query 更新条件 * @param ignoreProperties 指定忽略更新的字段,可以是实体类属性名,也可以是数据库字段名 * @return 受影响行数 */ int updateByQuery(@Param("entity") E entity, @Param("query") Query query, @Param("ignoreProperties") List ignoreProperties); + + /** + * 根据条件强制更新,只要是调用setter赋值的属性都更新哪怕赋的值为null
+ *
+     * {@literal
+     * TUser user = UpdateEntity.of(TUser.class,123L);
+     * user.setUsername(null);
+     * user.setAddTime(new Date());
+     * // 强制更新 user_name和add_time
+     * int i = mapper.forceUpdateById(user);
+     * }
+     * 对应SQL: UPDATE `t_user` SET `username`=? WHERE state = ?
+     * 
+ * + * @param entity 待更新的数据 + * @return 受影响行数 + */ + default int forceUpdateById(E entity) { + return forceUpdateById(entity, true); + } + + /** + * 根据条件强制更新,只要是调用setter赋值的属性都更新哪怕赋的值为null
+ *
+     * {@literal
+     * TUser user = UpdateEntity.of(TUser.class,123L);
+     * user.setUsername(null);
+     * user.setAddTime(new Date());
+     * // 强制更新 user_name和add_time
+     * int i = mapper.forceUpdateById(user,true);
+     * }
+     * 对应SQL: UPDATE `t_user` SET `username`=? WHERE state = ?
+     * 
+ * + * @param entity 待更新的数据 + * @param ignoreLogicDeleteColumn 无视逻辑删除字段 + * @return 受影响行数 + */ + default int forceUpdateById(E entity, boolean ignoreLogicDeleteColumn) { + Objects.requireNonNull(entity, "entity can not null"); + if (!(entity instanceof UpdateWrapper)) { + throw new IllegalStateException("please wrapper entity with UpdateEntity.of() before call setter!!"); + } + + UpdateWrapper uw = (UpdateWrapper) entity; + String pkColumnName = FastmybatisContext.getPkColumnName(ModifyAttrsRecordProxyFactory.getSrcClass(entity.getClass())); + Object pkValue = FastmybatisContext.getPkValue(entity); + Query query = new Query().eq(pkColumnName, pkValue).enableForceUpdate(); + if (ignoreLogicDeleteColumn) { + query.ignoreLogicDeleteColumn(); + } + + + List ignoreProperties = new ArrayList<>(); + ignoreProperties.addAll(FastmybatisContext.getIgnoreProperties(ModifyAttrsRecordProxyFactory.getSrcClass(entity.getClass()), uw.getUpdates().keySet())); + + return updateByQuery(entity, query, ignoreProperties); + } + + /** * 根据条件更新,map中的数据转化成update语句set部分,key为数据库字段名
- *
-     *{@literal
+     * 
+     * {@literal
      * Query query = new Query().eq("id", 1);
      * // key为数据库字段名
      * Map map = new LinkedHashMap<>();
diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordHandler.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordHandler.java
new file mode 100644
index 0000000..d26f1fc
--- /dev/null
+++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordHandler.java
@@ -0,0 +1,40 @@
+package com.gitee.fastmybatis.core.update;
+
+
+import com.gitee.fastmybatis.core.util.StringUtil;
+import org.apache.ibatis.javassist.util.proxy.MethodHandler;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+class ModifyAttrsRecordHandler implements MethodHandler {
+
+    //更新内容
+    private final Map updates = new LinkedHashMap<>();
+
+    public Map getUpdates() {
+        return updates;
+    }
+
+
+    @Override
+    public Object invoke(Object self, Method originalMethod, Method proxyMethod, Object[] args) throws Throwable {
+
+
+        String methodName = originalMethod.getName();
+        if (methodName.startsWith("set")
+                && methodName.length() > 3
+                && Character.isUpperCase(methodName.charAt(3))
+                && originalMethod.getParameterCount() == 1) {
+            String property = StringUtil.firstCharToLowerCase(originalMethod.getName().substring(3));
+            updates.put(property, args[0]);
+        }
+
+        return proxyMethod.invoke(self, args);
+    }
+
+
+}
+
+
diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordProxyFactory.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordProxyFactory.java
new file mode 100644
index 0000000..55e03cb
--- /dev/null
+++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/ModifyAttrsRecordProxyFactory.java
@@ -0,0 +1,89 @@
+package com.gitee.fastmybatis.core.update;
+
+import org.apache.ibatis.javassist.util.proxy.ProxyFactory;
+import org.apache.ibatis.javassist.util.proxy.ProxyObject;
+import org.apache.ibatis.logging.LogFactory;
+
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public class ModifyAttrsRecordProxyFactory {
+
+    private static final ModifyAttrsRecordProxyFactory instance = new ModifyAttrsRecordProxyFactory();
+
+    public static ModifyAttrsRecordProxyFactory getInstance() {
+        return instance;
+    }
+
+    private ModifyAttrsRecordProxyFactory() {
+    }
+
+
+    /**
+     * srcClass -> proxyClass
+     */
+    private static ConcurrentHashMap, Class> srcProxyMap = new ConcurrentHashMap<>();
+
+    /**
+     * proxyClass-> srcClass
+     */
+    private static ConcurrentHashMap, Class> proxySrcMap = new ConcurrentHashMap<>();
+
+    public static Class getProxyClass(Class src) {
+        return srcProxyMap.get(src);
+    }
+
+    public static Class getSrcClass(Class proxy) {
+        return proxySrcMap.get(proxy);
+    }
+
+    private Class createProxyClass(Class target) {
+        Class proxyClass = srcProxyMap.get(target);
+        if (null == proxyClass) {
+            synchronized (ModifyAttrsRecordProxyFactory.class) {
+                proxyClass = srcProxyMap.get(target);
+                if (null == proxyClass) {
+                    ProxyFactory factory = new ProxyFactory();
+                    factory.setSuperclass(target);
+
+                    Class[] interfaces = Arrays.copyOf(target.getInterfaces(), target.getInterfaces().length + 1);
+                    interfaces[interfaces.length - 1] = UpdateWrapper.class;
+                    factory.setInterfaces(interfaces);
+
+                    proxyClass = factory.createClass();
+                    srcProxyMap.put(target, proxyClass);
+                    proxySrcMap.put(proxyClass, target);
+
+                    return proxyClass;
+                }
+            }
+        }
+
+
+        return proxyClass;
+
+
+    }
+
+
+    public synchronized  T get(Class target) {
+
+        Class proxyClass = createProxyClass(target);
+
+        T proxyObject = null;
+        try {
+            proxyObject = (T) proxyClass.newInstance();
+            ((ProxyObject) proxyObject).setHandler(new ModifyAttrsRecordHandler());
+        } catch (Throwable e) {
+            LogFactory.getLog(ModifyAttrsRecordProxyFactory.class).error(e.toString(), e);
+        }
+
+        return proxyObject;
+    }
+
+
+}
+
+
+
diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/UpdateWrapper.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/UpdateWrapper.java
new file mode 100644
index 0000000..9b372b8
--- /dev/null
+++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/UpdateWrapper.java
@@ -0,0 +1,16 @@
+package com.gitee.fastmybatis.core.update;
+
+import org.apache.ibatis.javassist.util.proxy.ProxyObject;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public interface UpdateWrapper extends Serializable {
+
+
+    default Map getUpdates() {
+        ModifyAttrsRecordHandler handler = (ModifyAttrsRecordHandler) ((ProxyObject) this).getHandler();
+        return handler.getUpdates();
+    }
+
+}
diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ClassUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ClassUtil.java
index 6d3911a..53cf2a3 100644
--- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ClassUtil.java
+++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ClassUtil.java
@@ -36,7 +36,9 @@ public class ClassUtil {
     private static final Map CLASS_LAMBDA_CACHE = new ConcurrentHashMap<>();
 
     private ClassUtil() {
-    };
+    }
+
+    ;
 
     /**
      * 返回定义类时的泛型参数的类型. 
@@ -45,11 +47,9 @@ public class ClassUtil { *
* 调用getSuperClassGenricType(getClass(),0)将返回Book的Class类型
* 调用getSuperClassGenricType(getClass(),1)将返回Address的Class类型 - * - * @param clazz - * 从哪个类中获取 - * @param index - * 泛型参数索引,从0开始 + * + * @param clazz 从哪个类中获取 + * @param index 泛型参数索引,从0开始 * @return 返回泛型类型class * @throws IndexOutOfBoundsException */ @@ -74,11 +74,9 @@ public class ClassUtil { /** * 返回接口类的泛型参数的类型 - * - * @param clazz - * 从哪个类中获取 - * @param index - * 泛型参数索引,从0开始 + * + * @param clazz 从哪个类中获取 + * @param index 泛型参数索引,从0开始 * @return 返回class对象 */ public static Class getSuperInterfaceGenericType(Class clazz, int index) { @@ -119,9 +117,8 @@ public class ClassUtil { /** * 是否是数组或结合类 - * - * @param value - * 待检测对象 + * + * @param value 待检测对象 * @return true,是结合或数组 */ public static boolean isArrayOrCollection(Object value) { @@ -212,6 +209,19 @@ public class ClassUtil { return null; } + public static Method findMethod(Class clazz, String methodName, Class[] params) { + if (methodName == null) { + return null; + } + + try { + return clazz.getDeclaredMethod(methodName, params); + } catch (NoSuchMethodException e) { + + return null; + } + } + public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java new file mode 100644 index 0000000..ebd639a --- /dev/null +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.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.gitee.fastmybatis.core.util; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.Temporal; +import java.util.Date; + +public class ConvertUtil { + + private ConvertUtil() {} + + public static Object convert(Object value, Class targetClass) { + return convert(value, targetClass, false); + } + + public static Object convert(Object value, Class targetClass, boolean ignoreConvertError) { + if (value == null && targetClass.isPrimitive()) { + return getPrimitiveDefaultValue(targetClass); + } + if (value == null || (targetClass != String.class && value.getClass() == String.class + && StringUtil.isBlank((String) value))) { + return null; + } + if (value.getClass().isAssignableFrom(targetClass)) { + return value; + } + if (targetClass == String.class) { + return value.toString(); + } else if (targetClass == Integer.class || targetClass == int.class) { + if (value instanceof Number) { + return ((Number) value).intValue(); + } + return Integer.parseInt(value.toString()); + } else if (targetClass == Long.class || targetClass == long.class) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + return Long.parseLong(value.toString()); + } else if (targetClass == Double.class || targetClass == double.class) { + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + return Double.parseDouble(value.toString()); + } else if (targetClass == Float.class || targetClass == float.class) { + if (value instanceof Number) { + return ((Number) value).floatValue(); + } + return Float.parseFloat(value.toString()); + } else if (targetClass == Boolean.class || targetClass == boolean.class) { + String v = value.toString().toLowerCase(); + if ("1".equals(v) || "true".equalsIgnoreCase(v)) { + return Boolean.TRUE; + } else if ("0".equals(v) || "false".equalsIgnoreCase(v)) { + return Boolean.FALSE; + } else { + throw new RuntimeException("Can not parse to boolean type of value: \"" + value + "\""); + } + } else if (targetClass == BigDecimal.class) { + return new BigDecimal(value.toString()); + } else if (targetClass == BigInteger.class) { + return new BigInteger(value.toString()); + } else if (targetClass == byte[].class) { + return value.toString().getBytes(); + } else if (targetClass == Date.class) { + return DateUtil.parseDate(value); + } else if (targetClass == LocalDateTime.class) { + return toLocalDateTime(value); + } else if (targetClass == LocalDate.class) { + return DateUtil.toLocalDate(DateUtil.parseDate(value)); + } else if (targetClass == LocalTime.class) { + return DateUtil.toLocalTime(DateUtil.parseDate(value)); + } else if (targetClass == Short.class || targetClass == short.class) { + if (value instanceof Number) { + return ((Number) value).shortValue(); + } + return Short.parseShort(value.toString()); + } else if (targetClass.isEnum()) { + //TODO 枚举处理 + } + + if (ignoreConvertError) { + return null; + } else { + throw new IllegalArgumentException("Can not convert \"" + value + "\" to type\"" + targetClass.getName() + "\"."); + } + } + + + //Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE + public static Object getPrimitiveDefaultValue(Class paraClass) { + if (paraClass == int.class || paraClass == long.class || paraClass == float.class || paraClass == double.class) { + return 0; + } else if (paraClass == boolean.class) { + return Boolean.FALSE; + } else if (paraClass == short.class) { + return (short) 0; + } else if (paraClass == byte.class) { + return (byte) 0; + } else if (paraClass == char.class) { + return '\u0000'; + } else { + throw new IllegalArgumentException("Can not get primitive default value for type: " + paraClass); + } + } + + + public static Integer toInt(Object i) { + if (i instanceof Integer) { + return (Integer) i; + } else if (i instanceof Number) { + return ((Number) i).intValue(); + } + return i != null ? Integer.parseInt(i.toString()) : null; + } + + public static Long toLong(Object l) { + if (l instanceof Long) { + return (Long) l; + } else if (l instanceof Number) { + return ((Number) l).longValue(); + } + return l != null ? Long.parseLong(l.toString()) : null; + } + + public static Double toDouble(Object d) { + if (d instanceof Double) { + return (Double) d; + } else if (d instanceof Number) { + return ((Number) d).doubleValue(); + } + + return d != null ? Double.parseDouble(d.toString()) : null; + } + + public static BigDecimal toBigDecimal(Object b) { + if (b instanceof BigDecimal) { + return (BigDecimal) b; + } else if (b != null) { + return new BigDecimal(b.toString()); + } else { + return null; + } + } + + public static BigInteger toBigInteger(Object b) { + if (b instanceof BigInteger) { + return (BigInteger) b; + } + // 数据类型 id(19 number)在 Oracle Jdbc 下对应的是 BigDecimal, + // 但是在 MySql 下对应的是 BigInteger,这会导致在 MySql 下生成的代码无法在 Oracle 数据库中使用 + if (b instanceof BigDecimal) { + return ((BigDecimal) b).toBigInteger(); + } else if (b instanceof Number) { + return BigInteger.valueOf(((Number) b).longValue()); + } else if (b instanceof String) { + return new BigInteger((String) b); + } + + return (BigInteger) b; + } + + public static Float toFloat(Object f) { + if (f instanceof Float) { + return (Float) f; + } else if (f instanceof Number) { + return ((Number) f).floatValue(); + } + return f != null ? Float.parseFloat(f.toString()) : null; + } + + + public static Short toShort(Object s) { + if (s instanceof Short) { + return (Short) s; + } else if (s instanceof Number) { + return ((Number) s).shortValue(); + } + return s != null ? Short.parseShort(s.toString()) : null; + } + + + public static Byte toByte(Object b) { + if (b instanceof Byte) { + return (Byte) b; + } else if (b instanceof Number) { + return ((Number) b).byteValue(); + } + return b != null ? Byte.parseByte(b.toString()) : null; + } + + public static Boolean toBoolean(Object b) { + if (b instanceof Boolean) { + return (Boolean) b; + } else if (b == null) { + return null; + } + + // 支持 Number 之下的整数类型 + if (b instanceof Number) { + int n = ((Number) b).intValue(); + if (n == 1) { + return Boolean.TRUE; + } else if (n == 0) { + return Boolean.FALSE; + } + throw new IllegalArgumentException("Can not support convert: \"" + b + "\" to boolean."); + } + + // 支持 String + if (b instanceof String) { + String s = b.toString(); + if ("true".equalsIgnoreCase(s) || "1".equals(s)) { + return Boolean.TRUE; + } else if ("false".equalsIgnoreCase(s) || "0".equals(s)) { + return Boolean.FALSE; + } + } + + return (Boolean) b; + } + + public static Number toNumber(Object o) { + if (o instanceof Number) { + return (Number) o; + } else if (o == null) { + return null; + } + String s = o.toString(); + return s.indexOf('.') != -1 ? Double.parseDouble(s) : Long.parseLong(s); + } + + + public static Date toDate(Object o) { + if (o instanceof Date) { + return (Date) o; + } + + if (o instanceof Temporal) { + if (o instanceof LocalDateTime) { + return DateUtil.toDate((LocalDateTime) o); + } + if (o instanceof LocalDate) { + return DateUtil.toDate((LocalDate) o); + } + if (o instanceof LocalTime) { + return DateUtil.toDate((LocalTime) o); + } + } + + if (o instanceof String) { + String s = (String) o; + return DateUtil.parseDate(s); + } + + return (Date) o; + } + + + public static LocalDateTime toLocalDateTime(Object o) { + if (o instanceof LocalDateTime) { + return (LocalDateTime) o; + } + if (o instanceof Date) { + return DateUtil.toLocalDateTime((Date) o); + } + if (o instanceof LocalDate) { + return ((LocalDate) o).atStartOfDay(); + } + if (o instanceof LocalTime) { + return LocalDateTime.of(LocalDate.now(), (LocalTime) o); + } + + if (o instanceof String) { + String s = (String) o; + return DateUtil.parseLocalDateTime(s); + } + + return (LocalDateTime) o; + } +} diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java new file mode 100644 index 0000000..9572ca9 --- /dev/null +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.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.gitee.fastmybatis.core.util; + + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class DateUtil { + + private DateUtil() {} + + public static String datePatternWithoutDividing = "yyyyMMdd"; + public static String datePattern = "yyyy-MM-dd"; + public static final String dateMinutePattern = "yyyy-MM-dd HH:mm"; + public static final String dateMinutePattern2 = "yyyy-MM-dd'T'HH:mm"; + public static String datetimePattern = "yyyy-MM-dd HH:mm:ss"; + public static final String dateMillisecondPattern = "yyyy-MM-dd HH:mm:ss SSS"; + public static final String dateCSTPattern = "EEE MMM dd HH:mm:ss zzz yyyy"; + + private static final ThreadLocal> TL = ThreadLocal.withInitial(() -> new HashMap<>()); + + private static final Map dateTimeFormatters = new ConcurrentHashMap<>(); + + public static DateTimeFormatter getDateTimeFormatter(String pattern) { + DateTimeFormatter ret = dateTimeFormatters.get(pattern); + if (ret == null) { + ret = DateTimeFormatter.ofPattern(pattern); + dateTimeFormatters.put(pattern, ret); + } + return ret; + } + + public static SimpleDateFormat getSimpleDateFormat(String pattern) { + SimpleDateFormat ret = TL.get().get(pattern); + if (ret == null) { + if (dateCSTPattern.equals(pattern)) { + ret = new SimpleDateFormat(dateCSTPattern, Locale.US); + } else { + ret = new SimpleDateFormat(pattern); + } + TL.get().put(pattern, ret); + } + return ret; + } + + + public static Date parseDate(Object value) { + if (value instanceof Number) { + return new Date(((Number) value).longValue()); + } + if (value instanceof Timestamp) { + return new Date(((Timestamp) value).getTime()); + } + if (value instanceof LocalDate) { + return DateUtil.toDate((LocalDate) value); + } + if (value instanceof LocalDateTime) { + return DateUtil.toDate((LocalDateTime) value); + } + if (value instanceof LocalTime) { + return DateUtil.toDate((LocalTime) value); + } + String s = value.toString(); + if (StringUtil.isNumeric(s)) { + return new Date(Long.parseLong(s)); + } + return DateUtil.parseDate(s); + } + + + + public static Date parseDate(String dateString) { + if (StringUtil.isBlank(dateString)) { + return null; + } + dateString = dateString.trim(); + try { + SimpleDateFormat sdf = getSimpleDateFormat(getPattern(dateString)); + try { + return sdf.parse(dateString); + } catch (ParseException ex) { + //2022-10-23 00:00:00.0 + int lastIndexOf = dateString.lastIndexOf("."); + if (lastIndexOf == 19) { + return parseDate(dateString.substring(0, lastIndexOf)); + } + + //2022-10-23 00:00:00,0 + lastIndexOf = dateString.lastIndexOf(","); + if (lastIndexOf == 19) { + return parseDate(dateString.substring(0, lastIndexOf)); + } + + //2022-10-23 00:00:00 000123 + lastIndexOf = dateString.lastIndexOf(" "); + if (lastIndexOf == 19) { + return parseDate(dateString.substring(0, lastIndexOf)); + } + + if (dateString.contains(".") || dateString.contains("/")) { + dateString = dateString.replace(".", "-").replace("/", "-"); + return sdf.parse(dateString); + } else { + throw ex; + } + } + } catch (ParseException ex) { + throw new IllegalArgumentException("The date format is not supported for the date string: " + dateString); + } + } + + + + public static LocalDateTime parseLocalDateTime(String dateString) { + if (StringUtil.isBlank(dateString)) { + return null; + } + dateString = dateString.trim(); + DateTimeFormatter dateTimeFormatter = getDateTimeFormatter(getPattern(dateString)); + try { + return LocalDateTime.parse(dateString, dateTimeFormatter); + } catch (Exception ex) { + //2022-10-23 00:00:00.0 + int lastIndexOf = dateString.lastIndexOf("."); + if (lastIndexOf == 19) { + return parseLocalDateTime(dateString.substring(0, lastIndexOf)); + } + + //2022-10-23 00:00:00,0 + lastIndexOf = dateString.lastIndexOf(","); + if (lastIndexOf == 19) { + return parseLocalDateTime(dateString.substring(0, lastIndexOf)); + } + + //2022-10-23 00:00:00 000123 + lastIndexOf = dateString.lastIndexOf(" "); + if (lastIndexOf == 19) { + return parseLocalDateTime(dateString.substring(0, lastIndexOf)); + } + + if (dateString.contains(".") || dateString.contains("/")) { + dateString = dateString.replace(".", "-").replace("/", "-"); + dateTimeFormatter = getDateTimeFormatter(getPattern(dateString)); + return LocalDateTime.parse(dateString, dateTimeFormatter); + } else { + throw ex; + } + } + } + + + private static String getPattern(String dateString) { + int length = dateString.length(); + if (length == datetimePattern.length()) { + return datetimePattern; + } else if (length == datePattern.length()) { + return datePattern; + } else if (length == dateMinutePattern.length()) { + if (dateString.contains("T")) { + return dateMinutePattern2; + } + return dateMinutePattern; + } else if (length == dateMillisecondPattern.length()) { + return dateMillisecondPattern; + } else if (length == datePatternWithoutDividing.length()) { + return datePatternWithoutDividing; + } else if (length == dateCSTPattern.length()) { + return dateCSTPattern; + } else { + throw new IllegalArgumentException("The date format is not supported for the date string: " + dateString); + } + } + + + public static LocalDateTime toLocalDateTime(Date date) { + if (date == null) { + return null; + } + // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date + if (date instanceof java.sql.Date) { + date = new Date(date.getTime()); + } + + Instant instant = date.toInstant(); + ZoneId zone = ZoneId.systemDefault(); + return LocalDateTime.ofInstant(instant, zone); + } + + + public static LocalDate toLocalDate(Date date) { + if (date == null) { + return null; + } + // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date + if (date instanceof java.sql.Date) { + date = new Date(date.getTime()); + } + + Instant instant = date.toInstant(); + ZoneId zone = ZoneId.systemDefault(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); + return localDateTime.toLocalDate(); + } + + + public static LocalTime toLocalTime(Date date) { + if (date == null) { + return null; + } + // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date + if (date instanceof java.sql.Date) { + date = new Date(date.getTime()); + } + + Instant instant = date.toInstant(); + ZoneId zone = ZoneId.systemDefault(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); + return localDateTime.toLocalTime(); + } + + + public static Date toDate(LocalDateTime localDateTime) { + if (localDateTime == null) { + return null; + } + ZoneId zone = ZoneId.systemDefault(); + Instant instant = localDateTime.atZone(zone).toInstant(); + return Date.from(instant); + } + + + public static Date toDate(LocalDate localDate) { + if (localDate == null) { + return null; + } + ZoneId zone = ZoneId.systemDefault(); + Instant instant = localDate.atStartOfDay().atZone(zone).toInstant(); + return Date.from(instant); + } + + + public static Date toDate(LocalTime localTime) { + if (localTime == null) { + return null; + } + LocalDate localDate = LocalDate.now(); + LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); + ZoneId zone = ZoneId.systemDefault(); + Instant instant = localDateTime.atZone(zone).toInstant(); + return Date.from(instant); + } + + + public static String toDateTimeString(Date date) { + return toString(date, datetimePattern); + } + + + public static String toString(Date date, String pattern) { + return date == null ? null : getSimpleDateFormat(pattern).format(date); + } + + +} diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/StringUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/StringUtil.java index 8af0213..a924d7b 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/StringUtil.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/StringUtil.java @@ -128,4 +128,147 @@ public class StringUtil { } } + /** + * 第一个字符转换为小写 + * + * @param string + */ + public static String firstCharToLowerCase(String string) { + char firstChar = string.charAt(0); + if (firstChar >= 'A' && firstChar <= 'Z') { + char[] arr = string.toCharArray(); + arr[0] += ('a' - 'A'); + return new String(arr); + } + return string; + } + + + /** + * 第一个字符转换为大写 + * + * @param string + */ + public static String firstCharToUpperCase(String string) { + char firstChar = string.charAt(0); + if (firstChar >= 'a' && firstChar <= 'z') { + char[] arr = string.toCharArray(); + arr[0] -= ('a' - 'A'); + return new String(arr); + } + return string; + } + /** + * 驼峰转下划线格式 + * + * @param string + */ + public static String camelToUnderline(String string) { + if (isBlank(string)) { + return ""; + } + int strLen = string.length(); + StringBuilder sb = new StringBuilder(strLen); + for (int i = 0; i < strLen; i++) { + char c = string.charAt(i); + if (Character.isUpperCase(c) && i > 0) { + sb.append('_'); + } + sb.append(Character.toLowerCase(c)); + } + return sb.toString(); + } + + /** + * 下划线转驼峰格式 + * + * @param string + */ + public static String underlineToCamel(String string) { + if (isBlank(string)) { + return ""; + } + String temp = string.toLowerCase(); + int strLen = temp.length(); + StringBuilder sb = new StringBuilder(strLen); + for (int i = 0; i < strLen; i++) { + char c = temp.charAt(i); + if (c == '_') { + if (++i < strLen) { + sb.append(Character.toUpperCase(temp.charAt(i))); + } + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 字符串为 null 或者内部字符全部为 ' ', '\t', '\n', '\r' 这四类字符时返回 true + */ + public static boolean isBlank(String str) { + if (str == null) { + return true; + } + + for (int i = 0, len = str.length(); i < len; i++) { + if (str.charAt(i) > ' ') { + return false; + } + } + return true; + } + + + /** + * 这个字符串是否是全是数字 + * + * @param str + * @return + */ + public static boolean isNumeric(String str) { + if (isBlank(str)) { + return false; + } + for (int i = str.length(); --i >= 0; ) { + int chr = str.charAt(i); + if (chr < 48 || chr > 57) { + return false; + } + } + return true; + } + public static boolean startsWithAny(String str, String... prefixes) { + if (isBlank(str) || prefixes == null || prefixes.length == 0) { + return false; + } + + for (String prefix : prefixes) { + if (str.startsWith(prefix)) { + return true; + } + } + return false; + } + + + public static boolean endsWithAny(String str, String... suffixes) { + if (isBlank(str) || suffixes == null || suffixes.length == 0) { + return false; + } + + for (String suffix : suffixes) { + if (str.endsWith(suffix)) { + return true; + } + } + return false; + } + + + public static String trimOrNull(String string) { + return string != null ? string.trim() : null; + } + } diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/UpdateEntity.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/UpdateEntity.java new file mode 100644 index 0000000..8658346 --- /dev/null +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/UpdateEntity.java @@ -0,0 +1,23 @@ +package com.gitee.fastmybatis.core.util; + +import com.gitee.fastmybatis.core.FastmybatisContext; +import com.gitee.fastmybatis.core.update.ModifyAttrsRecordProxyFactory; + +public class UpdateEntity { + + private UpdateEntity() {} + + + + public static T of(Class clazz) { + return ModifyAttrsRecordProxyFactory.getInstance().get(clazz); + } + + public static T of(Class clazz, Object id) { + T newEntity = ModifyAttrsRecordProxyFactory.getInstance().get(clazz); + FastmybatisContext.setPkValue(newEntity,clazz,id); + return newEntity; + } + + +} diff --git a/fastmybatis-demo/fastmybatis-demo-springmvc/pom.xml b/fastmybatis-demo/fastmybatis-demo-springmvc/pom.xml index e50d3eb..8e9ad89 100644 --- a/fastmybatis-demo/fastmybatis-demo-springmvc/pom.xml +++ b/fastmybatis-demo/fastmybatis-demo-springmvc/pom.xml @@ -14,7 +14,7 @@ 1.8 - 5.3.15 + 5.2.15.RELEASE 1.9.7 1.7.33 1.2.79 diff --git a/fastmybatis-demo/fastmybatis-demo-springmvc/src/test/java/com/myapp/TUserMapperTest.java b/fastmybatis-demo/fastmybatis-demo-springmvc/src/test/java/com/myapp/TUserMapperTest.java index 77d5db7..a64e102 100644 --- a/fastmybatis-demo/fastmybatis-demo-springmvc/src/test/java/com/myapp/TUserMapperTest.java +++ b/fastmybatis-demo/fastmybatis-demo-springmvc/src/test/java/com/myapp/TUserMapperTest.java @@ -8,6 +8,7 @@ import com.gitee.fastmybatis.core.query.Query; import com.gitee.fastmybatis.core.query.Sort; import com.gitee.fastmybatis.core.query.annotation.Condition; import com.gitee.fastmybatis.core.query.expression.ValueExpression; +import com.gitee.fastmybatis.core.util.UpdateEntity; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.myapp.entity.TUser; @@ -506,6 +507,23 @@ public class TUserMapperTest extends TestBase { print("updateByQuery --> " + i);*/ } + + @Test + public void testForceUpdateById() { + TUser user = UpdateEntity.of(TUser.class,123L); + user.setUsername("李四"); + user.setRemark(null); + int i = mapper.forceUpdateById(user); + print("updateByQuery --> " + i); + + TUser user2 = UpdateEntity.of(TUser.class,123L); +// user.setUsername("李四"); + user2.setRemark(null); + int i2 = mapper.forceUpdateById(user2); + print("updateByQuery2 --> " + i2); + + } + @Test public void testListByPojo() { UserDTO param = new UserDTO(); -- Gitee From e704f61fc765a6e30a55d2b0e83c75e6702bd62d Mon Sep 17 00:00:00 2001 From: youbeiwuhuan Date: Thu, 13 Jul 2023 22:00:24 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B0=83=E7=94=A8getter?= =?UTF-8?q?=E5=92=8Csetter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fastmybatis/core/FastmybatisContext.java | 41 ++++++------------- .../fastmybatis/core/update/Reflectors.java | 17 ++++++++ 2 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/Reflectors.java diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java index 7467d01..aca7657 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/FastmybatisContext.java @@ -8,16 +8,15 @@ import com.gitee.fastmybatis.core.ext.spi.SpiContext; import com.gitee.fastmybatis.core.mapper.CrudMapper; import com.gitee.fastmybatis.core.mapper.Mapper; import com.gitee.fastmybatis.core.update.ModifyAttrsRecordProxyFactory; +import com.gitee.fastmybatis.core.update.Reflectors; import com.gitee.fastmybatis.core.update.UpdateWrapper; import com.gitee.fastmybatis.core.util.ClassUtil; import com.gitee.fastmybatis.core.util.ConvertUtil; -import com.gitee.fastmybatis.core.util.StringUtil; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.reflection.Reflector; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.*; /** @@ -148,21 +147,14 @@ public class FastmybatisContext { return null; } - Class idType = field.getType(); - Method setter = ClassUtil.findMethod(entityClass, "get" + StringUtil.firstCharToUpperCase(pkJavaName), null); - - if (setter == null) { - return null; - } - setter.setAccessible(true); + Reflector reflector = Reflectors.of(entityClass); try { - return setter.invoke(entity, null); - } catch (IllegalAccessException e) { - LOG.error("反射出错", e); - } catch (InvocationTargetException e) { - LOG.error("反射出错", e); + return reflector.getGetInvoker(field.getName()).invoke(entity, null); + } catch (Exception ignored) { + // do nothing here. } + return null; } @@ -178,21 +170,14 @@ public class FastmybatisContext { return; } - Class idType = field.getType(); - - Method setter = ClassUtil.findMethod(entityClass, "set" + StringUtil.firstCharToUpperCase(pkJavaName), new Class[]{idType}); - - if (setter == null) { - return; - } - setter.setAccessible(true); + Reflector reflector = Reflectors.of(entityClass); try { - setter.invoke(entity, new Object[]{ConvertUtil.convert(id, idType)}); - } catch (IllegalAccessException e) { - LOG.error("反射出错", e); - } catch (InvocationTargetException e) { - LOG.error("反射出错", e); + reflector.getSetInvoker(field.getName()).invoke(entity, new Object[]{ConvertUtil.convert(id, field.getType())}); + } catch (Exception ignored) { + // do nothing here. } + + } public static Set getIgnoreProperties(Class srcClass, Set includeProperties) { diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/Reflectors.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/Reflectors.java new file mode 100644 index 0000000..273a3df --- /dev/null +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/update/Reflectors.java @@ -0,0 +1,17 @@ + +package com.gitee.fastmybatis.core.update; + +import org.apache.ibatis.reflection.Reflector; +import org.apache.ibatis.util.MapUtil; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class Reflectors { + + private static final ConcurrentMap, Reflector> reflectorMap = new ConcurrentHashMap<>(); + + public static Reflector of(Class type){ + return MapUtil.computeIfAbsent(reflectorMap, type, Reflector::new); + } +} -- Gitee From d72254945d497f7870d2306b286a0a283041965b Mon Sep 17 00:00:00 2001 From: youbeiwuhuan Date: Thu, 13 Jul 2023 22:11:14 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gitee/fastmybatis/core/mapper/UpdateMapper.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java index 2b2465e..4bbd496 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/mapper/UpdateMapper.java @@ -6,7 +6,12 @@ import com.gitee.fastmybatis.core.update.ModifyAttrsRecordProxyFactory; import com.gitee.fastmybatis.core.update.UpdateWrapper; import org.apache.ibatis.annotations.Param; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; + /** * 具备更新功能的Mapper -- Gitee From aae786eb0abe2f768fa691771252d42cb42d5e12 Mon Sep 17 00:00:00 2001 From: youbeiwuhuan Date: Thu, 13 Jul 2023 22:11:29 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gitee/fastmybatis/core/util/ConvertUtil.java | 15 --------------- .../com/gitee/fastmybatis/core/util/DateUtil.java | 15 --------------- 2 files changed, 30 deletions(-) diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java index ebd639a..2fd29fd 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/ConvertUtil.java @@ -1,18 +1,3 @@ -/* - * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.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.gitee.fastmybatis.core.util; import java.math.BigDecimal; diff --git a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java index 9572ca9..fd63928 100644 --- a/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java +++ b/fastmybatis-core/src/main/java/com/gitee/fastmybatis/core/util/DateUtil.java @@ -1,18 +1,3 @@ -/* - * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.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.gitee.fastmybatis.core.util; -- Gitee