瀏覽代碼

fix #IOW4E

Caratacus 6 年之前
父節點
當前提交
e8e690d34e

+ 24 - 10
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisDefaultParameterHandler.java

@@ -15,12 +15,20 @@
  */
 package com.baomidou.mybatisplus.core;
 
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-import com.baomidou.mybatisplus.core.metadata.TableInfo;
-import com.baomidou.mybatisplus.core.toolkit.*;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.ibatis.executor.ErrorContext;
-import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.apache.ibatis.mapping.ParameterMode;
+import org.apache.ibatis.mapping.SqlCommandType;
 import org.apache.ibatis.reflection.MetaObject;
 import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
 import org.apache.ibatis.session.Configuration;
@@ -29,9 +37,15 @@ import org.apache.ibatis.type.TypeException;
 import org.apache.ibatis.type.TypeHandler;
 import org.apache.ibatis.type.TypeHandlerRegistry;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.*;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
 
 /**
  * <p>
@@ -195,10 +209,10 @@ public class MybatisDefaultParameterHandler extends DefaultParameterHandler {
         if (metaObjectHandler != null) {
             if (isInsert && metaObjectHandler.openInsertFill()) {
                 // 插入填充
-                metaObjectHandler.insertFill(metaObject);
+                metaObjectHandler.insertFill(metaObject, FieldFill.INSERT);
             } else if (!isInsert) {
                 // 更新填充
-                metaObjectHandler.updateFill(metaObject);
+                metaObjectHandler.updateFill(metaObject, FieldFill.UPDATE);
             }
         }
         return metaObject.getOriginalObject();

+ 44 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/handlers/MetaObjectHandler.java

@@ -16,11 +16,16 @@
 package com.baomidou.mybatisplus.core.handlers;
 
 import java.util.Objects;
+import java.util.Optional;
 
 import org.apache.ibatis.reflection.MetaObject;
 import org.apache.ibatis.reflection.SystemMetaObject;
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
 
 /**
  * <p>
@@ -32,19 +37,30 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
  */
 public interface MetaObjectHandler {
 
+    /**
+     * 乐观锁常量
+     */
+    String MP_OPTLOCK_ET_ORIGINAL = "MP_OPTLOCK_ET_ORIGINAL";
+
     /**
      * 插入元对象字段填充(用于插入时对公共字段的填充)
      *
      * @param metaObject 元对象
+     * @param fieldFill  填充策略枚举 3.0.7添加,之前版本升级传递该参数至MetaObjectHandler#setFieldValByName
+     * @see com.baomidou.mybatisplus.core.handlers.MetaObjectHandler#setFieldValByName
+     * @since 3.0.7
      */
-    void insertFill(MetaObject metaObject);
+    void insertFill(MetaObject metaObject, FieldFill fieldFill);
 
     /**
      * 更新元对象字段填充(用于更新时对公共字段的填充)
      *
      * @param metaObject 元对象
+     * @param fieldFill  填充策略枚举 3.0.7添加,之前版本升级传递该参数至MetaObjectHandler#setFieldValByName
+     * @see com.baomidou.mybatisplus.core.handlers.MetaObjectHandler#setFieldValByName
+     * @since 3.0.7
      */
-    void updateFill(MetaObject metaObject);
+    void updateFill(MetaObject metaObject, FieldFill fieldFill);
 
     /**
      * <p>
@@ -57,16 +73,18 @@ public interface MetaObjectHandler {
      * @param fieldName  java bean property name
      * @param fieldVal   java bean property value
      * @param metaObject meta object parameter
+     * @param fieldFill  填充策略枚举
+     * @since 3.0.7
      */
-    default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
-        if(Objects.nonNull(fieldVal)){
-            if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)) {
+    default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject, FieldFill fieldFill) {
+        if (Objects.nonNull(fieldVal)) {
+            if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName) && isFill(fieldName, metaObject, fieldFill)) {
                 metaObject.setValue(fieldName, fieldVal);
             } else if (metaObject.hasGetter(Constants.ENTITY)) {
                 Object et = metaObject.getValue(Constants.ENTITY);
                 if (et != null) {
                     MetaObject etMeta = SystemMetaObject.forObject(et);
-                    if (etMeta.hasSetter(fieldName)) {
+                    if (etMeta.hasSetter(fieldName) && isFill(fieldName, etMeta, fieldFill)) {
                         etMeta.setValue(fieldName, fieldVal);
                     }
                 }
@@ -96,6 +114,26 @@ public interface MetaObjectHandler {
         return null;
     }
 
+    /**
+     * 是否填充
+     *
+     * @param fieldName  字段名
+     * @param metaObject
+     * @param fieldFill  填充策略
+     * @return
+     */
+    default boolean isFill(String fieldName, MetaObject metaObject, FieldFill fieldFill) {
+        TableInfo tableInfo = metaObject.hasGetter(MP_OPTLOCK_ET_ORIGINAL) ? TableInfoHelper.getTableInfo(metaObject.getValue(MP_OPTLOCK_ET_ORIGINAL).getClass()) : TableInfoHelper.getTableInfo(metaObject.getOriginalObject().getClass());
+        if (Objects.nonNull(tableInfo)) {
+            Optional<TableFieldInfo> first = tableInfo.getFieldList().stream().filter(e -> e.getProperty().equals(fieldName)).findFirst();
+            if (first.isPresent()) {
+                FieldFill fill = first.get().getFieldFill();
+                return fill.equals(fieldFill) || FieldFill.INSERT_UPDATE.equals(fill);
+            }
+        }
+        return false;
+    }
+
     /**
      * 是否开启了插入填充
      */

+ 7 - 6
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2MetaObjectHandler.java

@@ -19,6 +19,7 @@ import java.sql.Timestamp;
 
 import org.apache.ibatis.reflection.MetaObject;
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 
 
@@ -36,7 +37,7 @@ public class H2MetaObjectHandler implements MetaObjectHandler {
      * 测试 user 表 name 字段为空自动填充
      */
     @Override
-    public void insertFill(MetaObject metaObject) {
+    public void insertFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("insert fill");
         System.out.println("*************************");
@@ -46,19 +47,19 @@ public class H2MetaObjectHandler implements MetaObjectHandler {
         System.out.println("testType=" + testType);
         if (testType == null) {
             //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-            this.setFieldValByName("testType1", 3, metaObject);
-            this.setFieldValByName("testType", 3, metaObject);
+            this.setFieldValByName("testType1", 3, metaObject, fieldFill);
+            this.setFieldValByName("testType", 3, metaObject, fieldFill);
         }
     }
 
     @Override
-    public void updateFill(MetaObject metaObject) {
+    public void updateFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("update fill");
         System.out.println("*************************");
         //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-        this.setFieldValByName("lastUpdatedDt1", new Timestamp(System.currentTimeMillis()), metaObject);
-        this.setFieldValByName("lastUpdatedDt", new Timestamp(System.currentTimeMillis()), metaObject);
+        this.setFieldValByName("lastUpdatedDt1", new Timestamp(System.currentTimeMillis()), metaObject, fieldFill);
+        this.setFieldValByName("lastUpdatedDt", new Timestamp(System.currentTimeMillis()), metaObject, fieldFill);
     }
 }
 

+ 10 - 8
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/mysql/MysqlMetaObjectHandler.java

@@ -15,10 +15,12 @@
  */
 package com.baomidou.mybatisplus.test.mysql;
 
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import java.time.LocalDateTime;
+
 import org.apache.ibatis.reflection.MetaObject;
 
-import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 
 /**
  * <p>
@@ -34,7 +36,7 @@ public class MysqlMetaObjectHandler implements MetaObjectHandler {
      * 测试 user 表 name 字段为空自动填充
      */
     @Override
-    public void insertFill(MetaObject metaObject) {
+    public void insertFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("insert of mysql fill");
         System.out.println("*************************");
@@ -43,19 +45,19 @@ public class MysqlMetaObjectHandler implements MetaObjectHandler {
         System.out.println("createDatetime=" + createDatetime);
         if (createDatetime == null) {
             //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-            this.setFieldValByName("createDatetime1", LocalDateTime.now(), metaObject)
-                .setFieldValByName("createDatetime", LocalDateTime.now(), metaObject);
+            this.setFieldValByName("createDatetime1", LocalDateTime.now(), metaObject, fieldFill)
+                .setFieldValByName("createDatetime", LocalDateTime.now(), metaObject, fieldFill);
         }
     }
 
     @Override
-    public void updateFill(MetaObject metaObject) {
+    public void updateFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("update of mysql fill");
         System.out.println("*************************");
         //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-        this.setFieldValByName("updateDatetime1", LocalDateTime.now(), metaObject)
-            .setFieldValByName("updateDatetime", LocalDateTime.now(), metaObject);
+        this.setFieldValByName("updateDatetime1", LocalDateTime.now(), metaObject, fieldFill)
+            .setFieldValByName("updateDatetime", LocalDateTime.now(), metaObject, fieldFill);
     }
 }
 

+ 10 - 8
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/postgres/PostgresMetaObjectHandler.java

@@ -15,10 +15,12 @@
  */
 package com.baomidou.mybatisplus.test.postgres;
 
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import java.time.LocalDateTime;
+
 import org.apache.ibatis.reflection.MetaObject;
 
-import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 
 /**
  * <p>
@@ -34,7 +36,7 @@ public class PostgresMetaObjectHandler implements MetaObjectHandler {
      * 测试 user 表 name 字段为空自动填充
      */
     @Override
-    public void insertFill(MetaObject metaObject) {
+    public void insertFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("insert of postgres fill");
         System.out.println("*************************");
@@ -43,19 +45,19 @@ public class PostgresMetaObjectHandler implements MetaObjectHandler {
         System.out.println("createDatetime=" + createDatetime);
         if (createDatetime == null) {
             //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-            this.setFieldValByName("createDatetime1", LocalDateTime.now(), metaObject)
-                .setFieldValByName("createDatetime", LocalDateTime.now(), metaObject);
+            this.setFieldValByName("createDatetime1", LocalDateTime.now(), metaObject, fieldFill)
+                .setFieldValByName("createDatetime", LocalDateTime.now(), metaObject, fieldFill);
         }
     }
 
     @Override
-    public void updateFill(MetaObject metaObject) {
+    public void updateFill(MetaObject metaObject, FieldFill fieldFill) {
         System.out.println("*************************");
         System.out.println("update of postgres fill");
         System.out.println("*************************");
         //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-        this.setFieldValByName("updateDatetime1", LocalDateTime.now(), metaObject)
-            .setFieldValByName("updateDatetime", LocalDateTime.now(), metaObject);
+        this.setFieldValByName("updateDatetime1", LocalDateTime.now(), metaObject, fieldFill)
+            .setFieldValByName("updateDatetime", LocalDateTime.now(), metaObject, fieldFill);
     }
 }