轉載至:前端
http://www.javashuo.com/article/p-tuzcfysg-hr.htmlsql
今天在工做中有個點擊排序的功能調試了許久,終尋因,總結之。
需求是這樣的,頁面有個table,有一列的上下箭頭可點擊並排序。對於這種需求,個人mybatis.xml的sql配置寫成了以下:數據庫
<if test="map.ColumnNameSort!=null and map.ColumnNameSort!=''">
mybatis
ORDER BY columnName #{map.ColumnNameSort}
</if>
ColumnNameSort即前端傳的排序方式,asc或者desc。.net
而後,預計它的輸出應該是相似於下面這樣的調試
ORDER BY columnName desc
code
可是,真正跑起來時,排序的效果一直沒出現,常常一番查找,發現是mybatis 的’#{}’傳值的問題,它將sql語句編譯成了以下xml
ORDER BY columnName 'desc' 或者 ORDER BY columnName 'asc'
對象
這樣,desc或者asc就成了字符串而不是關鍵字,sql語句的意思是columnName的別名是desc或者asc,沒加排序關鍵字時默認是正序排序,成了以下blog
ORDER BY columnName "desc" asc 或者 ORDER BY columnName "asc" asc
排序沒效果的問題找到緣由了,解決之,mybatis提供了另外一種綁定參數的方式–${param},將sql配置改成
ORDER BY columnName ${map.ColumnNameSort}
這樣一來,mybatis會直接將ColumnNameSort的值加入sql中,不會轉義。正確結果:
ORDER BY columnName desc
最後,對於mybatis中#和$綁定參數的區別作個總結,避免之後相似的問題發生。
#{}
將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #{id},若是傳入的值是111,那麼解析成sql時的值爲order by 「111」, 若是傳入的值是id,則解析成的sql爲order by 「id」。
${}
將傳入的數據直接顯示生成在sql中。如:order by
${id},若是傳入的值是111,那麼解析成sql時的值爲order by 111, 若是傳入的值是id,則解析成的sql爲order
by id。
#
方式可以很大程度防止sql注入。
$
方式沒法防止Sql注入。
$
方式通常用於傳入數據庫對象,例如傳入表名.
通常能用#的就別用$.
ps:在使用mybatis中還遇到<![CDATA[]]>
的用法,在該符號內的語句,將不會被當成字符串來處理,而是直接當成sql語句,好比要執行一個存儲過程。