PrepareStatement與Statement之間的區別
- preparestatement是預編譯,對於批量處理可以大大提高執行效率。
- 如果說所使用的SQL語句是一次性的話,那麼使用statement較好,因為,這樣的話使用preparestatement並不會產生太大的效果,相反,可能還會在效能方面劣於statement。畢竟preparestatement物件開銷比statement較大。
- statement每次執行sql 語句,相關資料庫都要對sql語句進行編譯,而preparestatement則不需要。
- 執行許多SQL語句的JDBC程式產生大量的Statement和PreparedStatement物件。通常認為PreparedStatement物件比Statement物件更有效,特別是如果帶有不同引數的同一SQL語句被多次執行的時候。PreparedStatement物件允許資料庫預編譯SQL語句,這樣在隨後的執行中可以節省時間並增加程式碼的可讀性。
- 在企業應用程式中更喜歡使用PreparedStatement物件是因為它還具有安全性。傳遞給PreparedStatement物件的引數可以被強制進行型別轉換,使開發人員可以確保在插入或查詢資料時與底層的資料庫格式匹配。為什麼我們比較常用PrepareStatement,有位高手跟我們講述了許多,下面我將把它拷貝下來,與大家一同分享:
-
一.程式碼的可讀性和可維護性.
雖然用PreparedStatement來代替Statement會使程式碼多出幾行,但這樣的程式碼無論從可讀性還是可維護性上來說.都比直接用Statement的程式碼高很多檔次:
stmt.executeUpdate( "insert into tb_name (col1,col2,col2,col4) values ( ' "+var1+ " ', ' "+var2+ " ', "+var3+ ", ' "+var4+ " ') ");
perstmt = con.prepareStatement( "insert into tb_name (col1,col2,col2,col4) values (?,?,?,?) ");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多說,對於第一種方法.別說其他人去讀你的程式碼,就是你自己過一段時間再去讀,都會覺得傷心.
二.PreparedStatement盡最大可能提高效能(特別是批量處理時).
每一種資料庫都會盡最大努力對預編譯語句提供最大的效能優化.因為預編譯語句有可能被重複呼叫.所以語句在被DB的編譯器編譯後的執行程式碼被快取下來,那麼下次呼叫時只要是相同的預編譯語句就不需要編譯,只要將引數直接傳入編譯過的語句執行程式碼中(相當於一個涵數)就會得到執行.這並不是說只有一個Connection中多次執行的預編譯語句被快取,而是對於整個DB中,只要預編譯的語句語法和快取中匹配.那麼在任何時候就可以不需要再次編譯而可以直接執行.而statement的語句中,即使是相同一操作,而由於每次操作的資料不同所以使整個語句相匹配的機會極小,幾乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ( '11 ', '22 ');
insert into tb_name (col1,col2) values ( '11 ', '23 ');
即使是相同操作但因為資料內容不一樣,所以整個個語句本身不能匹配,沒有快取語句的意義.事實是沒有資料庫會對普通語句編譯後的執行程式碼快取.這樣每執行一次都要對傳入的語句編譯一次.
當然並不是所以預編譯語句都一定會被快取,資料庫本身會用一種策略,比如使用頻度等因素來決定什麼時候不再快取已有的預編譯結果.以儲存有更多的空間儲存新的預編譯語句.
三.最重要的一點是極大地提高了安全性.
即使到目前為止,仍有一些人連基本的惡義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,;等做費盡心機的判斷和過慮.
相關文章
- Statement和PreparedStatement之間的區別
- Java中Statement與PreparedStatement與CallableStatement之間的區別 - javarevisitedJava
- statement 、prepareStatement的用法和解釋REST
- jdbc Statement和PrepareStatement操作JDBCREST
- JDBC之Statement,PreparedStatement,CallableStatement的區別JDBC
- Oracle與OpenJDK之間的區別OracleJDK
- GCD與NSOperation之間的區別GC
- PHP abstract與interface之間的區別PHP
- prepareStatement和Statement執行批處理的執行情況REST
- 雲與本地部署 ERP 之間的區別
- size resize與capacity reserve之間的區別
- 深度學習與機器學習之間區別 - javaworld深度學習機器學習Java
- [譯]HTML attribute與DOM property之間的區別?HTML
- TCP、UDP、HTTP、SOCKET之間的區別與聯絡TCPUDPHTTP
- 陣列地址與指標之間的區別與聯絡陣列指標
- 大資料分析與機器學習之間的區別與聯絡大資料機器學習
- 淺析HTML、CSS、JavaScript之間的聯絡與區別!HTMLCSSJavaScript
- 簡單介紹HTTP與HTTPS之間的區別HTTP
- Android Bitmap 與 Drawable之間的區別和轉換Android
- 敏捷和 Scrum 之間的區別敏捷Scrum
- java-Statement、PreparedStatement、PreparedStatement + 批處理 的區別Java
- 談談機器學習與傳統程式設計之間的區別機器學習程式設計
- QWidget體系與QGraphicsWidget體系之間的區別
- select、poll、epoll之間的區別
- @Bean和@Component之間的區別?Bean
- MVC,MVP和MVVM之間的區別MVCMVPMVVM
- JavaSE、JavaEE、JavaME之間的區別概述Java
- reboot和init 6之間的區別boot
- WCF、WebAPI、WCFREST、WebService之間的區別WebAPIREST
- 宏旺半導體解答ECC與RECC記憶體之間的區別記憶體
- 《西遊記》管理文化與六西格瑪管理文化之間的區別
- TCP協議與UDP協議以及兩者之間的區別TCP協議UDP
- WCF 服務應用程式與 服務庫之間的區別
- String、StringBuffer與StringBuilder之間區別UI
- querySelector和getElementById之間的區別
- hadoop發行版本之間的區別Hadoop
- tali -f 和 tail -F 之間的區別AI
- 公共雲和私有云之間的區別