MybatisPlus 使用 saveOrUpdate 详解(慎用),及问题解决方法&mysql保存或更新 ON DUPLICATE KEY UPDATE

您所在的位置:网站首页 key效果怎么样 MybatisPlus 使用 saveOrUpdate 详解(慎用),及问题解决方法&mysql保存或更新 ON DUPLICATE KEY UPDATE

MybatisPlus 使用 saveOrUpdate 详解(慎用),及问题解决方法&mysql保存或更新 ON DUPLICATE KEY UPDATE

2024-07-12 09:58| 来源: 网络整理| 查看: 265

今天的想法是,要在插入数据库时,如果有某某一个主要字段的值重复,则不插入,否则则插入! 看了一下mybatis-Plus是有这个saveOrUpdate 方法!

原本使用save时是没有问题了,改成saveOrUpdate 用了一下就报错了。

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

就是这个mybatisPlus不能找到哪个是主键字段,因为这个saveOrUpdate默认是根据主键执行操作的!

所有需要在原本的实体类的主键头上,打个@TableId,如下,后面是对应数据库的字段,已经主键自动递增。

@Data @AllArgsConstructor @NoArgsConstructor public class Subject { @TableId(value = "subject_Code", type = IdType.AUTO) private long subjectCode; private String subjectNameCn; private String subjectNameEn; private String subjectHref; private long subjectParentCode; private long levelCode; private int isDelete; private long operateTimestamp; }

不过还有个问题,就是这个是根据主键做操作的,但是我主键本来就是自动递增肯定不会有问题的,接下来就是想个办法,让他根据指定字段做操作,好像是有提供了一个口子。

// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法 boolean saveOrUpdate(T entity, Wrapper updateWrapper);

我再去看一下怎么操作的!

研究尝试了半天,终于搞出来了,可能是很少有人会像我这样做吧!所以我自己尝试了下。

当saveOrUpdate不使用条件构造器时,会先做根据主键查询,如果查出来的结果为0,那么就执行插入操作,如果查出来的结果不为0,则执行更新操作。

但是一般情况下,主键都不会重复啊!所有我就用条件构造器Wrapper!

UpdateWrapper subject_name_cn = new UpdateWrapper() .eq("subject_Name_Cn", subjectNameCn); subjectService.saveOrUpdate(subject,subject_name_cn );

这样改变后的结果就是会先执行修改,如果执行一条,则执行成功,如果执行结果为0,再执行根据主键查询,然后做插入操作!

其实有点多此一举的感觉,因为既然都已经更新不到结果了,那么肯定是没有这个字段咯!

不过转念一想,你是指定字段没有,又不是主键没有!

但是主键自增那肯定没有啊!

所有我又想到一个骚操作,我不传UpdateWrapper而传QueryWrapper会怎么样呢!

会不会加在查询条件种呢!我丢进去没有报错,有点小激动,不知道结果如何!

QueryWrapper subject_name_cn1 = new QueryWrapper() .eq("subject_Name_Cn", subjectNameCn); subjectService.saveOrUpdate(subject,subject_name_cn1);

好吧!上来全给我Update了!丝毫不留情面!我把数据删了再试试!

好吧!然并卵!幻想破灭!跟传UpdateWrapper没有区别!~告辞!

看了一下源码,默认参数是Wrapper类型,然后根据条件构造器更新,

成功则返回,

不成功则走无条件构造器的方法。

default boolean saveOrUpdate(T entity, Wrapper updateWrapper) { return this.update(entity, updateWrapper) || this.saveOrUpdate(entity); }

我感觉应该加个类型判断!

if(updateWrapper instanceof QueryWrapper){ 去拼接查询语句! } if(updateWrapper instanceof UpdateWrapper){ 去拼接更新语句! }

这样就不会只根据ID来死查了!

我才终于明白~

为什么要用updateWrapper了!

它与queryWrapper的区别就是。

updateWrapper用set来设置修改的数据。

queryWrapper应用select来设置要查出来的数据。

哈哈,这个还是很重要的!

saveOrUpdate 是否有映射id

我们知道mybatis在插入时,会映射id,但是如果是saveOrUpdate会怎么样呢?

比如我saveOrUpdate()后,需要用他的id,但是我传进去的对象是没有id的。

@Test void saveOrUpdate(){ UserText userText = new UserText(); userText.setUserSex(Sex.MAN); boolean b = userTextService.saveOrUpdate(userText); System.out.println(userText.getUserId()); }

可以看到他先通过id查了没有再进行插入,然后返回新的id。

==> Preparing: SELECT user_id,user_name,user_sex,start_time FROM user_text WHERE user_id=? ==> Parameters: 0(Long) Preparing: INSERT INTO user_text ( user_sex ) VALUES ( ? ) ==> Parameters: 1(Integer)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3