標籤:最大 輸入 select into too sts injection 相同 語句
可以通過調用 Connection 對象的 preparedStatement() 方法擷取 PreparedStatement 對象。
PreparedStatement 介面是 Statement 的子介面,它表示一條先行編譯過的 SQL 陳述式。
PreparedStatement 對象所代表的 SQL 陳述式中的參數用問號(?)來表示,調用 PreparedStatement 對象的 setXXX() 方法來設定這些參數. setXXX() 方法有兩個參數,第一個參數是要設定的 SQL 陳述式中的參數的索引(從 1 開始),第二個是設定的 SQL 陳述式中的參數的值。
PreparedStatement 和 Statement 比較
1、代碼的可讀性和可維護性.
2、PreparedStatement 能最大可能提高效能:
DBServer會對先行編譯語句提供效能最佳化。因為先行編譯語句有可能被重複調用,所以語句在被DBServer的編譯器編譯後的執行代碼被緩衝下來,那麼下次調用時只要是相同的先行編譯語句就不需要編譯,只要將參數直接傳入編譯過的語句執行代碼中就會得到執行。
在statement語句中,即使是相同操作但因為資料內容不一樣,所以整個語句本身不能匹配,沒有緩衝語句的意義.事實是沒有資料庫會對普通語句編譯後的執行代碼緩衝.這樣每執行一次都要對傳入的語句編譯一次.
(語法檢查,語義檢查,翻譯成二進位命令,緩衝)
3、PreparedStatement 可以防止 SQL 注入。
例子:
@Test public void testPreparedStatement() { Connection connection = null; PreparedStatement preparedStatement = null; try { connection = JDBCTools.getConnection(); String sql = "INSERT INTO customers (name, email, birth) " + "VALUES(?,?,?)"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, "soyoungboy"); preparedStatement.setString(2, "[email protected]"); preparedStatement.setDate(3, new Date(new java.util.Date().getTime())); preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.releaseDB(null, preparedStatement, connection); } }SQL 插入式攻擊
概念:
SQL 注入是利用某些系統沒有對使用者輸入的資料進行充分的檢查,而在使用者輸入資料中注入非法的 SQL 陳述式段或命令,從而利用系統的 SQL 引擎完成惡意行為的做法。
對於 Java 而言,要防範 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了。
sql注入例子:
/** * SQL 注入. */ @Test public void testSQLInjection() { String username = "a‘ OR PASSWORD = "; String password = " OR ‘1‘=‘1"; String sql = "SELECT * FROM users WHERE username = ‘" + username + "‘ AND " + "password = ‘" + password + "‘"; System.out.println(sql); Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { connection = JDBCTools.getConnection(); statement = connection.createStatement(); resultSet = statement.executeQuery(sql); if (resultSet.next()) { System.out.println("登入成功!"); } else { System.out.println("使用者名稱和密碼不匹配或使用者名稱不存在. "); } } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.releaseDB(resultSet, statement, connection); } }
使用PreparedStatement 解決sql注入例子:
/** * 使用 PreparedStatement 將有效解決 SQL 注入問題. */ @Test public void testSQLInjection2() { String username = "a‘ OR PASSWORD = "; String password = " OR ‘1‘=‘1"; String sql = "SELECT * FROM users WHERE username = ? " + "AND password = ?"; Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connection = JDBCTools.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, username); preparedStatement.setString(2, password); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { System.out.println("登入成功!"); } else { System.out.println("使用者名稱和密碼不匹配或使用者名稱不存在. "); } } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.releaseDB(resultSet, preparedStatement, connection); } }
Java -- JDBC 學習--PreparedStatement