Browse Source

feat: v_2.3.4自动填充完善
增加新方法:setInsertFieldValByName/setUpdateFieldValByName
不推荐老方法setFieldValByName

yuxiaobin 6 years ago
parent
commit
413889480f

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

@@ -44,8 +44,11 @@ public class H2MetaObjectHandler extends MetaObjectHandler {
         System.out.println("testType=" + testType);
         if (testType == null) {
             //测试实体没有的字段,配置在公共填充,不应该set到实体里面
-            this.setFieldValByName("testType1", 3, metaObject);
-            this.setFieldValByName("testType", 3, metaObject);
+            this.setInsertFieldValByName("testType1", 3, metaObject);
+            int b =3;
+            this.setInsertFieldValByName("testType", b, metaObject);
+            Integer a = 3;
+            this.setInsertFieldValByName("testType", a, metaObject);
         }
     }
 
@@ -55,8 +58,8 @@ public class H2MetaObjectHandler extends MetaObjectHandler {
         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.setUpdateFieldValByName("lastUpdatedDt1", new Timestamp(System.currentTimeMillis()), metaObject);
+        this.setUpdateFieldValByName("lastUpdatedDt", new Timestamp(System.currentTimeMillis()), metaObject);
     }
 }
 

+ 2 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/h2/entity/persistent/H2UserVersionAndLogicDeleteEntity.java

@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.annotations.TableField;
 import com.baomidou.mybatisplus.annotations.TableLogic;
 import com.baomidou.mybatisplus.annotations.TableName;
 import com.baomidou.mybatisplus.annotations.Version;
+import com.baomidou.mybatisplus.enums.FieldFill;
 import com.baomidou.mybatisplus.enums.FieldStrategy;
 import com.baomidou.mybatisplus.test.h2.entity.SuperEntity;
 
@@ -59,7 +60,7 @@ public class H2UserVersionAndLogicDeleteEntity extends SuperEntity implements Se
     private BigDecimal price;
 
     /* 测试下划线字段命名类型, 字段填充 */
-    @TableField(value = "test_type", strategy = FieldStrategy.IGNORED)
+    @TableField(value = "test_type", strategy = FieldStrategy.IGNORED, fill = FieldFill.INSERT)
     private Integer testType;
 
     private String desc;

+ 102 - 8
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/mapper/MetaObjectHandler.java

@@ -18,6 +18,11 @@ package com.baomidou.mybatisplus.mapper;
 import org.apache.ibatis.reflection.MetaObject;
 import org.apache.ibatis.reflection.SystemMetaObject;
 
+import com.baomidou.mybatisplus.entity.TableFieldInfo;
+import com.baomidou.mybatisplus.entity.TableInfo;
+import com.baomidou.mybatisplus.enums.FieldFill;
+import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
+
 /**
  * <p>
  * 元对象字段填充控制器抽象类,实现公共字段自动写入
@@ -29,6 +34,10 @@ import org.apache.ibatis.reflection.SystemMetaObject;
 public abstract class MetaObjectHandler {
 
     protected static final String META_OBJ_PREFIX = "et";
+    /**
+     * 乐观锁常量
+     */
+    String MP_OPTLOCK_ET_ORIGINAL = "MP_OPTLOCK_ET_ORIGINAL";
 
     /**
      * <p>
@@ -58,19 +67,74 @@ public abstract class MetaObjectHandler {
      * 如果包含前缀 et 使用该方法,否则可以直接 metaObject.setValue(fieldName, fieldVal);
      * </p>
      *
+     * 从2.3.4版本开始,调用了
+     * {@link #setInsertFieldValByName(String, Object, MetaObject)} / {@link #setUpdateFieldValByName(String, Object, MetaObject)}
+     * 这2个方法时需注意:只有注解了fill = FieldFill.INSERT/UPDATE/INSERT_UPDATE的字段,才会自动填充。
+     * 当前这个方法不推荐使用,因为不论是否有fill,都会被自动填充
+     *
      * @param fieldName  java bean property name
      * @param fieldVal   java bean property value
      * @param metaObject meta object parameter
+     * @deprecated since 2.3.4, refer to {@link #setInsertFieldValByName(String, Object, MetaObject)} / {@link #setUpdateFieldValByName(String, Object, MetaObject)}
      */
