JDBC與Statement和PreparedStatement的區別

来源:https://www.cnblogs.com/mingmingmomo/archive/2018/07/16/9318519.html
-Advertisement-
Play Games

一、先來說說,什麼是java中的Statement:Statement是java執行資料庫操作的一個重要方法,用於在已經建立資料庫連接的基礎上,向資料庫發送要執行的SQL語句。具體步驟: 1.首先導入java.sql.*;這個包。 2.然後載入驅動,創建連接,得到Connection介面的的實現對象 ...


一、先來說說,什麼是java中的Statement:Statement是java執行資料庫操作的一個重要方法,用於在已經建立資料庫連接的基礎上,向資料庫發送要執行的SQL語句。具體步驟:

  1.首先導入java.sql.*;這個包。

  2.然後載入驅動,創建連接,得到Connection介面的的實現對象,比如對象名叫做conn。

  3.然後再用conn對象去創建Statement的實例,方法是:Statement stmt = conn.creatStatement("SQL語句字元串");

  Statement 對象用於將 SQL 語句發送到資料庫中。實際上有三種 Statement 對象,它們都作為在給定連接上執行 SQL語句的包容器:Statement、PreparedStatement(它從 Statement 繼承而來)和CallableStatement(它從 PreparedStatement 繼承而來)。它們都專用於發送特定類型的 SQL 語句:Statement 對象用於執行不帶參數的簡單 SQL 語句;PreparedStatement 對象用於執行帶或不帶參數的預編譯 SQL 語句;CallableStatement 對象用於執行對資料庫已存儲過程的調用。

  綜上所述,總結如下:Statement每次執行sql語句,資料庫都要執行sql語句的編譯,最好用於僅執行一次查詢並返回結果的情形,效率高於PreparedStatement.但存在sql註入風險。PreparedStatement是預編譯執行的。在執行可變參數的一條SQL時,PreparedStatement要比Statement的效率高,因為DBMS預編譯一條SQL當然會比多次編譯一條SQL的效率高。安全性更好,有效防止SQL註入的問題。對於多次重覆執行的語句,使用Prepared

Statement效率會更高一點。執行SQL語句是可以帶參數的,並支持批量執行SQL。由於採用了Cache機制,則預編譯的語句,就會放在Cache中,下次執行相同的SQL語句時,則可以直接從Cache中取出來。

PreparedStatement pstmt  =  con.prepareStatement("UPDATE EMPLOYEES  SET name= ? WHERE ID = ?");
pstmt.setString(1, "李四");
pstmt.setInt(2, 1);
pstmt. executeUpdate();

  那麼CallableStatement擴展了PreparedStatement的介面,用來調用存儲過程,它提供了對於輸入和輸出參數的支持,CallableStatement 介面還有對 PreparedStatement 介面提供的輸入參數的sql查詢的支持。

PreparedStatement: 資料庫會對sql語句進行預編譯,下次執行相同的sql語句時,資料庫端不會再進行預編譯了,而直接用資料庫的緩衝區,提高數據訪問的效率(但儘量採用
使用?號的方式傳遞參數),如果sql語句只執行一次,以後不再復用。 從安全性上來看,PreparedStatement是通過?來傳遞參數的,避免了拼sql而出現sql註入的問題,所以安全性較好。 在開發中,推薦使用 PreparedStatement

二、

本人的幾點淺見,各位大大不喜勿噴。

先說下這倆到底是幹啥的吧。其實這倆乾的活兒都一樣,就是創建了一個對象然後去通過對象調用executeQuery方法來執行sql語句。說是CreateStatement和PrepareStatement的區別,但其實說的就是Statement和PrepareStatement的區別,相信大家在網上已經看到過不少這方面的資料和博客,我在此處提幾點,大家看到過的,就當重記憶,沒看到就當補充~下麵開始談談他們的區別。

最明顯的區別,就是執行的sql語句格式不同。我們往上放兩段代碼來看看他們的區別把:

代碼背景:我們有一個資料庫,裡面有一個user表,有username,userpwd兩列。我們要查出這兩列的數據。

這是使用CreateStatement方法創建了stmt對象,再通過他查詢的一部分語句片段。

String sql = "select * from users where  username= '"+username+"' and userpwd='"+userpwd+"'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);

  而下麵則是使用了PrepareStatement方法創建了pstmt對象,再通過這個對象查詢的一部分語句片段。

String sql = "select * from users where  username=? and userpwd=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, userpwd);
rs = pstmt.executeQuery();

  相信寫到這,大家很多人就能看出來了,原來PrepareStatement跟Statement的主要區別就是把上面sql語句中的變數抽出來了。這就是我要說的第一大優點,PrepareStatement可以提高代碼的可讀性。

 

下麵說說第二點優點。ParperStatement提高了代碼的靈活性和執行效率。

PrepareStatement介面是Statement介面的子介面,他繼承了Statement介面的所有功能。它主要是拿來解決我們使用Statement對象多次執行同一個SQL語句的效率問題的。ParperStatement介面的機制是在資料庫支持預編譯的情況下預先將SQL語句編譯,當多次執行這條SQL語句時,可以直接執行編譯好的SQL語句,這樣就大大提高了程式的靈活性和執行效率。

 

最後但也是最重要的一個大大的比Statement好的優點,那就是安全!

你說啥?這還關安全啥事兒,那我給你一行代碼,你來給我說說這是幹嘛的。

String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);

  這是驗證用戶名密碼的,對吧。但要是我們把'or '1' = 1'當作密碼傳進去,你猜猜會發生啥。

