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>