[JDBC]PreparedStatement vs Statement
5 min readSep 1, 2020
優先使用PreparedStatement 理由:預先編譯 安全性佳 批次執行速度快
PreparedStatement 預先編譯執行速度佳
會先初始化SQL再將SQL數據庫處理
適合重複執行SQL命令
安全性高於避免被注入sql語法
Statement無預處理,每次都由0開始執行
creatstatement每次執行sql語句,相關數據庫都要執行sql語句的編譯
只適合一次性查詢
最大差異
最大差別在於PreparedStatement可以替換變量
PreparedStatement可以替換變量
不必重複SQL語句的句法而只需更改其中變量的值
便可重新執行SQL語句
Statement Code
String updateString = "UPDATE COFFEES SET SALES = 75 " + "WHERE COF_NAME LIKE ′Colombian′";stmt.executeUpdate(updateString);-------------------------------------
//如果要更新其他欄位以及數值就要整個sql重寫
PreparedStatement Code
PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");updateSales.setInt(1, 75);updateSales.setString(2, "Colombian");updateSales.executeUpdate();
-------------------------------------
//要更新其他欄位只需要使用 Set型別(參數(?)位置 , value )將?替換
PreparedStatement可以預防注入
原因:採用預先編譯
範例
1.不使用set方法設置參數相當於Statement
String param = "'test' or 1=1";String sql = "select file from file where name = " + param;
// 拼接SQL參數 PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); System.out.println(resultSet.next())
-------------------------------
輸出 為 true-- 永真條件1=1成為了查詢條件的一部分,可以返回所有數據,造成了SQL注入問題
2.使用PreparedStatement的set方法設置參數
String param = "'test' or 1=1"; String sql = "select file from file where name = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, param); ResultSet resultSet = preparedStatement.executeQuery(); System.out.println(resultSet.next());
------------------------------------
輸出 為 false
因為使用 PreparedStatement 所以傳入的內容不會跟原本的sql有關係
使用預先編譯 setString方法(因為其它設置參數的方法諸如setInt,setDouble之類,編譯器會檢查參數類型,已經避免了SQL注入)
總結
PreparedStatement
預先編譯 安全性佳 批次執行速度快
參考