JDBC-預防SQL注入-預處理對象PrepareStatement

PreparedStatement接口介紹

  • PreparedStatementStatement接口的子接口,繼承於父接口中全部的方法.它是一個預編譯的SQL語句對象
  • 預編譯: 是指SQL語句被預編譯,並存儲在PreparedStatement對象中. 而後可使用此對象屢次市郊地執行該語句

PreparedStatement特色

  • 由於有預先編譯的功能, 提升SQL的執行效率
  • 能夠有效的防止SQL注入的問題,安全性更高

獲取PreparedStatement對象

Statement相似, 都是經過Connection進行建立建立sql

Connection接口中的方法 說明
PreparedStatement prepareStatement(String sql) 指定預編譯的SQL語句
  • 預編譯的SQL語句: SQL語句中使用佔位符?

PreparedStatement接口經常使用方法

  • Statement相似,接口經常使用方法名都是int executeUpdate()ResultSet executeQuery
  • Statement不一樣,上述兩個方法是沒有參數的.由於在構造PrepareStatement對象時,就已經傳入SQL進行了預編譯
經常使用方法 說明
int executeUpdate() 執行insert / update / delete 語句.返回受影響的行數
ResultSet executeQuery() 執行select語名.返回結果集對象Result

使用PreparedStatement的步驟

  • 編定SQL語句,未知內容使用 ? 佔位
    select * from test_02 where name = ? and password = ?
  • 獲取PreparedStatement對象
  • 設置實際參數: 調用setXxx方法
  • 執行參數化SQL
  • 關閉資源

使用PreparedStatement完成登陸案例

代碼示例

public class LoginTest02 {

    public static void main(String[] args) throws SQLException {

        // 1.獲取鏈接
        Connection conn = JDBCUtils.getConnection();
        // 2.使用佔位符建立sql語句,獲取prepareStatement對象
        // 使用?佔位符的方式來設置參數
        String sql = "select * from test_02 where name = ? and password = ?";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        // 3.提示用戶輸入用戶名和密碼
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入用戶名:");
        String user = sc.next();
        System.out.println("請輸入密碼:");
        String pass = sc.next();
        // 4.替換佔位符,執行sql語句
        // 設置參數,使用setXXX(int 佔位符位置 從1開始, 要設置/替換的值)的方法設置佔位符的參數
        preparedStatement.setString(1,user); // 設置第一個問號值爲name
        preparedStatement.setString(2,pass);
        ResultSet resultSet = preparedStatement.executeQuery();
        // 5.處理結果集,判斷是否登陸成功
        if(resultSet.next()){
            System.out.println("登陸成功!歡迎:" + user);
        }else{
            System.out.println("登陸失敗!");
        }
        // 6.關閉對象
        JDBCUtils.close(conn,preparedStatement,resultSet);
    }
}

運行結果(正常)

image.png

運行結果(SQL注入)

image.png

這裏提示登陸失敗,也就是SQL注入的方式沒有成功.
緣由是: 剛剛咱們使用了?做爲佔位符,那麼在輸入密碼時,不管輸入什麼,其實都會總體以String形式賦值給sql語句.
因此這裏最終的sql語句實際上是select * from test_02 where name = 'wdm' and password = "'0704' or '1' = '1' ". 很明顯, 這個就不會返回正常結果數據庫

PreparedStatement的執行原理

image.png

Statement與PrepareStatement的區別

  • Statement用於執行靜態SQL語句,在執行時,必須指定一個事先準備好的SQL語句
  • PreparedStatement是預編譯的SQL語句對象,語句中能夠包含動態參數"?", 在執行時能夠爲"?"動態設置參數值
  • PreparedStatement能夠減小編譯次數提升數據庫性能
相關文章
相關標籤/搜索