MyBatis实现SaveOrUpdate

来源:互联网 发布:word vba编程代码大全 编辑:程序博客网 时间:2024/06/13 12:42

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=ChinaCountry country = new Country();country.setId(35);country.setCountryname("中国");country.setCountrycode("CN");//由于存在,这里会updateint result = countryMapper.saveOrUpdate(country);//查询结果,判断是否已经改变Country c2 = countryMapper.selectById(35);assertEquals("中国",c2.getCountryname());//id=300的不存在c2 = countryMapper.selectById(300);assertNull(c2);//将id=300country.setId(300);//由于id=300不存在,这里会Insertresult = countryMapper.saveOrUpdate(country);//查询结果c2 = countryMapper.selectById(300);assertNotNull(c2)

输出日志

DEBUG ==>  Preparing: select count(*) from country where id = ? DEBUG ==> Parameters: 35(Integer)TRACE <==    Columns: C1TRACE <==        Row: 1DEBUG <==      Total: 1DEBUG ==>  Preparing: update country set countryname = ?,countrycode = ? where id = ? DEBUG ==> Parameters: 中国(String), CN(String), 35(Integer)DEBUG <==    Updates: 1DEBUG ==>  Preparing: select * from country where id = ? DEBUG ==> Parameters: 35(Integer)TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODETRACE <==        Row: 35, 中国, CNDEBUG <==      Total: 1DEBUG ==>  Preparing: select * from country where id = ? DEBUG ==> Parameters: 300(Integer)DEBUG <==      Total: 0DEBUG ==>  Preparing: select count(*) from country where id = ? DEBUG ==> Parameters: 300(Integer)TRACE <==    Columns: C1TRACE <==        Row: 0DEBUG <==      Total: 1DEBUG ==>  Preparing: insert into country values(?,?,?) DEBUG ==> Parameters: 300(Integer), 中国(String), CN(String)DEBUG <==    Updates: 1DEBUG ==>  Preparing: select * from country where id = ? DEBUG ==> Parameters: 300(Integer)TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODETRACE <==        Row: 300, 中国, CNDEBUG <==      Total: 1实际配置类名
package com.jn.oracle.tz.importExcel.bean;public class ExcelUser {    private String  username; //用户名    private Integer  reportId; //报表id    private 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中实现更好。