關於工作中Mybatis中的$和#的區別和理解

想起來前幾天的工作中,線上突然出現了一個bug,說是什部分數據查詢出錯。看了看後臺日誌,也沒發現什麼情況。

sql原本是這樣的

後來我懷疑是Mybatis的$的問題,將它替換成#。替換下來果然bug解決了。所以決定記錄一下,不能白白的踩這個坑。

這是你可能會奇怪,這兩個其實不是差不多嘛。我起始本來也是這麼認爲的,雖然表面差不多,起始背後的原理則不同。

1、Mybatis中的#{}是預編譯處理,Mybatis在處理#{}時,它會將sql中的#{}替換成?,然後調用PreparedStatement的set方法來賦值,傳入字符串後,會在值兩邊加上單引號。

2、Mybatis中的${}是字符串替換,Mybatis在處理${}時,它會將sql中的${}替換成變量的值,傳入的數據不會在兩邊加上單引號。

我們這次傳入的值對應的PORT_ID字段是char類型。所以碰見有的數據如果用${}的話,會出現錯誤,而且用${}會導致sql注入,不利於系統的安全性。

    sql注入:就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意的)SQL命令注入到後臺數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。比如先前的很多影視網站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊。

對於#和$的應用場合:

   1、#{ }:主要用戶獲取DAO中的參數數據,在映射文件的SQL語句中出現#{}表達式,底層會創建預編譯的SQL;

   2、${ }:主要用於獲取配置文件數據,DAO接口中的參數信息,當$出現在映射文件的SQL語句中時創建的不是預編譯的SQL,而是字符串的拼接,有可能會導致SQL注入問題.所以一般使用$接收dao參數時,這些參數一般是字段名,表名等,例如order by {column}。

注:${}獲取DAO參數數據時,參數必須使用@param註解進行修飾或者使用下標或者參數#{param1}形式。#{}獲取DAO參數數據時,假如參數個數多於一個可有選擇的使用@param。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章