這是一次**優化過程中發現的問題,在功能優化後發現部分資料查不到出來了,問題就在於一條sql上的#和$。
下圖為兩條sql:
從圖上可以看出 wwlr.labelid in(you can't use 'macro parameter character #' in math mode) 和 wwlr.labelid in(#),其中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 。
注:${}獲取dao引數資料時,引數必須使用@param註解進行修飾或者使用下標或者引數#形式;
#{}獲取dao引數資料時,假如引數個數多於乙個可有選擇的使用@param。
其實剛開始我也沒太去看sql裡的#和$,我把sql放到資料庫跑一切正常,所以我就將**的執行sql輸出到控制台了,具體是這麼乙個輸出sql的配置檔案:
輸出後,終於發現了問題在**。。。。
看了上面的區別介紹,相信大家其實都應該知道區別在**,我們的問題在**,其實就是sql在in的時候 ,裡面的資料被加了兩個雙引號。「wwlr.labelid in(4,44,514)就會變成 wwlr.labelid in('4,44,514' );所以導致部分資料查不到了。
最快的方法就是把#直接替換成$,這樣問題應該就可以解決了。
但是,我很無語,我確沒有解決。
本地跑**一點問題都沒有,部署到公司的docker上問題一樣沒解決,給人的感覺就是**根本沒有從#變$。
大家都知道其實是有危險性,會容易被注入,具我所知道,我們公司的是會加一層防止注入的功能,所以不知道是不是這個功能把的其實是有危險性,會容易被sql注入,具我所知道,我們公司的docker是會加一層防止 sql注入的功能 ,所以不知道是不是這個功能把的無效掉了。
當然,我也沒有去再到服務上打出sql來看一下,因為本來$就是不太安全的,所以我換了一種方式處理。
foreach標籤主要用於構建in條件,他可以在sql中對集合進行迭代。
先來看看語法:
通過上圖,大家也應該也了解和使用這個標籤了吧。
那對於我們專案中的改造,其實就是把原來傳進來的字元型引數變成list,這樣問題就完美的解決了,既實現了我們的功能 ,又解決了安全性問題。
Redis 千萬不要亂用KEYS命令,不然會挨打的
redis現如今使用的場景越來越多?如何批量刪除key呢?有人說用keys命令,剛開始學redis的時候就是用這個命令列出庫中鍵。keys命令要謹慎使用。為何?客觀別急,我們先一步步來看。上面是官方文件宣告,keys命令不能用在生產的環境中,這個時候如果數量過大效率是十分低的。同時也不要用keys正...
Redis 千萬不要亂用KEYS命令,不然會挨打的
redis現如今使用的場景越來越多?如何批量刪除key呢?有人說用keys命令,剛開始學redis的時候就是用這個命令列出庫中鍵。keys命令要謹慎使用。為何?客觀別急,我們先一步步來看。上面是官方文件宣告,keys命令不能用在生產的環境中,這個時候如果數量過大效率是十分低的。同時也不要用keys正...
不要亂用maxdos
不要亂用maxdos 昨天夜裡,老婆說家裡用於網銀支付的手提電腦十分慢,幾乎不能使用。我看了一下,確實是這樣子。這機子是2004年買的,pentium m 1.5g,後來記憶體到1.2gb,跟乙個winxp,想來不應該這麼慢,所以我決定重灌系統。我想這是臺老機器,可能是記憶體有問題,於是拆記憶體,刷...