JDBC之statement與preparedstatement的區別

昨天寫了一篇jdbc的基本使用步驟,裏面創建的sql命令發送器是statement,其實開發過程中,一般不使用這個,使用的是preparedstatment
–statement的缺點:

1.可讀性差,比如登錄需要字符串拼接,不直觀
2.效率低下,在講解preparedstatement時會分析這個
3.不安全,sql注入漏洞

下面我們使用statement模擬用戶登錄來講解這些缺點

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
Statement stmt = conn.createStatement();
//模擬用戶輸入賬號密碼
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入賬號:");
String uname = scanner.next();
System.out.println("請輸入密碼:");
String upassword = scanner.next();
//使用拼接,語句比較繁瑣
String sql = "select * from t_user where uname = '"+uname+"' and upassword = '"+upassword+"'";
//執行sql時,如果用戶在輸入賬號或密碼時使用or拼接一個true條件,那麼這個條件都爲真,這種情況就叫sql注入,不知道密碼賬號也能登錄,例如:uname = aaa' or '1 = 1  或者upassword = aaa' or '1 = 1;
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()){//如果有下一行返回true
    System.out.println("登錄成功");
}else{
    System.out.println("登錄失敗");
}
--------------------------------
還有多次執行更新或者查詢,雖然語句相似但是每次都要重新編譯,效率低下
sql = "update ..where uid = 11";
sql = "update ..where uid = 22";
sql = "update ..where uid = 33";

使用preparedsatement可解決以上問題
preparedstatement:預處理,預編譯;獻上代碼和註釋一起理解它

//準備sql模板,供pstmt預編譯加載到內存中
String sql = "select * from t_user where uname = ? and upassword = ?";//?代表佔位符,內存會根據後面我們給的數據自動補充語句
//好處1,防止sql注入;2,代碼明瞭,不需要自己拼接字符串
PreparedStatement pstmt = conn.preparedStatement(sql);
//上面的sql語句並未執行,只是加載到內存了預編譯好了
//下面就是給問號賦值
pstmt.setString(1,"username");//這裏1代表第一個問號,後面跟的是賦的值
pstmt.setString(2,"password");//2,第二個問好,setXXX()根據表的結構選擇
//防注入的原理是預編譯之後,preparedstatement不允許在填充數據的時候改變他的邏輯結構了
ResultSet rs = pstmt.executeQuery();//這裏纔是真正執行SQL語句
if(rs.next()){
System.out.println("登錄成功");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章