[JDBC]PreparedStatement vs Statement

KouWei.Lee
5 min readSep 1, 2020

--

優先使用PreparedStatement 理由:預先編譯 安全性佳 批次執行速度快

Photo by Maximilian Weisbecker on Unsplash

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

預先編譯 安全性佳 批次執行速度快

參考

--

--

No responses yet