工作發狂:Mybatis 中$和#千萬不要亂用!
作者:程式猿的內心獨白
開頭
這是一次程式碼最佳化過程中發現的問題,在功能最佳化後發現部分資料查不到出來了,問題就在於一條sql上的#和$。
下圖為兩條sql:
從圖上可以看出 wwlr.LabelId in(${showLabels}) 和 wwlr.LabelId in(#{showLabels}),其中showLabels是傳進來一個字串型別的引數,引數的樣子是這樣的“4,44,514”,問題就出在這個引數傳進來後#和$處理的方式是不一樣的。
區別
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 {column}。
注:
${}獲取DAO引數資料時,引數必須使用@param註解進行修飾或者使用下標或者引數#{param1}形式;
#{}獲取DAO引數資料時,假如引數個數多於一個可有選擇的使用@param。
問題分析
其實剛開始我也沒太去看sql裡的#和$,我把sql放到資料庫跑一切正常,所以我就將程式碼的執行sql輸出到控制檯了,具體是這麼一個輸出sql的配置檔案:
輸出後,終於發現了問題在哪裡。。。。
看了上面的區別介紹,相信大家其實都應該知道區別在哪裡,我們的問題在哪裡,其實就是sql在in的時候 ,裡面的資料被加了兩個雙引號。“wwlr.LabelId in(4,44,514)就會變成 wwlr.LabelId in('4,44,514' );所以導致部分資料查不到了。
解決辦法
1、快速解決
最快的方法就是把#直接替換成$,這樣問題應該就可以解決了。
但是,我很無語,我確沒有解決。
本地跑程式碼一點問題都沒有,部署到公司的docker上問題一樣沒解決,給人的感覺就是程式碼根本沒有從#變$。
大家都知道$其實是有危險性,會容易被sql注入,具我所知道,我們公司的docker是會加一層防止 sql注入的功能 ,所以不知道是不是這個功能把的$無效掉了。
當然,我也沒有去再到服務上打出sql來看一下,因為本來$就是不太安全的,所以我換了一種方式處理。
2、foreach標籤的使用
foreach標籤主要用於構建in條件,他可以在sql中對集合進行迭代。
先來看看語法:
透過上圖,大家也應該也瞭解和使用這個標籤了吧。
那對於我們專案中的改造,其實就是把原來傳進來的字元型引數變成List<Integer>,這樣問題就完美的解決了,既實現了我們的功能 ,又解決了安全性問題。
原文連結:
·END·
程式設計師的成長之路
路雖遠,行則必至
本文原發於 同名微信公眾號「程式設計師的成長之路」,回覆「1024」你懂得,給個讚唄。
回覆 [ 520 ] 領取程式設計師最佳學習方式
回覆 [ 256 ] 檢視 Java 程式設計師成長規劃
往期精彩回顧
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69902700/viewspace-2643759/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 很恐怖ABAP修改程式(千萬不要亂用!!!!!!!!!)
- 千萬不要寫程式碼不要讀博
- @Transactional千萬不要這樣用!!踩坑了你都可能發現不了!!!
- 請不要在“微服務”的狂熱中迷失自我!微服務
- linux apt-get autoremove千萬別亂用Linuxapt-getREM
- MyBatis中#{}和${}MyBatis
- 程式設計師們,千萬不要接私活程式設計師
- Python!請不要再亂搞 Linux 發行版了PythonLinux
- 「Mybatis系列」Mybatis開發方式和配置MyBatis
- 程式設計師千萬不要學演算法!程式設計師演算法
- Linux 千萬不要執行的10個命令Linux
- 程式設計師,千萬不要重寫程式碼程式設計師
- 千萬不要把bool當成函式引數函式
- 力軟敏捷開發框架9.15史詩級更新,千萬不要錯過。敏捷框架
- Mybatis工作原理MyBatis
- 【實用知識】2020年招投標千萬不要這樣做!
- 程式設計師為什麼千萬不要瞎努力?程式設計師
- 好用的企業網盤工具千萬不要錯過
- [20160113]不要亂用國際化函式.txt函式
- CSS開發中的10個不要CSS
- 不要為了錢而工作
- PVE關卡設計淺談:千萬不要拍腦袋!
- 更新Kali的Metasploit框架,這些過程千萬不要踩雷!框架
- 遊戲創業團隊如何吸引投資?談投資的過程中,哪些坑千萬不要踩?遊戲創業團隊
- 用 OSGi 應用程式開發和工作的最佳實踐
- 為什麼程式設計師千萬不要重寫程式碼?程式設計師
- 關於Web前端面試的小技巧,千萬不要錯過!Web前端面試
- 不要升級!不要升級!MacOS 14.4 引發Java 應用崩潰MacJava應用崩潰
- Java開發中的工作流程和步驟Java
- 不要將Actors用於併發程式設計程式設計
- web前端CSS開發中的10個不要Web前端CSS
- 應用方便千萬人
- 小白手把手教學用spring框架實現mybatis和mysql以及工作原理Spring框架MyBatisMySql
- 外賣系原始碼陷阱,創業者千萬不要再去踩了原始碼創業
- 如果不會這兩招,千萬不要說你懂大資料大資料
- iPhone7釋出前 這幾款手機千萬不要買iPhone
- 淺析mybatis中${}和#{}取值區別MyBatis
- MyBatis中#{}和${}的區別詳解MyBatis