最近看了《碼農翻身》這本書,感覺很有意思,裏面講到了 JDBC 裏面的部分細節,以下是總結:
先看幾個重要的類(以下代碼僅爲示例代碼,沒有考慮例外情況、線程安全等因素)
- DriverManager 的實現:
- 包含一個 ArrayList,裏面是通過 register 函數註冊(add)進來的 Driver
- getConnection 函數會遍歷各個註冊過的 Driver 去嘗試獲得 Connection
public class DriverManager{
private static List<Driver> registeredDrivers = new ArrayList<>();
public static Connection getConnection(String url, String user, String password){
Properties info = new Properties();
info.put ("user", user);
info.put("password", password);
for( Driver driver: registeredDrivers){
Connection conn = driver.getConnection(url,info);
if( conn ! = null){
return conn;
}
}
throw new RuntimeException("can't create a connection");
}
public static void register(Driver driver){
if(!registeredDrivers.contains(driver)){
registeredDrivers.add(driver);
}
}
}
- MySqlDriver 的實現(以 MySql 爲例):
- static 靜態代碼塊,用於向 DriverManager 註冊自身
- getConnection 方法,返回一個 Connection 對象
- acceptsURL 方法,各個 Driver 可以判斷 URL 是不是自己所支持的
public class MySqlDriver implements Driver{
static{
DriverManager.register(new MySqlDriver());
}
public Connection getConnection(String url, Properties info){
if(acceptsURL(url)){
return new MySqlConnectionimpl(info);
}
return null;
}
public boolean acceptsURL(String url){
return url.startsWith("jdbc:mysql");
}
}
- 最終程序員使用 DriverManager 獲得 Connection
- Class.forName 方法把某個數據庫的 Driver 類裝載, Driver 類被裝載的時候就會把自己註冊到 DriverManager 中
- 等到 DriverManager.getConnection 執行的時候就會遍歷各個註冊過的 Driver 去嘗試獲得 Connection,各個 Driver 可以判斷 URL 是不是自己所支持的( acceptsURL 方法),如果是,則返回一個 Connection 對象。
Class.forName("com.coderising.mysql.MySqlDriver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/studb",
"root",
"123456");