這篇文章主要講如何通過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
