Mybatis 中,#{ } 與 ${ } 的區別

Mybatis 在對 sql 語句進行預編譯之前,會對 sql 進行動態解析,解析爲一個 BoundSql 對象,也是在此處對動態 SQL 進行處理的。在動態 SQL 解析階段, #{ } 和 ${ } 會有不同的表現。

#{ } 解析爲一個 JDBC 預編譯語句(prepared statement)的參數標記符,即解析爲一個參數佔位符 ? 。
${ } 僅僅爲一個純碎的 string 替換,在動態 SQL 解析階段將會進行變量替換。

例如在mybatis的xml文件中,需要根據用戶名查詢用戶信息:

(1) 採用#{ }
select * from Admin where username = #{username }
解析爲:
select * from Admin where username = ?

(2)採用${ } ,假設傳進來的參數的值爲”Admin”
select * from Admin where username = ${username }
解析爲:
select * from Admin where username = 'Admin'

看似實現的效果是一樣的,但是某些情況下,兩者不能替換。

(1)當傳進去的參數爲表名時
採用#{ }
select * from #{table} where username = #{username }
解析爲:
select * from ? where username = ?

採用${ } ,假設傳入的表名爲”t_admin”,用戶名爲”Admin”
select * from ${table} where username = ${username }
解析爲:
select * from 't_admin' where username = 'Admin'
此時,sql語句編譯時將出現錯誤,因爲表名不能加單引號
同理,order by 後的參數,也不能用${ }來傳遞

(2)當傳進去的參數是sql語句時
採用#{ }
select * from Admin #{sql}
解析爲:
select * from Admin ?
此時的where條件是沒有用的

而採用${ } ,假設傳入的sql語句爲”where username = ‘Admin’ ”
select * from Admin ${sql}
解析爲:
select * from Admin where username = 'Admin'
則可以得到正確的結果

其中部分原理參照了博客:
http://blog.csdn.net/pfnie/article/details/53230994

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章