一篇文章弄懂Mybatis中#和$的區(qū)別
前言
在學校的時候,想必大家肯定聽老師講過,在mybatis中,配置參數(shù)要用#,不要用$符號。因為$不安全,容易被sql注入。講是這么講,但是如何注入的,大家一起來看看吧。
一:下面我們寫個關于“#”的個sql,看能不能注入。
<select id="selectUser" resultMap="BaseResultMap"> SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name like #{userName} </select>
1.正常傳參
DfwsSysUserAccount user = new DfwsSysUserAccount(); user.setUserName("wanglingzhi"); List<DfwsSysUserAccount> list = userAccountService.selectUser(user); if(list!=null && list.size()>0){ for (DfwsSysUserAccount u:list) { System.out.println("用戶名:"+u.getUserName()); } }else{ System.out.println("暫無數(shù)據(jù)"); }
sql打?。?/p>
Preparing: SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name = ??
Parameters: wanglingzhi(String)
2.拼接傳參
DfwsSysUserAccount user = new DfwsSysUserAccount(); user.setUserName("'wanglingzhi' or acc.user_name = 'shuizhong'"); List<DfwsSysUserAccount> list = userAccountService.selectUser(user); if(list!=null && list.size()>0){ for (DfwsSysUserAccount u:list) { System.out.println("用戶名:"+u.getUserName()); } }else{ System.out.println("暫無數(shù)據(jù)"); }
sql打印:
Preparing: SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name = ??
Parameters: wanglingzhi or acc.user_name = shuizhong(String)
二:下面我們寫個關于“$”的個sql,看能不能注入。
<select id="selectUser" resultMap="BaseResultMap"> SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name like ${userName} </select>
1.正常傳參
DfwsSysUserAccount user = new DfwsSysUserAccount(); user.setUserName("'wanglingzhi'"); List<DfwsSysUserAccount> list = userAccountService.selectUser(user); if(list!=null && list.size()>0){ for (DfwsSysUserAccount u:list) { System.out.println("用戶名:"+u.getUserName()); } }else{ System.out.println("暫無數(shù)據(jù)"); }
打印sql:
SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name = 'wanglingzhi'
2.拼接傳參
DfwsSysUserAccount user = new DfwsSysUserAccount(); user.setUserName("'wanglingzhi' or acc.user_name = 'shuizhong'"); List<DfwsSysUserAccount> list = userAccountService.selectUser(user); if(list!=null && list.size()>0){ for (DfwsSysUserAccount u:list) { System.out.println("用戶名:"+u.getUserName()); } }else{ System.out.println("暫無數(shù)據(jù)"); }
打印sql:
SELECT acc.user_name FROM dfws_sys_user_account AS acc WHERE acc.user_name = 'wanglingzhi' or acc.user_name = 'shuizhong'?
很顯然,這里已經(jīng)sql注入了。
總結下,一般說來,二者的區(qū)別可總結為以下6點:
(1)#將傳入的數(shù)據(jù)都當成一個字符串,會對自動傳入的數(shù)據(jù)加一個雙引號。如:order by #user_id#,如果傳入的值是111,那么解析成sql時的值為order by "111",如果傳入的值是id,則解析成的sql為order by "id"。
(2)$將傳入的數(shù)據(jù)直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那么解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id。
(3)#方式在很大程度上能夠防止sql注入。
(4)$方式無法防止sql注入。
(5)$方式一般用于傳入數(shù)據(jù)庫對象,例如傳入表名。
(6)一般能用#的就別用$。
ps:在使用mybatis中還遇到<![CDATA[]]>的用法,在該符號內的語句,將不會被當成字符串來處理,而是直接當成sql語句,比如要執(zhí)行一個存儲過程。
總結
到此這篇關于Mybatis中#和$區(qū)別的文章就介紹到這了,更多相關Mybatis #和$區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring?boot之使用spring?data?jpa的自定義sql方式
這篇文章主要介紹了spring?boot之使用spring?data?jpa的自定義sql方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12