⑴ mybatis通過預編譯進行參數拼接的符號
#{}佔位轎帶符:佔位使用#{}意味著使用的預編譯的語句,即在使用jdbc時的preparedStatement,sql語句中如果存在參數則會使用?作佔位符,我仔帆粗們知道這種方式可以防止sql注入,並且在使用#{}時形成的sql語句,已經帶有引號,例,select * from table1 where id=#{id} 在調用這念鎮個語句時我們可以通過後台看到列印出的sql為:select * from table1 where id=『2』 加入傳的值為2.也就是說在組成sql語句的時候把參數默認為字元串。如果傳入的是基本類型,那麼#{}中的變數名稱可以隨意寫如果傳入的參數是pojo類型,那麼#{}中的變數名稱必須是pojo中的屬性.屬性.屬性?${}拼接符:字元串原樣拼接如果傳入的是基本類型,那麼${}中的變數名必須是value如果傳入的參數是pojo類型,那麼${}中的變數名稱必須是pojo中的屬性.屬性.屬性?注意:使用拼接符有可能造成sql注入使用${}時的sql不會當做字元串處理,是什麼就是什麼,如上邊的語句:select * from table1 where id=${id} 在調用這個語句時控制台列印的為:select * from table1 where id=2 ,假設傳的參數值為2從上邊的介紹可以看出這兩種方式的區別,我們最好是能用#{}則用它,因為它可以防止sql注入,且是預編譯的,在需要原樣輸出時才使用${},如,select * from ${tableName} order by ${id} 這里需要傳入表名和按照哪個列進行排序 ,加入傳入table1、id 則語句為:select * from table1 order by id如果是使用#{} 則變成了select * from 『table1』 order by 『id』 我們知道這樣就不對了。另,在使用以下的配置時,必須使用#{}
⑵ mybatis 為什麼可以防止sql注入
因為在mybatis中,」${xxx}」這樣格式的參數會直接參與sql編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用「${xxx}」這樣的參數格式,所以,這樣的參數需要程序開發者在代碼中手工進行處理來防止注入。
#xxx# 代表xxx是屬性值,map裡面的key或者是你的pojo對象裡面的屬性, ibatis會自動在它的外面加上引號,表現在sql語句是這樣的 where xxx = 'xxx' ;
$xxx$ 則是把xxx作為字元串拼接到sql語句中, 比如 order by topicId , 語句這樣寫 ... order by #xxx# ibatis 就會翻譯成order by 'topicId' (這樣就會報錯) 語句這樣寫 ... order by $xxx$ ibatis 就會翻譯成 order by topicId
#將傳入的數據都當成一個字元串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值為order by "111", 如果傳入的值是id,則解析成的sql為order by "id".2. $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那麼解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id
所以說#方式能夠很大程度防止sql注入。