預先編譯可以防止sql注入的原因:允許資料庫做參數化查詢。在使用參數化查詢的情況下,資料庫不會將參數的內容視為SQL執行的一部分,而是作為一個欄位的屬性值來處理,這樣就算參數中包含破環性語句(or '1=1' )也不會被執行。
PreparedStatement為什麼能在某種程度上防止SQL注入?
PreparedStatement會對SQL進行了預編譯,在第一次執行SQL前資料庫會進行分析、編譯和最佳化,同時執行計畫同樣會被快取起來,它允許資料庫做參數化查詢。在使用參數化查詢的情況下,資料庫不會將參數的內容視為SQL執行的一部分,而是作為一個欄位的屬性值來處理,這樣就算參數中包含破環性語句(or '1=1' )也不會被執行。
推薦課程:Java教學
怎麼使用PreparedStatement?如何避免SQL注入式攻擊? PreparedStatement與Statement有什麼差別,有什麼樣的優點?
一個PreparedStatement簡單範例
public class JDBCTest { public static void main(String[] args) { //表示使用Unicode字符集;字符编码设置为utf-8;不使用SSL连接 String URL = "jdbc:mysql://127.0.0.1:3306/sampledb?useUnicode=true&" + "characterEncoding=utf-8&useSSL=false"; String USER = "spring4";//用户 String PASSWORD = "spring4";//密码 Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { //1.加载驱动程序到JVM Class.forName("com.mysql.jdbc.Driver"); //2.创建数据库连接 conn = DriverManager.getConnection(URL, USER, PASSWORD); //3.创建Statement,实现增删改查 String sql = "select user_id,user_name,credits from t_user where credits > ?"; st = conn.prepareStatement(sql);//这里使用PreparedStatement st.setInt(1, 8); //4.向数据库发送SQL命令 rs = st.executeQuery(); //5.使用ResultSet处理数据库的返回结果 while (rs.next()) { System.out.println(rs.getLong("user_id") + " " + rs.getString("user_name") + " " + rs.getString("credits")); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { //6.关闭资源 try { rs.close(); st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
#Statement的幾個實作
Statement 物件用於將SQL語句傳送到資料庫中。
Statement每次執行SQL語句,資料庫都要執行SQL語句的編譯,最好用於只執行一次查詢並傳回結果的情形
1、執行靜態SQL語句。通常透過Statement實例實現。
2、執行動態SQL語句。通常透過PreparedStatement實例實現。
3、執行資料庫預存程序。通常透過CallableStatement實例實現。
'#'和'$'的區別
sql 預編譯指的是資料庫驅動在傳送sql 語句和參數給DBMS 之前對sql 語句進行編譯,這樣DBMS 執行sql 時,就不需要重新編譯。
‘#{ }’:解析為一個 JDBC 預編譯語句(prepared statement)的參數標記符,一個‘ #{ }’ 解析為一個參數佔位符 ? 。
‘${ }’ 只為純粹的 string 替換,在動態 SQL 解析階段將會進行變數替換。在預編譯之前已經被變數取代了
‘${ }’變數的替換階段是在動態 SQL 解析階段,而’#{ }’變數的替換則是在 DBMS 中。
PreparedStatement與Statement有什麼區別
1.PreparedStatement能預編譯,這條預編譯的SQL查詢語句能在將來的查詢中重複使用,這樣一來,它比Statement物件產生的查詢速度更快。
2.PreparedStatement可以寫動態參數化的查詢
3.PreparedStatement可以防止SQL注入式攻擊
4.PreparedStatement查詢可讀性更好,追蹤條件的語句很亂
5.PreparedStatement不允許一個佔位符(?)有多個值
以上是為什麼預編譯可以防止sql注入的詳細內容。更多資訊請關注PHP中文網其他相關文章!