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>

条件限制

根据不同的判断逻辑,会有所不同,就上面这个例子而言,就要求实体类中包含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)

输出日志

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实际配置
类名
package com.jn.oracle.tz.importExcel.bean;public class ExcelUser {private String  username; //用户名private Integer  reportId; //报表idprivate Integer  isView; // 是否有查看权限private Integer  isImport; //是否有导入权限private Integer count ; //一个计数器public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Integer getReportId() {return reportId;}public void setReportId(Integer reportId) {this.reportId = reportId;}public Integer getIsView() {return isView;}public void setIsView(Integer isView) {this.isView = isView;}public Integer getIsImport() {return isImport;}public void setIsImport(Integer isImport) {this.isImport = isImport;}public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}
}xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.oracle.tz.importExcel.dao.ExcelUserDao"><resultMap id="reportConfigMap" type="com.jn.oracle.tz.importExcel.bean.ExcelUser" ><result property="username" column="USER_NAME" jdbcType="VARCHAR" /><result property="reportId" column="REPORT_ID" jdbcType="INTEGER" /><result property="isView" column="IS_VIEW" jdbcType="INTEGER" /><result property="isImport" column="IS_IMPORT" jdbcType="INTEGER" /></resultMap><insert id="saveOrUpdate" parameterType="com.jn.oracle.tz.importExcel.bean.ExcelUser"><selectKey keyProperty="count" resultType="int" order="BEFORE">select count(*)  from TB_TZ_EXCEL_USER where report_id = #{reportId,jdbcType=INTEGER}and user_name = #{username,jdbcType=VARCHAR}</selectKey><if test="count > 0">update TB_TZ_EXCEL_USER set is_view =  #{isView,jdbcType=INTEGER},is_import =  #{isImport,jdbcType=INTEGER}where user_name =  #{username,jdbcType=VARCHAR}and report_id =  #{reportId,jdbcType=INTEGER}</if><if test="count == 0">insert into TB_TZ_EXCEL_USER(User_Name,REPORT_ID,IS_VIEW,IS_IMPORT)values( #{username,jdbcType=VARCHAR},#{reportId,jdbcType=INTEGER},#{isView,jdbcType=INTEGER},#{isImport,jdbcType=INTEGER} )</if></insert></mapper>


最后

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

												

MyBatis实现SaveOrUpdate相关推荐

  1. python 正则表达式提取数据_Python爬虫教程-19-数据提取-正则表达式(re)

    本篇主页内容:match的基本使用,search的基本使用,findall,finditer的基本使用,匹配中文,贪婪与非贪婪模式 Python爬虫教程-19-数据提取-正则表达式(re) 正则表达式 ...

  2. Spring Data JPA 之 理解 Persistence Context 的核心概念

    21 理解 Persistence Context 的核心概念 21.1 Persistence Context 相关核心概念 21.1.1 EntityManagerFactory 和 Persis ...

  3. Mybatis 关于同一条SQL语句实现批量插入和更新(SaveOrUpdate)完整版

    文章目录 一. 根据相应的唯一主键来判断是否新增或更新 [对事务支持较好] 二.根据selectkey判断查询的count值是否为1,然后再进行新增或更新 前言:我们在做批量更新或者插入时候,不想在代 ...

  4. 一个 Mybatis 开发神器:Fast MyBatis 超好用

    欢迎关注方志朋的博客,回复"666"获面试宝典 fastmybatis 是一个 mybatis 开发框架,其宗旨为:简单.快速.有效.零配置快速上手,无需编写 xml 文件即可完成 ...

  5. SSM-Spring+SpringMVC+MyBatis整合案例从0到1

    文章目录 概述 Step1.新建Maven web项目 step1.1 基本结构 Step1.2 pom.xml Step1.3 web.xml Step1.4 pom.xml中添加web的支持 St ...

  6. SpringMVC+Mybatis基础知识和配置

    SpringMVC和Mybatis简单的记录一下,因为现在有比较新的SpringBoot和Mybatis plus简化了很多步骤. SpringMVC 使用 创建maven项目,pom.xml < ...

  7. (4) hibernate增删查改+批量操作+类似Mybatis动态sql

    简介 采用spring + hibernate + freemaker+ maven搭建起来的一个hibernate增删查改和 类似mybatis动态sql查询的一个案例 增删查改demo + 动态s ...

  8. struts、hibernate、spring、 mybatis、 spring boot 等面试题汇总

    1.谈谈你对Struts的理解. 答: 1. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionS ...

  9. 在mybatis用mysql的代码块_mybatis plus与mysql分库组件mycat的结合

    之前的文章简单介绍了一下mybatis plus:<使用Mybatis-plus代替原生Mybatis>.截止目前在项目中使用了一段时间的mybatis plus,再也没有写过sql,都用 ...

最新文章

  1. 建筑工程的发展、未来那个职业将会兴起!
  2. CentOS7编译安装LNMP
  3. 文件系统vs对象存储——选型和趋势
  4. 简单理解AOP(面向切面编程)
  5. linux 下运行 tomcat
  6. 棋盘切割 DP POJ 1191
  7. fib函数用python编写_Python中利用函数装饰器实现备忘功能
  8. PostgreSQL 10 新特性, 流式接收端在线压缩redo
  9. 转载:大学生如何让自己强大起来(计算机、电子方向)
  10. eclipse关闭mysql数据库_Eclipse 连接 Mysql 数据库操作总结
  11. php 邮件发送是html 没样式_PHP 下的 Socket 编程--发送邮件
  12. STM32F4 + HAL库 + W25Q256的验证
  13. 数据结构实验二---单链表的实现
  14. ICLR 2022 | 合作博弈新范式:为可解释性等机器学习估值问题提供新方法
  15. quartus之BSF自底向上
  16. 实时视频服务器 SRS 开源初探
  17. 一个三维四翼混沌系统混沌吸引子——MATLAB实现
  18. 大学毕业必须知道的东西:三方协议、报到证(派遣证)、干部身份
  19. matlab 飞机大战小游戏
  20. 优信php面试流程_php面试的的时候你被提过哪些问题?

热门文章

  1. 【Python入门】for循环的易错点
  2. java安全编码指南之:表达式规则
  3. 看动画学算法之:二叉堆Binary Heap
  4. python怎么索引txt数据中第四行_python txt读取第一行数据库
  5. 分布式锁中的王者方案:Redisson
  6. '#selector' does not refer to an '@objc' method,No method declared with Objective-C selector 'compos
  7. 避坑_node-sass安装问题及解决办法
  8. 【简洁写法】剑指 Offer 32 - I. 从上到下打印二叉树
  9. 【0ms优化】剑指 Offer 18. 删除链表的节点
  10. 【简便解法】1091 N-自守数 (15分)