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

时间: 2024-10-12 19:38:12

MyBatis实现SaveOrUpdate的相关文章

从JDBC到hibernate再到mybatis之路

一.传统的JDBC编程 在java开发中,以前都是通过JDBC(Java Data Base Connectivity)与数据库打交道的,至少在ORM(Object Relational Mapping)框架没出现之前是这样,目前常用的ORM框架有JPA.hibernate.mybatis.spring jdbc等,我一开始也是使用JDBC编程,后面开始使用hibernate,有一次开发一个CRM管理系统使用的是Spring JDBC操作数据库,但个人还是不太喜欢这个框架,本人目前使用的最多还是

Hibernate、Spring、myBatis下增删改查的Dao与DaoImpI

Hibernate Dao //Dao.java import java.util.List; /**  * @author Administrator  *   */ public interface Dao { void saveObject(Object object); void updateObject(Object object); void deleteObject(Object object); Object getObject(String HQL); List<?> fin

hibernate中 saveorupdate(),save(),update(),merge()你是怎么看待的;

接触到mybatis竟然有把hibernate抛弃的想法. 言归正传,贴图为先.hibernate的三种状态位和切换之间对函数的使用: 总结下saveorupdate(),save(),update(),merge()这几个函数: save(),update():都是很好理解的 save()在数据库中生成一条记录,如果数据库中有,会报错说有重复的记录. update()就是更新数据库中的记录: merge()就非常奇葩: 1.如果session中存在相同持久化标识(identifier)的实例,

Spring struts2 hibernate MyBatis SpringMVC 原理

Spring原理 最核心的就是IOC,动态注入DI,利用java里的反射,让一个对象的创建不用new了,可以自动的生产.Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 .其实就是利用java里的反射,反射其实就是在运行时动态的去创建.调用对象. Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能.这些都是通过 配置类达到

集成框架 javaweb开发平台ssmy_m(生成代码) java struts2 mybatis spring maven jquery

网页地址 http://blog.csdn.net/lpy3654321/article/details/31841573 项目设想,在项目开发中,我们的开发者大多数时间都在反复开发 相同的keyword,相同的语法. 但就在这种情况下还会常常发生语法的错误,并且每一个开发者的代码风格不同. 其它人员阅读困难.新人的学习成本也会添加. 这些问题会浪费非常多时间,也会影响到开发者的心情,和程序质量. 由这些问题我想的解决方法是 <代码生成工具> . 代码生成能够解决上述问题,加强约定. 对于普通

使用MyBatis Generator自动生成实体、mapper和dao层

通过MyBatis Generator可以自动生成实体.mapper和dao层,记录一下怎么用的. 主要步骤: 关于mybatis从数据库反向生成实体.DAO.mapper: 参考文章:http://www.cnblogs.com/wangkeai/p/6934683.html第一种方式:main方法运行(推荐) 1.在pom.xml中加入插件依赖: 2.写mbgConfiguration.xml文件,jdbc.properties文件 3.写/SSM/src/main/java/main/Ge

SSM整合(spring,spirngmvc,mybatis)

整合思路   准备环境:导入jar包(spring mybatis  dbcp连接池  mysql驱动包 log4j) 工程结构: --------------------------- 1.  整合dao mybatis和spring进行整合   applicationContext-dao.xml 配置: 1.数据源 2.SqlSessionFactory 3.mapper扫描器 创建po以及mapper(通过逆向工程,这里不再演示) 针对综合查询mapper,一般情况会有关联查询,建议自定

SpringBoot 2.SpringBoot整合Mybatis

一.创建Springboot的配置文件:application.properties SpringApplication 会从 application.properties 文件中加载配置信息,下面是添加Spring配置信息的文件目录顺序: 当前目录下的/config子目录中 当前目录中 一个 classpath 包下的 /config 目录中 classpath 根目录中 大家根据自己习惯来即可. /application.properties 文件配置如下: spring.datasourc

springMVC+MyBatis+Spring 整合(3)

spring mvc 与mybatis 的整合. 加入配置文件: spring-mybaits.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xm