Class.forName vs DriverManager.registerDriver -> Load JDBC Driver

来源:互联网 发布:最好的网络推广软件 编辑:程序博客网 时间:2024/05/16 19:50

1. DriverManager是用来管理所有驱动的注册和反注册,getConnection()也是从中通过drivers.elementAt(i).connect(url,props)取得的连接,class.forName只是用来注册驱动

2.JDBC4(since JDK1.6)能自动红装载驱动,因为JDBC4.0驱动必须含有META-INF/services/java.sql.Driver,并且包含一个实现java.sql.Driver的驱动。例如,要装载my.sql.Driver class,java.sql.Driver应该包含它。例如mysql-connector-java-5.1.22-bin.jarMETA-INF/services/java.sql.Driver只有一行com.mysql.jdbc.Driver

那么这个驱动又是如何被自动加载的呢其实看一下DriverManager的源代码就知道了

当调用getConnection(),getDrivers(),就会检查是否已经初始化,如果没有,就初始化,让后通过DriverService调用Service.providers(java.sql.Driver.class); 去装载驱动

3. JDBC3(since JDK1.5)可以通过jdbc.drivers系统变量设置以冒号:分割,如果其中Driver没有找到也不会报错

4. JdbcOdbcDriver中总能自动装载,即便在不同的操作系统(Solaris,Linux,WIndows,AIX).

5.你不应该调用DriverManager.registerDriver(),它可能会引起系统注册驱动多次,具体规则

使用JDBC3(使用-Djdbc.drivers设置)JDBC4驱动加载,不会引起重复加载.

使用DriverManager.registerDriver(newDriver());至少会注册两次,第一次是Driverstatic方法被调用自动注册了一个该类的实例,然后又重复注册了一个new出来的对象.

产生对具体驱动类的强依赖,你必须import驱动所在的类

6.再谈class.forName,Sun/JRockit JDKClass.forName()将调用本地方法Class.forName0(name,true,classLoader),true表示自动初始化这个类,下面是Mysql的驱动

public class Driver extends NonRegisteringDriver implementsjava.sql.Driver {
         static{
                   try{
                            java.sql.DriverManager.registerDriver(newDriver());
                   }catch (SQLException E) {
                            thrownew RuntimeException("Can't register driver!");
                   }
         }
         publicDriver() throws SQLException {
         }
}

Class.forName保证该驱动类的注册只调用一次,以为它是由类的装载实现的(直接调用static)

Class.forName的参数是可以从配置或属性中方便制定更动态化


测试如下:

package org.octopus;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

public class JDBCTest {

public void testLoadedDriversByClassForName() {
System.out.println("testLoadedDriversByClassForName - Start");
try {
//It could not load more than once
Class.forName("oracle.jdbc.OracleDriver");
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
}
int count = 1;
Enumeration enu = DriverManager.getDrivers();
while (enu.hasMoreElements()) {
Driver driver = (Driver) enu.nextElement();
System.out.println("Driver " + count + " -> " + driver);
count++;
}
System.out.println("testLoadedDriversByClassForName - End, Count="
+ (count - 1));
}

public void testLoadedDriversByRegisterDriver() {
System.out.println("testLoadedDriversByRegisterDriver - Start");
try {
// no conflict with jdbc.drivers and JDBC4
//System.setProperty("jdbc.drivers",
//"com.mysql.jdbc.Driver:oracle.jdbc.OracleDriver");
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
} catch (SQLException e) {
}
int count = 1;
Enumeration enu = DriverManager.getDrivers();
while (enu.hasMoreElements()) {
Driver driver = (Driver) enu.nextElement();
System.out.println("Driver " + count + " -> " + driver);
count++;
}
System.out.println("testLoadedDriversByRegisterDriver - End, Count="
+ (count - 1));
}

public void testLoadedDriversBySystemProperties() {
System.out.println("testLoadedDriversBySystemProperties - Start");
// Please use the -Djdbc.drivers instead
System.setProperty("jdbc.drivers",
"com.mysql.jdbc.Driver:oracle.jdbc.OracleDriver");
int count = 1;
Enumeration enu = DriverManager.getDrivers();
while (enu.hasMoreElements()) {
Driver driver = (Driver) enu.nextElement();
System.out.println("Driver " + count + " -> " + driver);
count++;
}
System.out.println("testLoadedDriversBySystemProperties - End, Count="
+ (count - 1));
}


public static void main(String[] args) {
JDBCTest jdbctest = new JDBCTest();
jdbctest.testLoadedDriversByRegisterDriver();
jdbctest.testLoadedDriversByClassForName();
jdbctest.testLoadedDriversBySystemProperties();
}
}