JDBC作為數據庫訪問的規范接口,其中只是定義一些接口。具體的實現是由各個數據庫廠商來完成。

一、重要的接口:
1.public interface Driver 每個驅動程序類必須實現的接口。Java
SQL 框架允許多個數據庫驅動程序。每個驅動程序都應該提供一個實現 Driver 接口的類。DriverManager
會試著加載盡可能多的它可以找到的驅動程序,然后,對于任何給定連接請求,它會讓每個驅動程序依次試著連接到目標 URL。強烈建議每個 Driver
類應該是小型的并且是單獨的,這樣就可以在不必引入大量支持代碼的情況下加載和查詢 Driver 類。在加載某一 Driver
類時,它應該創建自己的實例并向 DriverManager 注冊該實例。這意味著用戶可以通過調用以下程序加載和注冊一個驅動程序 Class.forName("foo.bah.Driver")。例如:MYSQL驅動
com.mysql.jdbc.Driver
2.public interface Connection 與特定數據庫的連接(會話)。在連接上下文中執行 SQL 語句并返回結果。
3.public interface Statement 用于執行靜態 SQL 語句并返回它所生成結果的對象。
4.public interface PreparedStatement 表示預編譯的 SQL 語句的對象。SQL 語句被預編譯并存儲在 PreparedStatement
對象中。然后可以使用此對象多次高效地執行該語句。
二、驅動的加載方式
1.最常用的是使用 Class.forName("com.mysql.jdbc.Driver");方式。這行代碼只是使用當前的類加載去加載具體的數據庫驅動,不要小看這簡單的這一行代碼。在Driver類中的static域中把當前驅動注冊到DriverManager中。

static { try {
java.sql.DriverManager.registerDriver(new Driver());//注冊驅動
} catch (SQLException E) { throw new RuntimeException("Can't register driver!");
}
}

2.通過查看DriverManager源碼,我們也可以使用System.setProperty("jdbc.drivers","....")方式。

String drivers;
try {
drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("jdbc.drivers");
}
});
} catch (Exception ex) {
drivers = null;
}
String[] driversList = drivers.split(":");
println("number of Drivers:" + driversList.length);
for (String aDriver : driversList) {
try {
println("DriverManager.Initialize: loading " + aDriver);
Class.forName(aDriver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}

3.最直接(不推薦)方式new com.mysql.jdbc.Driver();
4.為了更好的使用數據庫驅動,JDBC為我們提供了DriverManager類。如果我們都沒有使用以上方式,DriverManager初始化中會通過ServiceLoader類,在我們classpath中jar(數據庫驅動包)中查找,如存在META-INF/services/java.sql.Driver文件,則加載該文件中的驅動類。

AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() {
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
/* Load these drivers, so that they can be instantiated.
* It may be the case that the driver class may not be there
* i.e. there may be a packaged driver with the service class
* as implementation of java.sql.Driver but the actual class
* may be missing. In that case a java.util.ServiceConfigurationError
* will be thrown at runtime by the VM trying to locate
* and load the service.
*
* Adding a try catch block to catch those runtime errors
* if driver not available in classpath but it's
* packaged as service and that service is there in classpath.
*/
try{ while(driversIterator.hasNext()) {
driversIterator.next();
}
} catch(Throwable t) { // Do nothing
}
return null;
}
});