#{}:佔位符號,好處防止sql注入
${}:sql拼接符號
優先使用 #{}。因為 ${} 會導致 sql 注入的問題
1、#是預編譯處理,mybatis在處理#時,它會將sql中的#替換為?,然後呼叫preparedstatement的set方法來賦值,傳入字串後,會在值兩邊加上單引號,如上面的值 「4,44,514」就會變成「 '4,44,514' 」;
2、$是字串替換, mybatis在處理$時,它會將sql中的$替換為變數的值,傳入的資料不會加兩邊加上單引號。
注意:使用$會導致sql注入,不利於系統的安全性!
sql注入:就是通過把sql命令插入到web表單提交或輸入網域名稱或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的sql命令。常見的有匿名登入(在登入框輸入惡意的字串)、借助異常獲取資料庫資訊等
應用場合:
1、#:主要使用者獲取dao中的引數資料,在對映檔案的sql語句**現#{}表示式,底層會建立預編譯的sql;
2、$:主要用於獲取配置檔案資料,dao介面中的引數資訊,當$出現在對映檔案的sql語句中時建立的不是預編譯的sql,而是字串的拼接,有可能會導致sql注入問題.所以一般使用$接收dao引數時,這些引數一般是欄位名,表名等,例如order by 。
注:${}獲取dao引數資料時,引數必須使用@param註解進行修飾或者使用下標或者引數#形式;
#{}獲取dao引數資料時,假如引數個數多於乙個可有選擇的使用@param。
動態 sql 是 mybatis 的強大特性之一,也是它優於其他 orm 框架的乙個重要原因。mybatis 在對 sql 語句進行預編譯之前,會對 sql 進行動態解析,解析為乙個 boundsql 物件,也是在此處對動態 sql 進行處理的。在動態 sql 解析階段, # 和 $ 會有不同的表現。
select
*
from
user
where
name
= #;
動態解析為:
select
*
from
user
where
name
= ?;
乙個 # 被解析為乙個引數佔位符 ? 。
而$ 僅僅為乙個純碎的 string 替換,在動態 sql 解析階段將會進行變數替換。
select
*
from
user
where
name
= $;
當我們傳遞的引數為 "jack" 時,上述 sql 的解析為:
select
*
from
user
where
name
=
"jack"
;
預編譯之前的 sql 語句已經不包含變數了,完全已經是常量資料了。 綜上所得, $ 變數的替換階段是在動態 sql 解析階段,而 #變數的替換是在 dbms 中。
1、能使用 # 的地方就用 #
首先這是為了效能考慮的,相同的預編譯 sql 可以重複利用。其次,$ 在預編譯之前已經被變數替換了,這會存在 sql 注入問題。例如,如下的 sql:
select
*
from
$
where
name
= #
假如,我們的引數 tablename 為 user; delete user; --,那麼 sql 動態解析階段之後,預編譯之前的 sql 將變為:
select
*
from
user
;
delete
user
;
-- where name = ?;
-- 之後的語句將作為注釋,不起作用,因此本來的一條查詢語句偷偷的包含了乙個刪除表資料的 sql。
2. 表名作為變數時,必須使用 $
這是因為,表名是字串,使用 sql 佔位符替換字串時會帶上單引號 '',這會導致 sql 語法錯誤,例如:
select
*
from
#
where
name
= #;
預編譯之後的sql 變為:
select
*
from
?
where
name
= ?;
假設我們傳入的引數為 tablename = "user" , name = "jack",那麼在佔位符進行變數替換後,sql 語句變為:
select
*
from
'user'
where
name
=
'jack'
;
上述 sql 語句是存在語法錯誤的,表名不能加單引號 ''(注意,反引號 ``是可以的)。
1. 定義:
sql 預編譯指的是資料庫驅動在傳送 sql 語句和引數給 dbms 之前對 sql 語句進行編譯,這樣 dbms 執行 sql 時,就不需要重新編譯。
2. 為什麼需要預編譯
jdbc 中使用物件 preparedstatement 來抽象預編譯語句,使用預編譯。預編譯階段可以優化 sql 的執行。預編譯之後的 sql 多數情況下可以直接執行,dbms 不需要再次編譯,越複雜的sql,編譯的複雜度將越大,預編譯階段可以合併多次操作為乙個操作。預編譯語句物件可以重複利用。把乙個 sql 預編譯後產生的 preparedstatement 物件快取下來,下次對於同乙個sql,可以直接使用這個快取的 preparedstate 物件。mybatis 預設情況下,將對所有的 sql 進行預編譯。
Mybatis和Hibbernate的區別介紹
mybatis 和 hibbernate 的區別 1 首先 mybatis 是乙個半自動化的 框架 hibbernate 是乙個全自動化的框架 2 mybatis 是乙個半自動化的 框架 它的 sql 語句我們自己 編寫 sql 語句的 好壞可以控制 hibbernate 是乙個全自動化的框架 它的...
面試之Mybatis中的 和 區別?
mybatis是如何做到sql預編譯的呢?其實在框架底層,是jdbc中的preparedstatemen類在起作用,preparedstatement是我們很熟悉的statement的子類,它的物件包含了編譯好的sql語句。這種 準備好 的方式不僅能提高安全性,而且在多次執行同乙個sql時,能夠提高...
面試之jpa和mybatis的區別
第一 jpa是物件與物件之間的對映,而mybatis是物件和結果集的對映。第二 jpa移植性比較好,不用關心用什麼資料庫,因為mybatis自由寫sql語句,所以當專案移植的時候還需要改sql。及時判斷資料庫型別,不嫌累麼 第三 當需要修改欄位的時候mybatis改起來特別費事,而jpa就相對簡單。...