select * from user where username = 'user' and userpwd = '' or '1' = '1';

  發現了吧!這是個永真式,因為1永遠等於1。所以不管怎樣都能獲取到許可權。哇。這就壞咯!這還不是最壞的,你再看!

String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);

  依舊是這行代碼。這次我們把'or '1' = 1';drop table book;當成密碼傳進去。哇!又壞了!這次直接把表給刪了。但是,你如果用PrepareStatement的話就不會出現這種問題。你傳入的這些數據根本不會跟原來的數據有任何的交集,也不會發生這些問題。

 

 對資料庫進行增刪改查的過程中的通用的流程:

  (1)創建Connection對象、SQL查詢命令字元串;

  (2)對Connection對象傳入SQL查詢命令,獲得PreparedStatement對象;

  (3)對PreparedStatement對象執行executeUpdate()或executeQurey()獲得結果;

  (4)先後關閉PreparedStatement對象和Connection對象。

  可見,使用JDBC時,最常打交道的是Connection、PreparedStatement這兩個類,以及select中的ResultSet類。查閱Java API手冊可以瞭解其具體的意義和方法。

  下麵引用的Java API的資料出自http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/index.html

  

  Connection

java.sql 
介面 Connection

所有超級介面:
Wrapper

public interface Connectionextends Wrapper

 

與特定資料庫的連接(會話)。在連接上下文中執行 SQL 語句並返回結果。

Connection 對象的資料庫能夠提供描述其表、所支持的 SQL 語法、存儲過程、此連接功能等等的信息。此信息是使用 getMetaData 方法獲得的。

 

  PreparedStatemnt

java.sql 
介面 PreparedStatement

所有超級介面:
StatementWrapper
所有已知子介面:
CallableStatement

public interface PreparedStatementextends Statement

表示預編譯的 SQL 語句的對象。

SQL 語句被預編譯並存儲在 PreparedStatement 對象中。然後可以使用此對象多次高效地執行該語句。

 

常用方法

 boolean  execute()

          在此 PreparedStatement 對象中執行 SQL 語句,該語句可以是任何種類的 SQL 語句。

 ResultSet  executeQuery()

          在此 PreparedStatement 對象中執行 SQL 查詢,並返回該查詢生成的 ResultSet 對象。

 int  executeUpdate()

          在此 PreparedStatement 對象中執行 SQL 語句,該語句必須是一個 SQL 數據操作語言(Data Manipulation Language,DML)語句,比如 INSERT、UPDATE 或 DELETE 語句;或者是無返回內容的 SQL 語句,比如 DDL 語句。

  

  ResultSet

  

java.sql 
介面 ResultSet

所有超級介面:
Wrapper
所有已知子介面:
CachedRowSetFilteredRowSetJdbcRowSetJoinRowSetRowSetSyncResolverWebRowSet

public interface ResultSetextends Wrapper

表示資料庫結果集的數據表,通常通過執行查詢資料庫的語句生成。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 鎖的定義,游標的新建和應用,存儲過程的新建,查看,修改和刪除 ...
  • 當同時排序又分頁時,如果排序的欄位X不是唯一欄位,當多個記錄的X欄位有同一個值時順序是 隨機 的。 這個有可能造成分頁時數據重覆的問題。某一頁又把上一頁的數據查出來了,其實資料庫只有一條記錄。 解決辦法: 如果排序欄位不是唯一的,則增加個二級排序,二級排序的欄位要是 唯一 的(例如id)。 ...
  • 一.概述 與其它資料庫不同,mysql 可以運行不同的sql model 下, sql model 定義了mysql應用支持的sql語法,數據校驗等,這樣更容易在不同的環境中使用mysql。 sql model 常用來解決下麵幾類問題 (1) 通過設置sql mode, 可以完成不同嚴格程度的數據校 ...
  • 恢復內容開始 sqlcode sqlstate 說明000 00000 SQL語句成功完成01xxx SQL語句成功完成,但是有警告+012 01545 未限定的列名被解釋為一個有相互關係的引用+098 01568 動態SQL語句用分號結束+100 02000 沒有找到滿足SQL語句的行+110 0 ...
  • 1. 介紹 PostgreSQL提供了一個copy命令的便利數據載入工具,copy命令源於PostgreSQL資料庫,copy命令支持文件與表之間的數據載入和表對文件的數據卸載。pg_bulkload是一種用於PostgreSQL的高速數據載入工具,相比copy命令。最大的優勢就是速度。優勢在讓我們 ...
  • MongoDB 複製(副本集) MongoDB複製是將數據同步在多個伺服器的過程。 複製提供了數據的冗餘備份,併在多個伺服器上存儲數據副本,提高了數據的可用性, 並可以保證數據的安全性。 複製還允許您從硬體故障和服務中斷中恢複數據。 什麼是複製? 保障數據的安全性 數據高可用性 (24 7) 災難恢 ...
  • 最近公司做一個項目用到了mongodb,下麵來介紹一下MongoRepository介面。 大家可以類比Hibernate的jpa,MongoRepository是一個springdata提供的一個有增刪改查以及分頁等操作的基本介面。 我們在使用介面時,只需要定義一個dao層的介面,例如: inte ...
  • 返回 "ProxySQL系列文章:http://www.cnblogs.com/f ck need u/p/7586194.html"   1.不同類型的讀寫分離 資料庫中間件最基本的功能就是實現讀寫分離,ProxySQL當然也支持。而且ProxySQL支持的路由規則非常靈活,不僅可以實現 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...