面試4 mybatis中的 和 的區別

2021-09-21 18:28:42 字數 3228 閱讀 6602

#{}:佔位符號,好處防止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*fromuserwherename= #;

動態解析為:

select*fromuserwherename= ?;

乙個 # 被解析為乙個引數佔位符 ? 。

而$ 僅僅為乙個純碎的 string 替換,在動態 sql 解析階段將會進行變數替換。

select*fromuserwherename= $;

當我們傳遞的引數為 "jack" 時,上述 sql 的解析為:

select*fromuserwherename="jack";

預編譯之前的 sql 語句已經不包含變數了,完全已經是常量資料了。 綜上所得, $ 變數的替換階段是在動態 sql 解析階段,而 #變數的替換是在 dbms 中。

1、能使用 # 的地方就用 #

首先這是為了效能考慮的,相同的預編譯 sql 可以重複利用。其次,$ 在預編譯之前已經被變數替換了,這會存在 sql 注入問題。例如,如下的 sql:

select*from$wherename= #

假如,我們的引數 tablename 為 user; delete user; --,那麼 sql 動態解析階段之後,預編譯之前的 sql 將變為:

select*fromuser;deleteuser;-- where name = ?;

-- 之後的語句將作為注釋,不起作用,因此本來的一條查詢語句偷偷的包含了乙個刪除表資料的 sql。

2. 表名作為變數時,必須使用 $

這是因為,表名是字串,使用 sql 佔位符替換字串時會帶上單引號 '',這會導致 sql 語法錯誤,例如:

select*from#wherename= #;

預編譯之後的sql 變為:

select*from?wherename= ?;

假設我們傳入的引數為 tablename = "user" , name = "jack",那麼在佔位符進行變數替換後,sql 語句變為:

select*from'user'wherename='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就相對簡單。...