我们可以在静态块中注册多个JDBC驱动,如下同时注册了mysql,oracle驱动.
try
{
Class.forName("com.mysql.jdbc.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e)
{
logger.error("driver not exists.", e);
}
}
然后通过下面的代码来创建连接,由于我们有两个驱动,怎么确定是用的哪一个呢?
Connection connection = DriverManager.getConnection(url, user, pwd);
答案是我们不用关心,只要url,user,pwd配置正确,DriverManager会一个一个驱动去试,哪个驱动能连接上数据库就使用那个驱动。
观察com.mysql.jdbc.Driver的源代码,发现其静态块中有如下代码,它向DriverManager注册了驱动。oracle.jdbc.driver.OracleDriver应该也是做了同样的事。所以DriverManager上注册了两个驱动。
static {
try {
//注册驱动
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
观察DriverManager.registerDriver(…)方法。Driver注册其实就是把Driver信息加到一个类型为CopyOnWriteArrayList的registeredDrivers中,所以此时这个ArrayList中注册了两个驱动,一个mysql的,一个Oracle的。
public static synchronized void registerDriver(java.sql.Driver driver,
DriverAction da)
throws SQLException {
if(driver != null) {
//Driver注册其实就是把Driver信息加到一个类型为CopyOnWriteArrayList的registeredDrivers中
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
} else {
throw new NullPointerException();
}
println("registerDriver: " + driver);
}
当我们创建连接时
Connection connection = DriverManager.getConnection(url, user, pwd);
观察DriverManager.getConnection()的源代码,发现它会遍历registeredDrivers,如果能连接上,就返回连接Connection,否则继续遍历registeredDrivers。
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
...
//一个一个驱动去试
for(DriverInfo aDriver : registeredDrivers) {
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
...
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// 如果连接成功,直接返回连接对象con
return (con);
}
} catch (SQLException ex) {
...
}
} else {
println(" skipping: " + aDriver.getClass().getName());
}
}
}
因此我们在执行DriverManager.getConnection(url,user, pwd)时无需关心具体使用了哪个驱动,只要url,user,pwd配置正确,DriverManager会一个一个驱动去试,如果能连接上就使用那个驱动。
968

被折叠的 条评论
为什么被折叠?



