4 回答

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊
首先通過下面兩條sql及打印的執(zhí)行sql,清楚明了的看一下它們的區(qū)別:
<select id="selectUserInfo" parameterType="java.util.Map" resultType="java.util.Map">
select
*
from
user
where
userId=${id} password=#{pwd}
</select>12345678
假設(shè)入?yún)魅氲氖?,打印執(zhí)行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
同樣入?yún)魅?,打印的執(zhí)行sql如下:
Preparing:select * from user where id=? and password=?
Parameters:1(String),111111(String)
MyBatis啟用了預(yù)編譯功能,在SQL執(zhí)行前,會先將上面的SQL發(fā)送給數(shù)據(jù)庫進(jìn)行編譯;執(zhí)行時(shí),如果入?yún)?{}格式的,將入?yún)⑻鎿Q編譯好的sql中的占位符“?”;如果入?yún)⒏袷綖?{},則直接使用編譯好的SQL就可以了。因?yàn)镾QL注入只能對編譯過程起作用,所以使用#{}入?yún)⒌姆绞娇梢院芎玫乇苊饬薙QL注入的問題。
mybatis預(yù)編譯底層實(shí)現(xiàn)原理
MyBatis是如何做到SQL預(yù)編譯的呢?其實(shí)在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準(zhǔn)備好”的方式不僅能提高安全性,而且在多次執(zhí)行同一個(gè)SQL時(shí),能夠提高效率。原因是SQL已編譯好,再次執(zhí)行時(shí)無需再編譯。
總結(jié)
#{}:相當(dāng)于JDBC中的PreparedStatement
${}:是輸出變量的值
簡單說,#{}是經(jīng)過預(yù)編譯的,是安全的;${}是未經(jīng)過預(yù)編譯的,僅僅是取變量的值,是非安全的,存在SQL注入。
番外(sql注入)
還是以上面的兩條sql為例,入?yún)d的值傳入“1 or userId=2”,入?yún)wd的值傳入“111111”。以#{}格式傳入入?yún)⒑蟮膱?zhí)行sql:
select * from user where userId=”1 or userId=2” and password = “111111”;
以${}格式傳入入?yún)⒑蟮膱?zhí)行sql:
select * from user where userId=1 or userId=2 and password = 111111;
很顯然,以${}格式傳入入?yún)⒑蟮膱?zhí)行sql打亂了我們的預(yù)期sql格式及查詢條件,從而實(shí)現(xiàn)sql注入。所以,除了order by 等需要傳入數(shù)據(jù)庫字段等的入?yún)⑹褂?{},其他的盡量使用#{}。

TA貢獻(xiàn)1911條經(jīng)驗(yàn) 獲得超7個(gè)贊

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊
mybatis預(yù)編譯底層實(shí)現(xiàn)原理
MyBatis是如何做到SQL預(yù)編譯的呢?其實(shí)在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準(zhǔn)備好”的方式不僅能提高安全性,而且在多次執(zhí)行同一個(gè)SQL時(shí),能夠提高效率。原因是SQL已編譯好,再次執(zhí)行時(shí)無需再編譯。
總結(jié)
#{}:相當(dāng)于JDBC中的PreparedStatement
${}:是輸出變量的值
簡單說,#{}是經(jīng)過預(yù)編譯的,是安全的;${}是未經(jīng)過預(yù)編譯的,僅僅是取變量的值,是非安全的,存在SQL注入。
- 4 回答
- 0 關(guān)注
- 1248 瀏覽
添加回答
舉報(bào)