MyBatis 怎么实现SaveOrUpdate

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis 怎么实现SaveOrUpdate相关的知识,希望对你有一定的参考价值。

因为现在要做批量更新操作,且无法确定数据库中是否存在要更新的记录,若不存在则用save,存在则用update,难道每条记录更新前先查一次数据库?

参考技术A 保存返回到插入张扬的数据saveOrUpdate无效
保存方法更适合插入的决心,需要插入到数据和主键

saveOrUpdate更倾向于缺乏插入或更新,而你不并不需要得到主键

另一方面,如果你不知道你要插入或更新对象不是持久性的状态或游离状态。如果保存持久状态或更新一个自由状态,这是一个问题,那么你必须使用saveOrUpdate

总的来说,如果你能确定你将要操作的对象的状态,没有saveOrUpdate本回答被提问者采纳

MyBatis实现SaveOrUpdate

这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现。

例子

<insert id="saveOrUpdate" >
  <selectKey keyProperty="count" resultType="int" order="BEFORE">
    select count(*) from country where id = #{id}
  </selectKey>
  <if test="count > 0">
    update country 
    set countryname = #{countryname},countrycode = #{countrycode} 
    where id = #{id}
  </if>
  <if test="count==0">
    insert into country values(#{id},#{countryname},#{countrycode})
  </if>
</insert>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

条件限制

根据不同的判断逻辑,会有所不同,就上面这个例子而言,就要求实体类中包含count属性(可以是别的名字)。否则selectKey的结果没法保存,如果入参是个Map类型,就没有这个限制。

说明

从例子来看除了有个限制外,也没别的麻烦。

通过selectKey做第一次查询,然后根据结果进行判断,所以这里的order="BEFORE"是必须的。

也是因为BEFORE,所以没法通过<bind>标签来临时存储中间的值,只能在入参中增加属性来存放。

测试代码

//数据库中已经存在该ID,但是countryname=China
Country country = new Country();
country.setId(35);
country.setCountryname("中国");
country.setCountrycode("CN");
//由于存在,这里会update
int result = countryMapper.saveOrUpdate(country);

//查询结果,判断是否已经改变
Country c2 = countryMapper.selectById(35);
assertEquals("中国",c2.getCountryname());

//id=300的不存在
c2 = countryMapper.selectById(300);
assertNull(c2);

//将id=300
country.setId(300);
//由于id=300不存在,这里会Insert
result = countryMapper.saveOrUpdate(country);

//查询结果
c2 = countryMapper.selectById(300);
assertNotNull(c2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

输出日志

DEBUG ==>  Preparing: select count(*) from country where id = ? 
DEBUG ==> Parameters: 35(Integer)
TRACE <==    Columns: C1
TRACE <==        Row: 1
DEBUG <==      Total: 1
DEBUG ==>  Preparing: update country set countryname = ?,countrycode = ? where id = ? 
DEBUG ==> Parameters: 中国(String), CN(String), 35(Integer)
DEBUG <==    Updates: 1
DEBUG ==>  Preparing: select * from country where id = ? 
DEBUG ==> Parameters: 35(Integer)
TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODE
TRACE <==        Row: 35, 中国, CN
DEBUG <==      Total: 1
DEBUG ==>  Preparing: select * from country where id = ? 
DEBUG ==> Parameters: 300(Integer)
DEBUG <==      Total: 0
DEBUG ==>  Preparing: select count(*) from country where id = ? 
DEBUG ==> Parameters: 300(Integer)
TRACE <==    Columns: C1
TRACE <==        Row: 0
DEBUG <==      Total: 1
DEBUG ==>  Preparing: insert into country values(?,?,?) 
DEBUG ==> Parameters: 300(Integer), 中国(String), CN(String)
DEBUG <==    Updates: 1
DEBUG ==>  Preparing: select * from country where id = ? 
DEBUG ==> Parameters: 300(Integer)
TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODE
TRACE <==        Row: 300, 中国, CN
DEBUG <==      Total: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

最后

这种方式只是利用了selectKey会多执行一次查询来实现的,但是如果你同时还需要通过selectKey获取序列或者自增的id,就会麻烦很多(Oracle麻烦,其他支持自增的还是很容易)。

建议在复杂情况下,还是选择在Service中实现更好。

MyBatis工具:www.mybatis.tk

http://blog.csdn.net/isea533/article/details/45578415

 

以上是关于MyBatis 怎么实现SaveOrUpdate的主要内容,如果未能解决你的问题,请参考以下文章

springboot+mybatis 怎么实现用户角色关联查询

Mybatis怎么实现各种字段的升降

内卷严重,不懂MyBatis插件开发怎么行,教你实现MyBatis分页插件

怎么编写mybatis.xml文件,实现sql增删改查

mybatis java注解怎么加判断

mybatis怎么实现时间段查询