在 mybatis 的 xml中,為一個SQL語句配置order by 子句時,需要這個排序的字段是前端傳遞過來的,而且排序的順序(升序 OR 降序)也是由前端傳遞過來的。對於這種需求,我起初寫成了下面這樣:
ORDER BY `#{condition.field}` #{condition.sortRule}
1
然后,預計它的輸出應該是類似於下面這樣的
ORDER BY `user_name` DESC
1
但是,真正運行時,你會發現,mybatis將會拋出異常,告訴你參數的個數不匹配。
我debug大概看了一下原因,對於上面這個SQL,mybatis會把它編譯成:
ORDER BY `?` ?
1
然后,有兩個待使用的參數值:
① condition.field = "user_name"
② condition.sortRule = "DESC"
1
2
但是,在替換參數時,由於第一個?是被 ` ` 包住的,而 ` ` 在MYSQL中就是用來括住字段名的(可以避免 與 SQL 關鍵字沖突等問題),所以,mybatis會把第一個?就當成是字段的名稱,從而不會進行值的替換,只會用condition.field的值替換第二個?的值,變成:
ORDER BY `?` "user_name"
1
上面這個轉換后的語句,我們會發現兩個問題:
第一個?沒有被替換
“user_name”帶了一對“”
為了解決這兩個問題,mybatis提供了另一種綁定參數的方式: ${param}
所以,現在,我們把原始的SQL語句改成如下:
ORDER BY `${condition.field}` ${condition.sortRule}
1
這個時候,我們就可以獲得正確的結果了
ORDER BY `user_name` DESC
1
這個時候,也許有人會問,這種情況下,為什么第一個?會被替換掉呢?
對於這個問題,我也沒有仔細調查,可能是mybatis的特殊處理吧。
最后,對於${ }的用法,需要注意以下幾點:
$方式無法防止Sql注入,所以,對於使用前端傳過來的值的時候,一定要進行轉義,不要直接使用
一般能用#的就別用$。
$方式一般用於傳入數據庫對象,例如傳入表名、排序規則等
---------------------
作者:rainbow702
來源:CSDN
原文:https://blog.csdn.net/rainbow702/article/details/53906763
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
