mybatis框架order by作為參數(shù)傳入時(shí)失效的解決
mxl中的語(yǔ)句如下
<select resultType='com.dahua.la.business.model.vo.StatSysResultVO'> select a, b,count(1) as total from table where a is not null and b is not null and operateTime >= #{startTime,jdbcType=TIMESTAMP} and operateTime <= #{endTime,jdbcType=TIMESTAMP} group by a, b order by <foreach collection='orderItems' item='item' separator=','> #{item.orderBy} #{item.order} </foreach></select>
運(yùn)行時(shí)通過(guò)日志打印出sql日志如下
select a, b, count(1) as total from table where a is not null and b is not null and operateTime >= ? and operateTime <= ? group by a, b order by ? ?
把參數(shù)補(bǔ)充上拿到Navicat執(zhí)行的時(shí)候,完全沒(méi)有問(wèn)題,排序也正常。
但是在代碼里執(zhí)行就是不行, 最后的排序完全沒(méi)有生效。
實(shí)際上,我補(bǔ)上參數(shù)的時(shí)候漏了引號(hào),因?yàn)?{item.orderBy}會(huì)對(duì)傳入的數(shù)據(jù)加一個(gè)引號(hào),如果帶著引號(hào)去Navicat執(zhí)行,也是排序不生效的。
問(wèn)題原因找到了直接替換成使用${item.orderBy}形式,單純的字符串替換不加引號(hào)。
<foreach collection='orderItems' item='item' separator=','> ${item.orderBy} ${item.order}</foreach>
此時(shí)程序正常。
MyBatis排序時(shí)使用order by 動(dòng)態(tài)參數(shù)時(shí)需要注意,用$而不是#字符串替換
默認(rèn)情況下,使用#{}格式的語(yǔ)法會(huì)導(dǎo)致MyBatis創(chuàng)建預(yù)處理語(yǔ)句屬性并以它為背景設(shè)置安全的值(比如?)。
這樣做很安全,很迅速也是首選做法,有時(shí)你只是想直接在SQL語(yǔ)句中插入一個(gè)不改變的字符串。
比如,像ORDER BY,你可以這樣來(lái)使用:
ORDER BY ${columnName}
這里MyBatis不會(huì)修改或轉(zhuǎn)義字符串。
重要:
接受從用戶輸出的內(nèi)容并提供給語(yǔ)句中不變的字符串,這樣做是不安全的。
這會(huì)導(dǎo)致潛在的SQL注入攻擊,因此你不應(yīng)該允許用戶輸入這些字段,或者通常自行轉(zhuǎn)義并檢查。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. MySQL 的啟動(dòng)和連接方式實(shí)例分析2. SQL SERVER數(shù)據(jù)庫(kù)開(kāi)發(fā)之存儲(chǔ)過(guò)程的應(yīng)用3. Oracle中pivot函數(shù)圖文實(shí)例詳解4. mybatis中方法返回泛型與resultType不一致的解決5. 服務(wù)器Centos部署MySql并連接Navicat過(guò)程詳解6. 在SQL Server 2005修改存儲(chǔ)過(guò)程7. idea連接SQL Server數(shù)據(jù)庫(kù)的詳細(xì)圖文教程8. SQL Server全文檢索簡(jiǎn)介9. Docker部署Mysql集群的實(shí)現(xiàn)10. Oracle?Users表空間重命名問(wèn)題解決