+    @Deprecated
     public MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
-        if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)) {
-            metaObject.setValue(fieldName, fieldVal);
-        } else if (metaObject.hasGetter(META_OBJ_PREFIX)) {
-            Object et = metaObject.getValue(META_OBJ_PREFIX);
-            if (et != null) {
-                MetaObject etMeta = SystemMetaObject.forObject(et);
-                if (etMeta.hasSetter(fieldName)) {
-                    etMeta.setValue(fieldName, fieldVal);
+        if (fieldVal != null) {
+            if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)) {
+                metaObject.setValue(fieldName, fieldVal);
+            } else if (metaObject.hasGetter(META_OBJ_PREFIX)) {
+                Object et = metaObject.getValue(META_OBJ_PREFIX);
+                if (et != null) {
+                    MetaObject etMeta = SystemMetaObject.forObject(et);
+                    if (etMeta.hasSetter(fieldName)) {
+                        etMeta.setValue(fieldName, fieldVal);
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Recommend to invoke {@code setInsertFieldValByName()} when auto fill for INSERT.
+     * 在INSERT时的自动填充,推荐使用{@code setInsertFieldValByName()}
+     *
+     * @param fieldName
+     * @param fieldVal
+     * @param metaObject
+     * @return
+     * @since 2.3.4
+     */
+    public MetaObjectHandler setInsertFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
+        return setFieldValByName(fieldName, fieldVal, metaObject, FieldFill.INSERT);
+    }
+
+    /**
+     * Recommend to invoke {@code setUpdateFieldValByName()} when auto fill for UPDATE.
+     * 在UPDATE时的自动填充,推荐使用{@code setUpdateFieldValByName()}
+     *
+     * @param fieldName
+     * @param fieldVal
+     * @param metaObject
+     * @return
+     * @since 2.3.4
+     */
+    public MetaObjectHandler setUpdateFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
+        return setFieldValByName(fieldName, fieldVal, metaObject, FieldFill.UPDATE);
+    }
+
+    public MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject, FieldFill fieldFill) {
+        if (fieldVal != null) {
+            if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)
+                && isFill(fieldName, fieldVal, metaObject, fieldFill)) {
+                metaObject.setValue(fieldName, fieldVal);
+            } else if (metaObject.hasGetter(META_OBJ_PREFIX)) {
+                Object et = metaObject.getValue(META_OBJ_PREFIX);
+                if (et != null) {
+                    MetaObject etMeta = SystemMetaObject.forObject(et);
+                    if (etMeta.hasSetter(fieldName) && isFill(fieldName, fieldVal, etMeta, fieldFill)) {
+                        etMeta.setValue(fieldName, fieldVal);
+                    }
                 }
             }
         }
@@ -98,6 +162,36 @@ public abstract class MetaObjectHandler {
         return null;
     }
 
+    /**
+     * 填充判断
+     * <li> 如果是主键,不填充 </li>
+     * <li> 根据字段名找不到字段,不填充 </li>
+     * <li> 字段类型与填充值类型不匹配,不填充 </li>
+     * <li> 如果该字段没有注解配置FILL, 不填充 </li>
+     *
+     * @param fieldName  java bean property name
+     * @param fieldVal   java bean property value
+     * @param metaObject meta object parameter
+     * @param fieldFill  填充策略枚举
+     * @return 是否进行填充
+     * @since 2.3.4
+     */
+    protected boolean isFill(String fieldName, Object fieldVal, 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 (tableInfo != null) {
+            for (TableFieldInfo e : tableInfo.getFieldList()) {
+                if (e.getProperty().equals(fieldName)
+                    && e.getPropertyType().isAssignableFrom(fieldVal.getClass())) {//设置子类的值也可以通过
+                    FieldFill fill = e.getFieldFill();
+                    return fill.equals(fieldFill) || FieldFill.INSERT_UPDATE.equals(fill);
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * 开启插入填充
      */