1. 程式人生 > >mybatis實現hibernate中的saveOrUpdate方法

mybatis實現hibernate中的saveOrUpdate方法

mybatis實現saveOrUpdate

最近在做專案過程中遇到需要更新或者插入的問題,就想起hibernate有個saveOrUpdate的方法,想著mybatis是不是也有這個方法。於是上網查詢資料。該問題有兩種解決方案。

方法1:使用mybatis的標籤

<insert id="saveOrUpdate" >
  <selectKey keyProperty="count" resultType="int" order="BEFORE">
    select count(*) from station where id = #{id}
  </selectKey>
  <if test="count > 0">
    update station 
    set s_describe = #{sDescribe},s_longitude = #{sLongitude} 
    where id = #{id}
  </if>
  <if test="count==0">
    insert into station values(#{id},#{sDescribe},#{sLongitude})
  </if>
</insert>

這種方式實際上就是將需求拆為兩條sql語句來完成,雖然解決問題了,但是感覺不利於事務的控制管理

方式2:使用sql語句實現

通過這次遇到的問題,我也學到了原生sql語句是怎麼實現這個功能的。
在mysql裡,如果在INSERT語句末尾指定了ON DUPLICATE KEY UPDATE,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重複值,則在出現重複值的行執行UPDATE;如果不會導致唯一值列重複的問題,則插入新行。

INSERT INTO table (a,c) VALUES (1,3) ON DUPLICATE KEY UPDATE c=c+1;
UPDATE TABLE SET c=c+1 WHERE a=1;

假設a為unique索引,當執行如上語句,如果出現已經存在a=1的資料,則執行該語句的結果為c=4即執行後面的update,c=c+1。

所以最後我決定還是用第二種方式:

<insert id="saveOrUpdate" parameterType="com.buoy.entity.Station">
    INSERT INTO station
            (s_id,
             s_describe,
             s_station,
             s_buoyid)
    VALUES (
            #{sId,jdbcType=INTEGER}, 
            #{sDescribe,jdbcType=VARCHAR},
            #{sStation,jdbcType=VARCHAR},
            #{sBuoyid,jdbcType=VARCHAR}
            )
    ON DUPLICATE KEY UPDATE 
             <if test="date != null">
                 date = #{date,jdbcType=VARCHAR},
             </if>
                 s_longitude = #{sLongitude,jdbcType=VARCHAR},
                 s_latitude = #{sLatitude,jdbcType=VARCHAR},
             <if test="sDescribe != null">
                s_describe = #{sDescribe,jdbcType=VARCHAR},
             </if>
             s_station = #{sStation,jdbcType=VARCHAR},
             ;
  </insert>