亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關于mybaties中#和$的區別?

關于mybaties中#和$的區別?

一只斗牛犬 2019-09-10 16:10:41
mybaties中#和$的區別
查看完整描述

4 回答

?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

首先通過下面兩條sql及打印的執行sql,清楚明了的看一下它們的區別:
<select id="selectUserInfo" parameterType="java.util.Map" resultType="java.util.Map">
select
*
from
user
where
userId=${id} password=#{pwd}
</select>12345678

假設入參傳入的是1,打印執行sql如下:
Preparing:select * from user where id=1 and password=111111
<select id="selectUserInfo" parameterType="java.util.Map" resultType="java.util.Map">
select
*
from
user
where
userId=#{id} and password=#{pwd}
</select>12345678

同樣入參傳入1,打印的執行sql如下:
Preparing:select * from user where id=? and password=?
Parameters:1(String),111111(String)
MyBatis啟用了預編譯功能,在SQL執行前,會先將上面的SQL發送給數據庫進行編譯;執行時,如果入參為#{}格式的,將入參替換編譯好的sql中的占位符“?”;如果入參格式為${},則直接使用編譯好的SQL就可以了。因為SQL注入只能對編譯過程起作用,所以使用#{}入參的方式可以很好地避免了SQL注入的問題。
mybatis預編譯底層實現原理
MyBatis是如何做到SQL預編譯的呢?其實在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準備好”的方式不僅能提高安全性,而且在多次執行同一個SQL時,能夠提高效率。原因是SQL已編譯好,再次執行時無需再編譯。
總結
#{}:相當于JDBC中的PreparedStatement
${}:是輸出變量的值
簡單說,#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變量的值,是非安全的,存在SQL注入。
番外(sql注入)
還是以上面的兩條sql為例,入參id的值傳入“1 or userId=2”,入參pwd的值傳入“111111”。以#{}格式傳入入參后的執行sql:
select * from user where userId=”1 or userId=2” and password = “111111”;
以${}格式傳入入參后的執行sql:
select * from user where userId=1 or userId=2 and password = 111111;
很顯然,以${}格式傳入入參后的執行sql打亂了我們的預期sql格式及查詢條件,從而實現sql注入。所以,除了order by 等需要傳入數據庫字段等的入參使用${},其他的盡量使用#{}。

查看完整回答
反對 回復 2019-09-14
?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

如果你學過jdbc編程,就知道java提供了2種statement,一種是拼寫式sql語句的statement,這種方式對應你說的$,并且可以輕松的注入攻擊;另一種是preparestatement,這種是預編譯的statement,因為預編譯,執行效率要更高,并且由于其拼寫sql只能用?代替(即字符不需要帶“ ' ”單引號,)它會自動的幫你根據數據類型加上單引號或不加,所以,使用此方式拼寫sql語句不容易被注入攻擊(或者根本不會),這就是對于你說的#。

查看完整回答
反對 回復 2019-09-14
?
白衣染霜花

TA貢獻1796條經驗 獲得超10個贊

mybatis預編譯底層實現原理
MyBatis是如何做到SQL預編譯的呢?其實在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準備好”的方式不僅能提高安全性,而且在多次執行同一個SQL時,能夠提高效率。原因是SQL已編譯好,再次執行時無需再編譯。
總結
#{}:相當于JDBC中的PreparedStatement
${}:是輸出變量的值
簡單說,#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變量的值,是非安全的,存在SQL注入。



查看完整回答
反對 回復 2019-09-14
  • 4 回答
  • 0 關注
  • 1254 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號