#{}和${}的區(qū)別
時(shí)間:2023-01-31 11:56:01 | 來源:建站知識
時(shí)間:2023-01-31 11:56:01 來源:建站知識
#{}和${}的區(qū)別
數(shù)據(jù)庫數(shù)據(jù)
一、先說#{}
例:mapper.xml如下
<select id="getPaymentByName" parameterType="String" resultMap="BaseResultMap"> select * from payment where name = #{name};</select>
1、#{}是一個(gè)占位符,相當(dāng)于JDBC中的一個(gè)?,會(huì)對一些敏感的字符進(jìn)行過濾
2、#{}底層采用的是PreparedStatement,會(huì)預(yù)編譯(主要是里面的setString方法,對一些特殊的字符,例如''單引號,會(huì)在值后面加上一個(gè)/右斜線進(jìn)行轉(zhuǎn)義,讓值無效),因此不會(huì)產(chǎn)生sql注入
例:
請求:
http:
//localhost:8001/payment/get?name='小明' debug運(yùn)行查看
value = {char[4]@9719} [', 小, 明, '] 0 = '/'' 39 1 = '小' 23567 2 = '明' 26126 3 = '/'' 39
結(jié)果:
{"code":444,"message":"查詢數(shù)據(jù)失敗,name:'小明'","data":null}
3、#{}不會(huì)產(chǎn)生字符串拼接,
4、#{}在使用時(shí)會(huì)根據(jù)傳遞進(jìn)來的值來選擇是否加上雙引號(例:#{name} 傳入sql中就是"小明"),因此我們在傳遞參數(shù)時(shí)一般都是直接傳遞,不用加雙引號
例:
http:
//localhost:8001/payment/get?name=小明 5、在傳遞參數(shù)時(shí)#{}中可以傳遞任意值
例:
<select id="getPaymentByName" parameterType="String" resultMap="BaseResultMap"> select * from payment where name = #{name}; </select> <select id="getPaymentByName2" parameterType="String" resultMap="BaseResultMap"> select * from payment where name = #{隨便寫}; </select>
得出的結(jié)果都是:
{"code":200,"message":"查詢數(shù)據(jù)成功,serverPort:8001","data":{"id":1,"serial":"xm","name":"小明"}}
注意在dao層改一下
Payment getPaymentByName2(@Param("隨便寫") String name);
6、#{}的應(yīng)用場景是為sql語句中where字句傳遞條件值
二、再說${}
1、${}匹配的是真是傳遞的值,傳遞后會(huì)與sql語句進(jìn)行字符拼接
2、${}會(huì)與其他sql進(jìn)行字符串拼接,不能預(yù)防sql注入
例:mapper.xml如下
<select id="getPaymentByName" parameterType="String" resultMap="BaseResultMap"> select * from payment where name = ${name}; </select>
請求:
http:
//localhost:8001/payment/get?name=小明 報(bào)錯(cuò):
SQL: select * from payment where name = 小明; ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column '小明' in 'where clause'
3、${}不會(huì)主動(dòng)加""雙引號,需要我們手動(dòng)加入
例:
請求:
http:
//localhost:8001/payment/get?name="小明" 結(jié)果:
{"code":200,"message":"查詢數(shù)據(jù)成功,serverPort:8001","data":{"id":1,"serial":"xm","name":"小明"}}
4、${}作為普通傳值,不能進(jìn)行字符過濾
5、${}的應(yīng)用場景是為了傳遞一些需要參與SQL語句語法生成的值
例:
<select id="getPaymentFromTable" parameterType="String" resultMap="BaseResultMap"> select * from ${table}; </select>
請求:
http:
//localhost:8001/payment/get?table=payment 結(jié)果:
{"code":200,"message":"查詢數(shù)據(jù)成功,serverPort:8001", "data":[ {"id":1,"serial":"xm","name":"小明"}, {"id":2,"serial":"xh","name":"小紅"}, {"id":3,"serial":"zs","name":"張三"}, {"id":4,"serial":"ls","name":"李四"}, {"id":5,"serial":"ww","name":"王五"}, {"id":6,"serial":"zl","name":"趙六"}, {"id":7,"serial":"tq","name":"田七"}, {"id":8,"serial":"wf","name":"王妃"}]}
三、最后統(tǒng)一總結(jié)一下(感覺自己寫的亂糟糟的o(╥﹏╥)o)
1、#{}是一個(gè)占位符,${}只是普通傳值
2、#{}在使用時(shí),會(huì)根據(jù)傳遞進(jìn)來的值來選擇是否加上雙引號,因此我們傳遞參數(shù)時(shí)一般都是直接傳遞,不用加雙引號;${}則不會(huì),我們需要手動(dòng)加
3、在傳遞一個(gè)參數(shù)時(shí),我們在#{}中可以寫任意值
4、#{}針對SQL注入進(jìn)行了字符過濾,${}則只是作為普通傳值,并沒有考慮到這些問題
5、#{}的應(yīng)用場景是為給SQL語句的where字句傳遞條件;${}的應(yīng)用場景是為了傳遞一些需要參與SQL語句語法生成的值