首先通過下面兩條sql及列印的執行sql,清楚明了的看一下它們的區別:
select
*from
user
where
userid=$ password=#
假設入參傳入的是1,列印執行sql如下:
preparing:select * from user where id=1 and password=111111
select
* from
user
where
userid=# and password=#
同樣入參傳入1,列印的執行sql如下:
preparing:select * from user where id=? and password=?
parameters:1(string),111111(string)
mybatis啟用了預編譯功能,在sql執行前,會先將上面的sql傳送給資料庫進行編譯;執行時,如果入參為#{}格式的,將入參替換編譯好的sql中的佔位符「?」;如果入參格式為${},則直接使用編譯好的sql就可以了。因為sql注入只能對編譯過程起作用,所以使用#{}入參的方式可以很好地避免了sql注入的問題。
mybatis預編譯底層實現原理
mybatis是如何做到sql預編譯的呢?其實在框架底層,是jdbc中的preparedstatement類在起作用,preparedstatement是我們很熟悉的statement的子類,它的物件包含了編譯好的sql語句。這種「準備好」的方式不僅能提高安全性,而且在多次執行同乙個sql時,能夠提高效率。原因是sql已編譯好,再次執行時無需再編譯。
總結
#{}:相當於jdbc中的preparedstatement
${}:是輸出變數的值
簡單說,#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變數的值,是非安全的,存在sql注入。
番外(sql注入)
還是以上面的兩條sql為例,入參id的值傳入「1 or userid=2」,入參pwd的值傳入「111111」。以#{}格式傳入入參後的執行sql:
select * from user where userid=」1 or userid=2」 and password = 「111111」;
以${}格式傳入入參後的執行sql:
select * from user where userid=1 or userid=2 and password = 111111;
很顯然,以${}格式傳入入參後的執行sql打亂了我們的預期sql格式及查詢條件,從而實現sql注入。所以,除了order by 等需要傳入資料庫欄位等的入參使用${},其他的盡量使用#{}。
myBatis中 和 區別
1.將傳入的資料都當成乙個字串,會對自動傳入的資料加乙個雙引號。如 order by user id 如果傳入的值是111,那麼解析成sql時的值為order by 111 如果傳入的值是id,則解析成的sql為order by id 2.將傳入的資料直接顯示生成在sql中。如 order by u...
mybatis 中 和 區別
在使用mybatis 框架時 在xml的配置檔案中,通常是使用 來獲取數值的 如 select from t user inf where id 這時 如果你傳入的值為zhangsan 則會編譯成為 select from t user inf where id zhangsan mybatis 會...
Mybatis 中 和 區別
號與 區別 號表示引數,代表乙個字串。如 select a,b,c from table1 where id value 傳入引數後如 value 1 則可生成 select a,b,c from table1 where id 1 select a,b,c from table1 where ci...