mybatis作為目前java較為常使用的orm框架,其中動態sql的參數的注入有${}與#{兩種形式,下面來介紹一下他們之間的區別,
#{}作為參數注入的方式時,從表象上來看,是在參數上添加了一個“”號,從實際執行情況來看,他其實是對原sql語句進行了預編譯,留下的參數位置作為一個“”坑“,使用預編譯有以下幾個好處,
1、效率性,數據庫在處理SQL語句時都有一個預編譯的過程,而預編譯對象就是把一些格式固定的SQL編譯后,存放在內存池中即數據庫緩沖池,當我們再次執行相同的SQL語句時就不需要預編譯的過程了,只需DBMS運行SQL語句。所以當你需要執行該sql多次的時候,將會大大降低運行時間,特別是的大型的數據庫中,它可以有效的也加快了訪問數據庫的速度。
2、防止sql注入,防止了 userName = "1' OR '1'='1";這種萬能密碼,或者"SELECT * FROM users WHERE name = 'any_value' and pw = ''; DROP TABLE users"這種破壞性的參數注入手段
${}作為參數注入方式時,從表象上來看,將參數拼接進sql中,未加“”號,這種方式其實質上就是作了一個字符串的拼接,所以第一個問題是他需要每次都編譯一個新的sql,而在數據庫的處理中,編譯sql是一個比較耗費資源的事,這就影響了效率,不方便復用。
比較兩種方式,#{}是先編譯再注入參數,而${}是先拼接字符串,然后在編譯,所以我們推薦的能用#{}就用#{},當然,如果#{}能解決一切問題也沒有${}存在的價值了,${}也存在其必要的使用場景,如變量的位置處於表名,字段名時,使用#{}無法完成拼接功能的,然后還有一種情景,在條件為in 多個參數拼接的字符作為條件時(如 in "2,3,4"),需要使用${}強行憑借,因為若使用了#{},實際判斷的是該字段是否在(2,3,4)這一個字符串中,這其實也是為了防止sql注入。