JDBC基礎(二):Statement和Preparement
阿新 • • 發佈:2019-01-11
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注入,提高安全性