• 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

    最后

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

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

    MyBatis工具:www.mybatis.tk

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

  • 相关阅读:
    UltraWebGrid多表头
    2009个人年度总结报告(IT)
    DevExpress分发
    AspxTreeList数据绑定以及模板和外观定制的运用
    每日一句英语:No problem, Mr. Smith. Anything else?
    “向程序发送命令时出现问题”的解决方法
    ASP常用进制转化类(2,8,10,16,32,64)
    我的分页用户控件(性能问题)
    研发的那些事2—设计之惑
    一个架构的演化2用ESB集成
  • 原文地址:https://www.cnblogs.com/softidea/p/6066106.html
Copyright © 2020-2023  润新知