JDBC中的預編譯語句

什麼是預編譯語句
預編譯語句PreparedStatement 是java.sql中的一個接口,它是Statement的子接口。經過Statement對象執行SQL語句時,須要將SQL語句發送給DBMS,由DBMS首先進行編譯後再執行。預編譯語句和Statement不一樣,在建立PreparedStatement 對象時就指定了SQL語句,該語句當即發送給DBMS進行編譯。當該編譯語句被執行時,DBMS直接運行編譯後的SQL語句,而不須要像其餘SQL語句那樣首先將其編譯。
何時使用預編譯語句
通常是在須要反覆使用一個SQL語句時才使用預編譯語句,預編譯語句經常放在一個for或者while循環裏面使用,經過反覆設置參數從而屢次使用該SQL語句;爲了防止SQL注入漏洞,在某些數據操做中也使用預編譯語句。
爲何使用預編譯語句
一、提升效率
當須要對數據庫進行數據插入、更新或者刪除的時候,程序會發送整個SQL語句給數據庫處理和執行。數據庫處理一個SQL語句,須要完成解析SQL語句、檢查語法和語義以及生成代碼;通常說來,處理時間要比執行語句所須要的時間長。預編譯語句在建立的時候已是將指定的SQL語句發送給了DBMS,完成了解析、檢查、編譯等工做。所以,當一個SQL語句須要執行屢次時,使用預編譯語句能夠減小處理時間,提升執行效率。
二、提升安全性
惡意的SQL語句
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
若是咱們把[' or '1' = '1]做爲varpasswd傳入進來.用戶名隨意,看看會成爲何?
select * from tb_name = '隨意' and passwd = '' or '1' = '1';由於'1'='1'確定成立,因此能夠任何經過驗證.更有甚者:
把[';drop table tb_name;]做爲varpasswd傳入進來,則:select * from tb_name = '隨意' and passwd = '';drop table tb_name;有些數據庫是不會讓你成功的,但也有不少數據庫就可使這些語句獲得執行.
而若是你使用預編譯語句.你傳入的任何內容就不會和原來的語句發生任何匹配的關係.只要全使用預編譯語句,你就用不着對傳入的數據作任何過慮.而若是使用普通的statement,有可能要對drop,;等作費盡心機的判斷和過慮.
預編譯語句的使用
一、建立 PreparedStatement 對象
       如下的代碼段(其中 con 是 Connection 對象)建立包含帶兩個 IN 參數佔位符的 SQL 語句的 PreparedStatement 對象:
  PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");
  pstmt 對象包含語句 "UPDATE table4 SET m = ? WHERE x = ?",它已發送給DBMS,併爲執行做好了準備。
二、傳遞 IN 參數
    在執行 PreparedStatement 對象以前,必須設置每一個 ? 參數的值。這可經過調用 setXXX 方法來完成,其中 XXX 是與該參數相應的類型。例如,若是參數具備Java 類型 long,則使用的方法就是 setLong。setXXX 方法的第一個參數是要設置的參數的序數位置,第二個參數是設置給該參數的值。例如,如下代碼將第一個參數設爲 123456789,第二個參數設爲 100000000:
  pstmt.setLong(1, 123456789);
  pstmt.setLong(2, 100000000);
一旦設置了給定語句的參數值,其值將一直保留,直到被設置爲新值或者調用clearParameters()方法清除它爲止。
示例:
import java.sql.*;
public class PreparedTest{
Connection con=null;
PreparedStatement update=null;
public void test(){
String sql="UPDATE STUDENT SET AGE=? WHERE ID=?";
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:stu","name","password");
}catch(ClassNotFoundException e){}
catch(SQLException ex){}
try{
update=con.prepareStatement(sql);
for(int i=0;i<6;i++){
update.setInt(1,i+18);
update.setInt(2,i);
update.executeUpdate();
}
update.close();
con.close();
}catch(SQLException ex){}
}
}
相關文章
相關標籤/搜索