首先查看两个版本this.setFieldValByName(MetaObjectHandler类中的方法)的源码
Mybatis-plus(3.0.5):
public interface MetaObjectHandler {
void insertFill(MetaObject var1);
void updateFill(MetaObject var1);
default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)) {
metaObject.setValue(fieldName, fieldVal);
} else if (metaObject.hasGetter("et")) {
Object et = metaObject.getValue("et");
if (et != null) {
MetaObject etMeta = SystemMetaObject.forObject(et);
if (etMeta.hasSetter(fieldName)) {
etMeta.setValue(fieldName, fieldVal);
}
}
}
return this;
}
default Object getFieldValByName(String fieldName, MetaObject metaObject) {
if (metaObject.hasGetter(fieldName)) {
return metaObject.getValue(fieldName);
} else {
return metaObject.hasGetter("et." + fieldName) ? metaObject.getValue("et." + fieldName) : null;
}
}
default boolean openInsertFill() {
return true;
}
default boolean openUpdateFill() {
return true;
}
}
Mybatis-plus(3.4.2):
public interface MetaObjectHandler {
default boolean openInsertFill() {
return true;
}
default boolean openUpdateFill() {
return true;
}
void insertFill(MetaObject metaObject);
void updateFill(MetaObject metaObject);
default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
if (Objects.nonNull(fieldVal) && metaObject.hasSetter(fieldName)) {
metaObject.setValue(fieldName, fieldVal);
}
return this;
}
default Object getFieldValByName(String fieldName, MetaObject metaObject) {
return metaObject.hasGetter(fieldName) ? metaObject.getValue(fieldName) : null;
}
我也看不是很懂,但能知道的是新老版本中metaObject.setValue()方法明显有差别,自己理解差别所在
先说另外一个区别:
我们都知道要使用自动填充需要在字段上加入以下两个注解
@TableField(fill = FieldFill.INSERT)
@TableField(fill = FieldFill.INSERT_UPDATE)
但经过调试发现3.0.5版本中在进行插入和删除操作时无论是否加有注解都会进入到定义自动填充类中去比对,如果有,则会进行填充处理
而3.4.2版本中如果没有注解则不会进入到方法中
下面说下遇到的问题:
在使用3.0.5版本中用metaObject.setValue()方法来自动填充时发现,如果插入和修改操作的表里没有自己定义的需要填充的字段的话该方法也会填充,并在sql语句拼接,然而数据库中并没有该字段,所以就会报错.但如果使用this.setFieldValByName() 方法则不会报错。原理参考源码中两者关系.
如果换成3.4.2版本,则上述问题不会遇到,两种方法均可.因为字段中没有注解根本就不会进入该方法中/
综上所述,metaObject.setValue()方法可以看成this.setFieldValByName()的子方法
所以使用this.setFieldValByName()方法更佳