1. 程式人生 > >JDBC基礎(二):Statement和Preparement

JDBC基礎(二):Statement和Preparement

Statement物件是用來執行SQL語句的
PreparedStatement:預編譯的Statement物件,是Statement的子介面。

一.效能和程式碼編寫的簡潔程度方面

它允許資料庫預編譯SQL語句(這些SQL語句通常有帶有引數),以後每次只需改變SQL命令的引數,避免資料庫每次都需要編譯SQL語句,提高了效能。
e.g.
連線資料庫部分

//已定義好driver、url、user、passwd等
//載入驅動
Class.forName(driver);
//獲得連線
Connection conn = DriverManager.getConnection(url, user, passwd);

Statement:

//用Connection建立一個Statement
Statement stmt = conn.createStatement() {
    //100條SQL語句來插入100條記錄
    for(int i = 0;i < 100;i++) {
        stmt.executeUpdate("insert into student values(" + "null, 'aaa" + i + "',90)");
    }
}

PreparedStatement:

//用Connection建立一個PreparedStatement
PreparedStatement pstmt = conn,getPreparedStatement("insert into student_table values(null, ?, 90)"
) { //設定引數,100次傳入引數而不是100次傳入SQL語句 for(int i = 0;i < 100;i++) { pstmt.setString(1, "姓名" + i); //執行 pstmt.executeUpdate(); } }

通過執行以上的程式碼可以發現,PreparedStatement插入100條記錄所用的時間比Statement插入100條記錄所花費時間少。而且可以在程式碼中可以看出,帶有引數的SQL語句,建立Statement物件需要對引數進行拼接,但是PreparedStatement會簡潔很多。
完整程式碼移步GitHub:

Statement&PrepareStatement
執行結果:
這裡寫圖片描述

二.安全方面

又因為PreparedStatement不需要拼接,還可以防止SQL注入從而提高安全性
注:SQL注入是一種Cracker入侵方式,從SQL語句的漏洞入侵
比如一個登入頁面,我們在獲取表單傳來的引數,將其與資料庫中的資料進行比對,比對有該賬號密碼時則登入成功:

Statement:

//傳入引數username和passwd是提交的資訊
String sql = "select * from users " + "where username = ' " + username + " ' and password= ' " + passwd + " ';
rs = stmt.executeQuery(sql);

如果在username框中輸入了:’or true or’,那麼,拼接後的SQL語句就變成了:

select * from users where username = ' ' or true or ' ' and desc = ' ';

結果為true被SQL當成直接量那麼直接會登入成功

PreparedStatement:

//傳入引數username和passwd是提交的資訊
PreparedStatement pstmt = conn.getPreparedStatement("select * from users where username = ? and password= ?");
pstmt.setString(1, username);
pstmt.setString(2, passwd);

從上述可以看出PreparedStatement相較於Statement有三個好處:
1. 預編譯,效能較好
2. 不用拼接,易編寫易讀懂
3. 防止SQL注入,提高安全性