一、問題描述:
1.在使用ibatis執行下面的sql:
update jc_jiesuan set doing_time = unix_timestamp(curdate()),doing_status = ? where id in (?) and current_oprerate_type = ?
2.傳入的參數是:
Parameters: [1, 444475305,444475300,444475297,444475299, 3]
Types: [java.lang.Integer, java.lang.String, java.lang.Integer]
3.報錯信息為:
org.springframework.dao.DataIntegrityViolationException: SqlMapClient operation; SQL [];
--- The error occurred in com/chl/dao/ibatis/sqlMap/sc_jiesuan-sqlmap.xml.
--- The error occurred while applying a parameter map.
--- Check the updateJiesuanDoingStatus-InlineParameterMap.
--- Check the statement (update failed).
--- Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: '444475305,444475300,444475297,444475299'; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
二、解決方法:
1.使用“$”
通常在ibatis中傳入參數使用的是“#”,如#currentOprerateType:INTEGER#
如果要想in中傳入參數,則需要使用“$”符號。
<update id="updateJiesuanDoingStatus" parameterClass="java.util.HashMap">
update jc_jiesuan set doing_time = unix_timestamp(now()),doing_status = #doingStatus:INTEGER#
where id in ($ids$) and current_oprerate_type = #currentOprerateType:INTEGER#
</update>但這種方式會增加系統被入侵的可能,因為'$'這個符號會將傳進來的值直接組合成查詢語句,這樣很容易被Sql注入攻擊。
2.使用iterate屬性。
Iterate:這屬性遍歷整個集合,並為 List 集合中的元素重復元素體的內容。
Iterate 的屬性:
prepend - 可被覆蓋的 SQL 語句組成部分,添加在語句的前面(可選)
property - 類型為 java.util.List 的用於遍歷的元素(必選)
open - 整個遍歷內容體開始的字符串,用於定義括號(可選)
close -整個遍歷內容體結束的字符串,用於定義括號(可選)
conjunction - 每次遍歷內容之間的字符串,用於定義 AND 或 OR(可選)
示例一:
<select id="selectByIterate" parameterClass="java.util.List" resultClass="user">
SELECT * FROM USERS WHERE USER_ID IN
<iterate conjunction="," open="(" close=")">
#ids[]#
</iterate>
</select>
示例二、
<!-- 刪除性別為man,年齡為 11,12 的Person記錄,刪除相應的person記錄 -->
<delete id="deletePerson" parameterClass="map">
delete from 表名 where sex=#sex#
<iterate prepend="and" property="personList" open="("
close=")" conjunction="or">
age=$personList[].age$
</iterate>
</delete>
輸出sql如下:
delete from 表名 where sex='man' and (age =11 or age=12)