前言略,直奔主題..
#{}相當於jdbc中的preparedstatement
${}是輸出變量的值
你可能說不明所以,不要緊我們看2段代碼:
String sql = "select * from admin_domain_location order by ?"; PreparedStatement st = con.prepareStatement(sql); st.setString(1, "domain_id"); System.out.println(st.toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("domain_id"));
}
輸出結果:
com.mysql.jdbc.PreparedStatement@1fa1ba1: select * from admin_domain_location order by 'domain_id'
3
4
5
2
6
這是個jdbc的preparedstatement例子,不要吐槽我這么寫是否合法,這里只是為了說明問題.
以上例子有得出以下信息:
1)order by后面如果采用預編譯的形式動態輸入參數,那么實際插入的參數是一個字符串,例子中是:order by 'domain_id'
2)輸出結果並沒有排序,從sql語句中的形式我們也可以推測出此sql語句根本也不合法(正常應該是 order by domain_id)
修改以上代碼如下:
String input = "domain_id"; String sql = "select * from admin_domain_location order by "+input; PreparedStatement st = con.prepareStatement(sql); System.out.println(st.toString()); ResultSet rs = st.executeQuery(); while(rs.next()){ System.out.println(rs.getString("domain_id")); }
輸出結果:
com.mysql.jdbc.PreparedStatement@1fa1ba1: select * from admin_domain_location order by domain_id
2
3
4
5
6
此次我們直接把一個變量的值拼接sql語句,從結果可以看出來:
1)sql語句拼接正常
2)查詢結果排序正常
你可能要問這和#{}與${}有什么關系..
上面已經說過#{}相當於jdbc的preparedstatement,所以以上的第一個例子就相當於#{},那么第二個例子就自然而然指的是${}的情況.
你可能說思維還是有些凌亂,不要緊我們來看第三個例子:
String sql = "select * from admin_domain_location where domain_id=?"; PreparedStatement st = con.prepareStatement(sql); st.setString(1, "2"); System.out.println(st.toString()); ResultSet rs = st.executeQuery(); while(rs.next()){ System.out.println(rs.getString("domain_id")); } ======================================= String input = "2"; String sql = "select * from admin_domain_location where domain_id='"+input+"'"; PreparedStatement st = con.prepareStatement(sql); System.out.println(st.toString()); ResultSet rs = st.executeQuery(); while(rs.next()){ System.out.println(rs.getString("domain_id")); } 輸出結果都為: com.mysql.jdbc.PreparedStatement@12bf560: select * from admin_domain_location where domain_id='2' 2
這第三個例子說的是#{}和${}通用的問題,也就是說在此種情況下#{}和${}是通用的,只不過需要些小的轉換.如例子中需要手動
拼接單引號 ' ' 到變量值的前后,確保sql語句正常.
簡單說#{}是經過預編譯的,是安全的,而${}是未經過預編譯的,僅僅是取變量的值,是非安全的,存在sql注入.
這里先說一下只能${}的情況,從我們前面的例子中也能看出,order by是肯定只能用${}了,用#{}會多個' '導致sql語句失效.此外還有一個like 語句后也需要用${},簡單想一下
就能明白.由於${}僅僅是簡單的取值,所以以前sql注入的方法適用此處,如果我們order by語句后用了${},那么不做任何處理的時候是存在sql注入危險的.你說怎么防止,那我只
能悲慘的告訴你,你得手動處理過濾一下輸入的內容,如判斷一下輸入的參數的長度是否正常(注入語句一般很長),更精確的過濾則可以查詢一下輸入的參數是否在預期的參數集合中..