MyBatisPlus 使用 saveOrUpdate()的正确姿势

8,407 阅读1分钟

使用MyBatisPlus的时候,有这样的一个需求,如果有某某个字段的值重复,则更新操作,否则插入!

看了下mybatis-Plus有个saveOrUpdate方法,应该是好使的,用了下就报错

com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: error: can not execute. because can not find column for id from entity!

大概意思是,它找不到那个是主键,因为它默认是按主键执行操作的!

排查流程

image-20231010120930249.png

所以需要在我们bean里面声明主键字段,@TableId(value = "id", type = IdType.AUTO)。

image-20231010121114731.png

我们继续看源码红框下面的一行,获取主键的值idVal,继续下面的判断如果idVal不为空,会执行 this.getById操作,通过主键id查询记录,所以此时我们应该意识到, 主键id一定要使用封装类型,而非基本类型,实际上我们在定义对外POJO的时候尽量都使用封装类型,避免转换默认值。

按照上述就可以使用了。

实际场景中可能我们不是按照主键去重的,例如用户信息对象,根据userId条件过滤,我们可以使用saveOrUpdate的另一个构造方法,saveOrUpdate(T entity, Wrapper updateWrapper),

image-20231010134111193.png 通过源码可以看到,先按照updateWrapper条件执行了update操作,如果成功直接返回,然后没有更新成功,再次只执行this.saveOrUpdate(entity)。

如果entity 主键id不为空,还会在执行this.getById(Serializable id),如果没有查询到接口在执行insert操作

注意事项

  • 主键id最好封装类型或String
  • 按照条件过滤,updateWrapper 不需要设置set参数
  • 执行entity对象的主键字段