慕斯3111050
2020-03-18 12:24
老师,按照教程,我在代码中,在insertFill和updateFill中都对要自动填充的字段进行了判断如下
@Override public void insertFill(MetaObject metaObject) { if (metaObject.hasSetter("createTime")) { log.info("自动插入"); LocalDateTime current = LocalDateTime.now(); this.setInsertFieldValByName("createTime", current, metaObject); } } @Override public void updateFill(MetaObject metaObject) { if (metaObject.hasSetter("updateTime")) { log.info("自动更新字段"); LocalDateTime current = LocalDateTime.now(); this.setUpdateFieldValByName("updateTime", current, metaObject); } }
经过debug发现,metaObject.hasSetter在insert时,底层调用的是BeanWrapper.hasSetter的方法,能判断是否包含了要设置的字段。
但是在update时,底层调用的是MapWrapper.hasSetter方法,这个方法直接返回true,并不判断是否包含要设置的字段,导致自动metaObject.hasSetter的判断不起作用,如下是debug截图。
我使用的mp版本是3.2.0。更新时调用的方法是updateById,不明白为什么在更新时没有调用BeanWrapper方法,而是调用MapWrapper
同学,你使用3.3.1.tmp版本试试,看看好不好使,我使用这个版本,debug时,看着调用的是BeanWrapper。
Object time = getFieldValByName("createTime", metaObject);
和
Object time = getFieldValByName("updateTime", metaObject);
在用法上没有区别,是可以使用的
老铁,你说的没错,可能这是官方的bug吧,我首先debug了
boolean updateTime = metaObject.hasSetter("updateTime");
发现走的是MapWrapper.class中的代码:
public boolean hasSetter(String name) { return true; }
直接返回的就是true,而debug以下代码的时候:
boolean createTime = metaObject.hasSetter("createTime");
发现走的是BeanWrapper.class中的代码:
public boolean hasSetter(String name) { PropertyTokenizer prop = new PropertyTokenizer(name); if (prop.hasNext()) { ………… } else { return this.metaClass.hasSetter(name); } }
所以添加
@TableField(fill = FieldFill.INSERT)
和
@TableField(fill = FieldFill.UPDATE)
他们走的判断路径都不一样
你的实体类上的注解是不是没有
@TableField(fill = FieldFill.INSERT_UPDATE ) private Date time;
你如果就是insert肯定没用啊
MyBatis-Plus进阶
23311 学习 · 118 问题
相似问题