Java中JDBC原理及使用

目前Mybatis是最主流的,為了學好Mybatis,我們先要搞明白JDBC。JDBC(Java DataBase Connectivity)就是Java數據庫連接,說白了就是用Java語言來操作數據庫。原來我們操作數據庫是在控制檯使用SQL語句來操作數據庫,JDBC是用Java語言向數據庫發送SQL語句。

Java中JDBC原理及使用

1,JDBC是一套協議,是JAVA開發人員和數據庫廠商達成的協議,也就是由Sun定義一組接口,由數據庫廠商來實現,並規定了JAVA開發人員訪問數據庫所使用的方法的調用規範。

2,JDBC的實現是由數據庫廠商提供,以驅動程序形式提供。

3,JDBC在使用前要先加載驅動。

JDBC對於使用者要有一致性,對不同的數據庫其使用方法都是相同的。

驅動開發必須要實現Driver接口。

數據庫驅動的實現方式 :

JDBC-ODBC橋接式

JDBC網絡驅動,這種方式是通過中間服務器的協議轉換來實現的

JDBC+本地驅動,這種方式的安全性比較差。

JDBC驅動,由數據庫廠商實現。

2 JDBC的API及應用步驟

1、java.sql包和javax.sql包

Driver接口(驅動),在加載某一 Driver 類時,它應該創建自己的實例並向 DriverManager 註冊該實例。這意味著用戶可以通過調用以下程序加載和註冊一個驅動程序

Class.forName("oracle.jdbc.driver.OracleDriver")

DriverManager類(驅動管理器),它可以創建連接,它本身就是一個創建Connection的工廠(Factory)。

Connection接口,會根據不同的驅動產生不同的連接

Statement接口,發送sql語句

ResultSet接口(結果集),是用來接收select語句返回的查詢結果的。其實質類似於集合。

2、JDBC應用步驟

執行一次JDBC連接,分六個步驟進行:

1. 導入包

在程序中包含數據庫編程所需的JDBC類。大多數情況下,使用 import java.sql.* 就足夠了

2. 註冊JDBC驅動程序

需要初始化驅動程序,這樣就可以打開與數據庫的通信。

3. 打開一個連接

使用DriverManager.getConnection()方法來創建一個Connection對象,它代表一個數據庫的物理連接。

4. 執行一個查詢

需要使用一個類型為Statement或PreparedStatement的對象(兩者區別看後文),並提交一個SQL語句到數據庫執行查詢。

5. 從結果集中提取數據

這一步中演示如何從數據庫中獲取查詢結果的數據。使用ResultSet.getXXX()方法來檢索的數據結果

6. 清理環境資源

在使用JDBC與數據交互操作數據庫中的數據後,應該明確地關閉所有的數據庫資源以減少資源的浪費。本文使用了try with resources方式關閉資源,這是JDK7的語法糖,讀者可自行搜索。

Java中JDBC原理及使用

注意點:

數據庫資源是非常昂貴的,用完了應該儘快關閉它。Connection, Statement, ResultSet等JDBC對象都有close方法,調用它就好了。

在代碼中必須顯式關閉掉ResultSet,Statement,Connection,如果你用的是連接池的話,連接用完後會放回池裡,但是沒有關閉的ResultSet和Statement就會造成資源洩漏了。

在finally塊中關閉資源,保證即便出了異常也能正常關閉。

大量相似的查詢應當使用批處理完成。

儘量使用PreparedStatement而不是Statement,以避免SQL注入,同時還能通過預編譯和緩存機制提升執行的效率。

如果你要將大量數據讀入到ResultSet中,應該合理的設置fetchSize以便提升性能。

你用的數據庫可能沒有支持所有的隔離級別,用之前先仔細確認下。

數據庫隔離級別越高性能越差,確保你的數據庫連接設置的隔離級別是最優的。

如果你需要長時間對ResultSet進行操作的話,儘量使用離線的RowSet。

4 FAQ

1、JDBC是如何實現Java程序和JDBC驅動的松耦合?

JDBC API使用Java的反射機制來實現Java程序和JDBC驅動的松耦合。看一下上文的JDBC示例,你會發現所有操作都是通過JDBC接口完成的,而驅動只有在通過Class.forName反射機制來加載的時候才會出現。

這是Java核心庫裡反射機制的最佳實踐之一,它使得應用程序和驅動程序之間進行了隔離,讓遷移數據庫的工作變得更簡單。

2、Statement和PreparedStatement區別

關係:PreparedStatement繼承自Statement,兩者都是接口

區別:PreparedStatement可以使用佔位符,而且是預編譯的,批處理比Statement效率高

3、預編譯

創建時的區別:

Java中JDBC原理及使用

執行時的區別:

Java中JDBC原理及使用

由上可以看出,PreparedStatement有預編譯的過程,已經綁定sql,之後無論執行多少次,都不會再去進行編譯,而Statement 不同,如果執行多次,則相應的就要編譯多少次sql,所以從這點看,PreparedStatement的效率會比Statement要高一些。PreparedStatement是預編譯的,所以可以有效的防止SQL注入等問題

4、佔位符

PrepareStatement可以替換變量在SQL語句中可以包含?,可以用?替換成變量。

Java中JDBC原理及使用

而Statement只能用字符串拼接。

int sid = 1001;Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);

5、JDBC的ResultSet

在查詢數據庫後會返回一個ResultSet,它就像是查詢結果集的一張數據表。

ResultSet對象維護了一個遊標,指向當前的數據行。開始的時候這個遊標指向的是第一行。如果調用了ResultSet的next()方法遊標會下移一行,如果沒有更多的數據了,next()方法會返回false。可以在for循環中用它來遍歷數據集。

默認的ResultSet是不能更新的,遊標也只能往下移。也就是說你只能從第一行到最後一行遍歷一遍。不過也可以創建可以回滾或者可更新的ResultSet,像下面這樣。
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

當生成ResultSet的Statement對象要關閉或者重新執行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關閉。

可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數據。

6、ResultSet的不同類型

根據創建Statement時輸入參數的不同,會對應不同類型的ResultSet。如果你看下Connection的方法,你會發現createStatement和prepareStatement方法重載了,以支持不同的ResultSet和併發類型。

ResultSet對象有三種類型。

ResultSet.TYPE_FORWARD_ONLY:這是默認的類型,它的遊標只能往下移。

ResultSet.TYPE_SCROLL_INSENSITIVE:遊標可以上下移動,一旦它創建後,數據庫裡的數據再發生修改,對它來說是透明的。

ResultSet.TYPE_SCROLL_SENSITIVE:遊標可以上下移動,如果生成後數據庫還發生了修改操作,它是能夠感知到的。

ResultSet有兩種併發類型。

ResultSet.CONCUR_READ_ONLY:ResultSet是隻讀的,這是默認類型。

ResultSet.CONCUR_UPDATABLE:我們可以使用ResultSet的更新方法來更新裡面的數據。


Java中JDBC原理及使用


分享到:


相關文章: