本文主要講了PrepareStatement和CreateStatement的作用區別,大家可以一起學習!走后端的小伙伴都會必修JDBC,在前段時間作者實訓期間,看到老師舉例的時候用了CreateStatement(當然老師只是隨便舉得例子)。而本人的個人習慣是用PrepareStatement的,作者之前是很困惑過這兩個之間的區別的,在實踐之后以及看的一些資料積攢了一些看法,在這里和大家談一下CreatStatement和PrepareStatement的作用和區別吧。(圖為老師的案例)
作用:這兩者作用基本一樣,來看兩者代碼的寫法。兩者在JDBC連接數據庫時用法基本一樣,都是創建了一個數據庫的操作對象,然后讓該對象調用excuteQuery執行相應的sql語句。所以在JDBC中這倆其實最后達成的效果是一樣的。
區別:CreateStatement和PrepareStatement的最明顯的區別首先自然是寫法上面了。來直接看代碼:
代碼背景:假設我們數據庫里面有一張關於book的表,里面有bid和bname兩列,現在進行查詢兩列數據這個簡單的操作。
這是用PrepareStatement創建的ps操作對象的過程(為了增強對比性其余片段先省略掉)
//創建sql命令 String sql="select *from book where bid=? and bname=?"; //創建sql操作對象 ps=conn.prepareStatement; //給占位值賦值 ps.setString(1,bid); ps.setString(2,bname); //執行sql命令 rs=ps.executeQuery();
這是用CreatStatement創建的st操作對象的過程
//創建sql命令 String sql="select *from book where bid='"+bid+"' and bname='"+bname"'"; //創建數據庫操作對象 st=conn.createStatement; //執行sql命令 rs=st.executeQuery(sql);
從代碼上相信很多人就可以看出兩個人寫法上的區別了,PrepareStatement和CreateStatement的寫法就是前者將sql語句中的變量抽離出來了。你品,你細品。有沒有從這發現PrepareStatement的一大優點:可讀性強!什么?你沒有發現?如果我們原來數據庫中的book表多了bdescn,bprice,bauthor這三列。我們往這五列添加數據,兩個代碼的樣子又變成什么樣子了呢?
Createment的是這樣的:
String sql = "insert into book (bid,bname,bauthor,bdescn,bprice) values("+var1+'"+var2+"',"+var3+",'"+var4+","+var5+"')";
st = conn.createStatement();
rs = st.executeUpdate(sql);
PrepareStatement是這樣的
String sql = "insert into book (boid,bname,bauthor,bdescn,bprice) values(?,?,?,?,?)"; ps=conn.prepareStatement(sql); ps.setString(1,var1); ps.setString(2,var2); ps.setString(3,var3); ps.setString(4,var4);
ps.setString(5,var5); pst.executeUpdate();
這樣看應該是非常清晰了吧,CreateStatement在寫的時候要注意的太多了,而且標點符號啥的一點都不能錯。否則程序就會報錯,這誰頂得住呀!
當然不止這一個區別。PrepareStatement從“倫理”上面來說應該是誕生於CresteStatement,也就是CreateStatement是它爸!!所以CreateStatement上面的所有優點都被PrepareStatement完美的繼承了。就拿上面的舉例,實際上Createment的工作原理就是將String sql="insert into book values()"執行了多次,而PrepareStatement工作原理則相反,是先將相應的sql語句編譯好,之后有對象執行這條sql語句時,直接調用相應編譯好的sql語句時就好。所以后者的工作效率就會明顯的比前者高,當然也就更加靈活啦。
最后,就是最重要的一個區別了。那就是PrepareStatement的安全性比“他爸”高了非常多,你在看上面的代碼,你品,你細品。如果看不出來的話我給大家換一個,如果使用CreateStatement創造數據庫操作對象去驗證用戶的賬號密碼的時是不是下面這么操作的呢?
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
st = conn.createStatement();
rs = st.executeUpdate(sql);
有沒有感覺有什么不對的地方呢??你看,假使我們在知道一個用戶的用戶名卻不知道密碼的時候,將or '1' = '1'當作密碼傳進去會發生什么呢?句子就變成這樣子了select * from user where username = 'user' and userpwd = '' or '1' = '1'是不是就會驚奇的發現,這竟然是一個恆等式!!所以想要得到你的權限去干事情就變得非常簡單,比如添加一個在'or '1' = 1'添加一個drop table book是不是你這一個表就消失了呢?而用它的“兒子”就完全不會出現這種情況,因為PrepareStatement在運行的過程中都是獨立的,數據也都是獨立運行的,所以影響沒有那么大的!
好啦,就講到這了,希望可以給你一點幫助!