PreparStament
-
簡介
通過上面的例子發現,statement存在以下問題
- sql注入的問題
- 動態sql拼接太過麻煩
爲了解決上述問題,那麼我們可以採用一個新的執行SQL語句工具類對象
PreparStament
,有以下好處:- 提供了預編譯功能,避免了SQL注入問題
- 能夠使用動態sql,不需要用戶手動拼接動態sql
-
創建PreparStatement,並執行DML語句
@Test public void preInsertData() throws Exception { Connection connection = ConnectionUtil.getConnection(); // 創建sql語句,如果不確定sql中具體的值,可以用 ?代替 // 簡單的說 :?就是一個佔位符 String sql = "insert into jdbc_test values(?,?,?,?)"; // 創建對象時需要傳入sql語句 PreparedStatement prepareStatement = connection.prepareStatement(sql); /* * 給sql語句注入值,說白了就是替換? 給替換?時需要根據數據類型不同而調用不同的方法 */ // id數據爲int類型,第一個參數爲?的索引,從1開始,第二個參數爲具體的值 prepareStatement.setInt(1,2); prepareStatement.setString(2, "套馬的漢子"); prepareStatement.setDouble(3, 1000); prepareStatement.setDate(4, new Date(System.currentTimeMillis())); // 返回影響條數,執行時不需要傳入SQL int result = prepareStatement.executeUpdate(); System.out.println(result); connection.commit(); prepareStatement.close(); connection.close(); }
-
執行查詢
@Test public void selectData() throws Exception { // 獲取連接 Connection connection = ConnectionUtil.getConnection(); String sql = "select * from jdbc_test where id = ?"; // 創建對象 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 用戶手動輸入數據 Scanner scanner = new Scanner(System.in); String id = scanner.next(); preparedStatement.setInt(1, Integer.parseInt(id)); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { int ids = resultSet.getInt(1); String name = resultSet.getString("name"); double salary = resultSet.getDouble("salary"); System.out.println(ids + ":" + name + ":" + salary); } preparedStatement.close(); connection.close(); }
-
PreparStatement與Statement對比
Statement:
-
創建時不需要傳遞sql語句,但是執行時需要傳遞sql語句。
-
如果涉及到動態參數的傳遞,必須使用字符串拼接-
PreparedStatement:
-
創建時就需要傳遞sql語句,執行的時候不需要傳遞sql語句-
-
如果涉及到動態參數的傳遞,可以使用字符串拼接,也可以使用?佔-
位的形式要求在執行sql語句之前,給?號傳值。 -
提供預編譯的功能,某種程度上可以避免sql注入的問題
-