以MySQL数据库提供的驱动com.mysql.jdbc.Driver为例:
一、Driver接口
1、首先我们看一下JDBC标准定义的Driver接口:
package java.sql;
public interface Driver {
//它主要是使用指定的URL(如com.mysql.jdbc.Driver)和与具体提供商相关的信息建立一个连接。
Connection connect(String url, java.util.Properties info)
throws SQLException;
boolean acceptsURL(String url) throws SQLException;
DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info)
throws SQLException;
int getMajorVersion(); //返回驱动的主版本号
int getMinorVersion(); //返回驱动的次版本号
boolean jdbcCompliant(); //是否兼容于JDBC标准
}
以上就是JDBC中的Driver接口,它是任何数据库提供商的驱动类必须实现的接口,它之所以是一个接口,就是OO中经常谈到的“依赖倒转原则(DIP-Dependence Inverse Principle)”的具体应用了!在DriverManager类中可以看到:它使用的驱动都是Driver接口,从而依赖于高层,不依赖于实现。这样就使得JDBC Framework可以管理和维护不同JDBC提供商的数据库驱动,从而不用改变上层的代码,因为它们都是基于JDBC所定义标准的实现。
2、MySQL数据库提供商实现的Driver类源码:
package com.mysql.jdbc;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
从MySQL的Driver实现中,我们可以看到当我们调用
Class.forName("com.mysql.jdbc.Driver");
时,会执行上面的静态代码块,从而加载注册我们提供的数据库驱动。
二、DriverManager驱动管理器
DriverManager类是整个JDBC的起点!利用它可以加载并注册我们的驱动,创建连接,从而完成后续的操作。
package java.sql;
import sun.misc.Service;
import java.util.Iterator;
public class DriverManager {
final static SQLPermission SET_LOG_PERMISSION =
new SQLPermission("setLog");
public static java.io.PrintWriter getLogWriter() {
return logWriter;
}
public static void setLogWriter(java.io.PrintWriter out) {
SecurityManager sec = System.getSecurityManager();
if (sec != null) {
sec.checkPermission(SET_LOG_PERMISSION);
}
logStream = null;
logWriter = out;
}
public static Connection getConnection(String url,
java.util.Properties info) throws SQLException {
ClassLoader callerCL = DriverManager.getCallerClassLoader();
return (getConnection(url, info, callerCL));
}
public static Connection getConnection(String url,
String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties();
ClassLoader callerCL = DriverManager.getCallerClassLoader();
if (user != null) {
info.put("user", user);
}
if (password != null) {
info.put("password", password);
}
return (getConnection(url, info, callerCL));
}
public static Connection getConnection(String url)
throws SQLException {
java.util.Properties info = new java.util.Properties();
ClassLoader callerCL = DriverManager.getCallerClassLoader();
return (getConnection(url, info, callerCL));
}
public static Driver getDriver(String url)
throws SQLException {
java.util.Vector drivers = null;
println("DriverManager.getDriver(\"" + url + "\")");
if (!initialized) {
initialize();
}
synchronized (DriverManager.class){
drivers = readDrivers;
}
ClassLoader callerCL = DriverManager.getCallerClassLoader();
for (int i = 0; i < drivers.size(); i++) {
DriverInfo di = (DriverInfo)drivers.elementAt(i);
if ( getCallerClass(callerCL, di.driverClassName ) !=
di.driverClass ) {
println(" skipping: " + di);
continue;
}
try {
println(" trying " + di);
if (di.driver.acceptsURL(url)) {
println("getDriver returning " + di);
return (di.driver);
}
} catch (SQLException ex) {
}
}
println("getDriver: no suitable driver");
throw new SQLException("No suitable driver", "08001");
}
//向DriverManager注册指定的驱动
public static synchronized void registerDriver(java.sql.Driver driver)
throws SQLException {
//注册驱动之前保证已经初始化
if (!initialized) {
initialize();
}
//创建一个驱动信息类,用于记录驱动的各种信息
DriverInfo di = new DriverInfo();
di.driver = driver;
di.driverClass = driver.getClass();
di.driverClassName = di.driverClass.getName();
//将驱动信息加入一个驱动的Vector中,这个Vector用于记录注册的多个驱动
writeDrivers.addElement(di);
println("registerDriver: " + di);
readDrivers = (java.util.Vector) writeDrivers.clone();
}
//从DriverManager中取消注册某个驱动
public static synchronized void deregisterDriver(Driver driver)
throws SQLException {
ClassLoader callerCL = DriverManager.getCallerClassLoader();
println("DriverManager.deregisterDriver: " + driver);
int i;
DriverInfo di = null;
for (i = 0; i < writeDrivers.size(); i++) {
di = (DriverInfo)writeDrivers.elementAt(i);
if (di.driver == driver) {
break;
}
}
if (i >= writeDrivers.size()) {
println(" couldn't find driver to unload");
return;
}
if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
throw new SecurityException();
}
//在以上所有操作后可以删除此驱动了
writeDrivers.removeElementAt(i);
readDrivers = (java.util.Vector) writeDrivers.clone();
}
//得到当前所有加载的驱动枚举
public static java.util.Enumeration<Driver> getDrivers() {
java.util.Vector<Driver> result = new java.util.Vector<Driver>();
java.util.Vector drivers = null;
if (!initialized) {
initialize();
}
synchronized (DriverManager.class){
drivers = readDrivers;
}
ClassLoader callerCL = DriverManager.getCallerClassLoader();
//遍历所有的驱动
for (int i = 0; i < drivers.size(); i++) {
//得到某个具体的驱动
DriverInfo di = (DriverInfo)drivers.elementAt(i);
//假如调用者没有许可加载此驱动时,忽略该驱动
if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
println(" skipping: " + di);
continue;
}
//将可以加载的驱动加入返回的结果集
result.addElement(di.driver);
}
//返回结果集
return (result.elements());
}
public static void setLoginTimeout(int seconds) {
loginTimeout = seconds;
}
public static int getLoginTimeout() {
return (loginTimeout);
}
public static void setLogStream(java.io.PrintStream out) {
SecurityManager sec = System.getSecurityManager();
if (sec != null) {
sec.checkPermission(SET_LOG_PERMISSION);
}
logStream = out;
if ( out != null )
logWriter = new java.io.PrintWriter(out);
else
logWriter = null;
}
public static java.io.PrintStream getLogStream() {
return logStream;
}
public static void println(String message) {
synchronized (logSync) {
if (logWriter != null) {
logWriter.println(message);
logWriter.flush();
}
}
}
private static Class getCallerClass(ClassLoader callerClassLoader,
String driverClassName) {
Class callerC = null;
try {
callerC = Class.forName(driverClassName, true, callerClassLoader);
}
catch (Exception ex) {
callerC = null;
}
return callerC;
}
//初始化方法中完成加载所有系统提供的驱动的方法
private static void loadInitialDrivers() {
String drivers;
try {
//得到系统属性"jdbc.drivers"对应的驱动的驱动名,需要许可
drivers = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("jdbc.drivers"));
} catch (Exception ex) {
drivers = null;
}
DriverService ds = new DriverService();
java.security.AccessController.doPrivileged(ds);
println("DriverManager.initialize: jdbc.drivers = " + drivers);
if (drivers == null) {
return;
}
while (drivers.length() != 0) {
//系统属性"jdbc.drivers"可能有多个数据库驱动,这些驱动的名字是以":"分隔开的,将以':"分隔的驱动
//依次遍历,然后调用Class.forName加载
int x = drivers.indexOf(':');
String driver;
if (x < 0) {
driver = drivers;
drivers = "";
} else {
driver = drivers.substring(0, x);
drivers = drivers.substring(x+1);
}
if (driver.length() == 0) {
continue;
}
try {
println("DriverManager.Initialize: loading " + driver);
Class.forName(driver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}
}
private static Connection getConnection(
String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
java.util.Vector drivers = null;
synchronized(DriverManager.class) {
if(callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
}
if(url == null) {
throw new SQLException("The url cannot be null", "08001");
}
println("DriverManager.getConnection(\"" + url + "\")");
if (!initialized) {
initialize();
}
synchronized (DriverManager.class){
drivers = readDrivers;
}
//遍历当前的所有驱动,并视图建立连接
SQLException reason = null;
for (int i = 0; i < drivers.size(); i++) {
DriverInfo di = (DriverInfo)drivers.elementAt(i);
//加入调用者没有许可加载该类变忽略
if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
println(" skipping: " + di);
continue;
}
try {
println(" trying " + di);
//调用某个驱动的连接方法建立连接
Connection result = di.driver.connect(url, info);
if (result != null) {
//在建立连接后打印连接信息且打印连接
println("getConnection returning " + di);
return (result);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}
}
if (reason != null) {
println("getConnection failed: " + reason);
throw reason;
}
println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, "08001");
}
static void initialize() {
if (initialized) {
return;
}
initialized = true;
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
/* Prevent the DriverManager class from being instantiated. */
private DriverManager(){}
private static java.util.Vector writeDrivers = new java.util.Vector();
private static java.util.Vector readDrivers = new java.util.Vector();
private static int loginTimeout = 0;
private static java.io.PrintWriter logWriter = null;
private static java.io.PrintStream logStream = null;
private static boolean initialized = false;
private static Object logSync = new Object();
private static native ClassLoader getCallerClassLoader();
}
// DriverService is a package-private support class.
class DriverService implements java.security.PrivilegedAction {
Iterator ps = null;
public DriverService() {};
public Object run() {
ps = Service.providers(java.sql.Driver.class);
try {
while (ps.hasNext()) {
ps.next();
} // end while
} catch(Throwable t) {
// Do nothing
}
return null;
} //end run
}
// DriverInfo is a package-private support class.
class DriverInfo {
Driver driver;
Class driverClass;
String driverClassName;
public String toString() {
return ("driver[className=" + driverClassName + "," + driver + "]");
}
}