MyBatis实现SaveOrUpdate

简介: 这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现。 例子 select count(*) from country where id = #{id} update country se...

这篇文章主要讲如何通过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>

 

条件限制

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

说明

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

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

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

测试代码

//数据库中已经存在该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);

 

输出日志

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

 

最后

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

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

MyBatis工具:www.mybatis.tk

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

 

相关文章
|
SQL XML Oracle
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
572 0
Mybatis动态SQL语句查询,实现一个参数 可查询多个字段。
|
SQL Java 数据库连接
Mybatis中sql拦截增强-AOP+interceptor实现分页和排序
基于interceptor可以实现sql的完整打印,除了实现打印之外。其实还可以实现分页和排序,下面的分页和排序基于aop+mybatis的interceptor实现。其本质还是对mappedStament的boundSql进行增强。 下面的项目来源于github,通过这个我们可以很好的学习mybatis中插件interceptor的使用。
893 0
Mybatis中sql拦截增强-AOP+interceptor实现分页和排序
|
JavaScript 前端开发 Java
SpringBoot+Vue+Mybatis+Redis实现汽车租赁系统【毕设专用、源码、数据库设计】
SpringBoot+Vue+Mybatis+Redis实现汽车租赁系统【毕设专用、源码、数据库设计】
242 0
SpringBoot+Vue+Mybatis+Redis实现汽车租赁系统【毕设专用、源码、数据库设计】
|
前端开发 JavaScript Java
全栈开发实战|​人事管理系统的设计与实现(Spring Boot + Vue 3 + MyBatis)
全栈开发实战|​人事管理系统的设计与实现(Spring Boot + Vue 3 + MyBatis)
1056 0
全栈开发实战|​人事管理系统的设计与实现(Spring Boot + Vue 3 + MyBatis)
|
Java BI 数据安全/隐私保护
基于JSP+Mybatis实现的CRM客户关系管理系统
基于JSP+Mybatis实现的CRM客户关系管理系统
130 0
基于JSP+Mybatis实现的CRM客户关系管理系统
|
Java 数据库连接 数据库
|
Java 数据库连接 数据库
springboot03、实现mybatis
springboot03、实现mybatis
82 0
springboot03、实现mybatis
|
Java 数据库连接 数据库
【Mybatis】学习笔记02:实现简单的查
【Mybatis】学习笔记02:实现简单的查
109 0
【Mybatis】学习笔记02:实现简单的查
|
SQL Java 数据库连接
【Mybatis】学习笔记01:连接数据库,实现增删改 2
【Mybatis】学习笔记01:连接数据库,实现增删改 2
108 0
【Mybatis】学习笔记01:连接数据库,实现增删改 2
|
SQL XML Java
【Mybatis】学习笔记01:连接数据库,实现增删改 1
【Mybatis】学习笔记01:连接数据库,实现增删改
227 0
【Mybatis】学习笔记01:连接数据库,实现增删改 1