-
加載數據庫驅動:
1)由於Java是一個純面向對象語言,任何事物在其中都必須抽象成類或者類對象,數據庫也不例外,JDBC同樣也把數據庫抽象成面向對象的結構;
2)JDBC將整個數據庫驅動器在底層抽象成一個對象(即驅動器對象),所有對數據庫的操作都可以通過該對象進行;
3)只不過數據庫驅動對象和普通的Java對象有所不同:
i. 首先大多數普通的Java對象都是運行該Java程序前不存在的,而是運行的時候臨時創建的,程序退出后這些對象也隨之釋放; ii. 但數據庫不一樣,數據庫往往是不依賴程序運行的,數據庫通常都是24小時持續運行,只不過應用程序可以訪問它而已,因此數據庫對象不能像普通對象那樣從無到有地“創建”; iii. 也就是說一個在應用程序運行之前就已經存在並且正常運行的數據庫實例如何在Java程序中訪問呢?
4)加載數據庫驅動的方法:
i. 加載數據庫驅動其實就是將操作系統中正在運行的數據庫進程(實例)轉化成Java對象供Java程序使用(操作數據庫); ii. 這里首先要了解以下類驅動器的概念: a. 其實在Java中任何類(Object、String等)想要正常運行,底層都要有相應的驅動器驅動它; b. 但是我們平時看不出來這些類對象需要什么驅動器驅動啊!那是因為這些基礎類的驅動器就是JVM虛擬機本身,其驅動的加載是在底層伴隨着JVM的啟動進行的,都對用戶隱藏起來了,所以你看不到; c. 而那些不依賴虛擬機驅動的程序(比如非常典型的就是數據庫程序、大多數圖形程序,基本都是用C/C++編寫,肯定不能靠JVM驅動)想在Java中訪問就必須自己手動編寫加載驅動器的代碼了!! iii. 手動加載類的驅動器——使用Class類的forName靜態方法:static Class<?> Class.forName(String className); a. className就是那個不依賴JVM驅動的外部進程的Java類名,這個類名必須符合Java命名規則,例如“com.xxx.Xxx"之類的; b. 你在Java中訪問外部進程(將外部進程抽象成Java類或者對象)還一定要有Java類名?那這個類名是不是要事先就准備好咯? c. 是的!並不是任何外部進程都可以被Java訪問,想要被Java訪問就必須讓那個程序自己准備好被Java調用的接口,並事先命名好Java類名才行,而程序准備好的Java接口就是該程序的Java驅動器(讓JVM控制程序行為的東西就是Java驅動器); d. 因此數據庫廠商必須自行別寫好數據庫的Java驅動器(稱作數據庫Connector,即連接器,用於和Java程序連接),並准備好類名,好讓Class.forName加載它; iv. forName的加載原理: a. 首先任意一個提供Java接口的程序都會擁有一個Java類名(加載到JVM中就是用該類名來訪問該程序實例的); b. 這樣的程序運行后,這個Java類名就會被記錄到改程序的進程信息中(而改程序的Java接口(驅動器)的句柄也會被記錄到進程信息中); c. forName傳入該類名以后就會到操作系統的進程表中查找具有該Java類名的線程; d. 找到對應的進程后就會找到該進程對應的Java驅動,然后將該驅動加載進JVM; e. 之后就可以在Java程序中通過這個類名(或者對象)來調用該進程的功能,或者訪問進程中的數據了;
5)數據庫廠商對驅動類名的命名:
i. 廠商之間各不相同,而且也沒有規律可循,因此必須要查閱相應廠商的JDBC手冊才能知道; ii. MySQL的命名:com.sql.jdbc.Driver iii. Oracle的命名:oracle.jdbc.driver.OracleDriver iv. 從命名的包路徑來看,各個廠商驅動的實現差異較大; 因此MySQL數據庫的加載就是:Class.forName("com.sql.jdbc.Driver");
6)准備好數據庫連接器:
i. 必須事先將數據庫的JDBC-Connector加入到CLASSPATH路徑當中,Connector由數據庫廠商提供,而MySQL的JDBC-Connector文件是mysql-connector-java-版本號-bin.jar; ii. 原因很簡單,數據庫的JDBC驅動必須要運行起來才能起到作用,在Java中就是要運行該類,而運行一個類首先會想到命令"java 要運行的類的類名“了,既然要直接執行該命令,那就必須得將目標類的路徑添加到CLASSPATH中去才行,因此必須先將上面講的jar包添加到CLASSPATH路徑中去才行; iii. 在Eclipse中這樣設置:window -> preferences -> java -> install jres -> 選中當前采用的JRE點擊edit -> add external jars -> 選擇jar包路徑保存即可;
-
JDBC如何管理加載后的數據庫驅動——用DriverManager建立連接:
-
forName加載完類后如果發現這是一個數據庫類的驅動那就會做一定的特殊處理了;
-
JDBC專門(注意!“專門”)用DriverManager類來管理數據庫驅動!也就是說DriverManager類是專門用來管理JDBC驅動的!不要因為類命中沒有出現JDBC之類的字眼就認為該類還可以管理其它驅動!不!DriverManager只用來管理JDBC驅動!
-
加載后的驅動會被抽象成Java類型的對象保存在DriverManager的靜態變量driver中;
-
JDBC規定,一個Java進程只能同時持有(最多持有)一個JDBC驅動,也就是說上述的driver在加載后就有且僅有它一個了,也就是說你一次只能持有一個數據庫對象,這就不允許你一個Java進程同時連多個數據庫了;
-
還有一點要強調的是,數據庫訪問跟HTTP協議的原理一樣,都是基於連接的,即查詢數據庫前必須現建立連接,連接上了以后可以進行多次查詢,最后查詢完畢后關閉連接才算一次完整的數據庫操作,而這里的要素是什么?
i. 那就是一個進程同時(最多)只能建立一個連接;
ii. 這是很顯然的,一個進程就代表一個用戶,這和HTTP一樣,一個用戶不能同時向一個服務器建立兩個連接,即同一個人要建立第二個連接除非是第一個連接已經斷開(上一次服務已經結束);
iii. 因此加載后的驅動器driver是受到同不監視的,即driver是一個同步監視器!
-
可以看一下DriverManager的getConnection方法,它利用driver來建立和數據庫的連接(就跟HTTP中客戶端和服務器端建立連接一樣一樣滴),它是一個同步方法!
public static synchronized Connection DriverManager.getConnection(String url, String user, String passwd);
driver是DriverManager的靜態對象,該方法是同步方法,因此driver在該方法中就是同步監視器了;
可以看到這樣的結構就是單例模式,JDBC讓一個進程最多只能得到一個數據庫驅動器! -
看一下getConnection的參數和返回值:
i. url:要訪問的數據庫往往都是在遠程(處在某個網絡節點中),因此需要對數據庫進行定位;
a. 這個url的寫法有講究,不同數據庫的寫法不一樣,需要參考數據庫的JDBC手冊; b. 但是JDBC標准還是規定了該URL的框架,其格式是:jdbc:數據庫品牌:具體定位信息(該部分各數據庫有差異) c. MySQL的寫法:jdbc:mysql://hostname:port/具體數據庫名,例如"jdbc.mysql://192.23.21.9:8889/student_data
ii. user和passwd代表用戶名和登陸密碼,這都是數據庫管理員分配的;
iii. 返回值是一個Connection對象,該對象表示Java程序和數據庫所建立的一個屋里連接會話,之后可以通過Connection對象和數據庫進行交流(操作數據庫);
-
建立連接的示例:Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/select_test", "root", "1234");
-
-
一個完整的加載驅動建立連接的代碼:
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/select_test");
// 利用conn和數據庫交流
原文地址:
https://blog.csdn.net/Lirx_Tech/article/details/51121980