System.setProperty和Class.forName方法获取数据库连接的异同

Java中,我们在加载数据驱动程序的时候常常用一下两种方法:

方法1

     System.setProperty("jdbc.drivers","com.microsoft.sqlserver.jdbc.SQLServerDriver: com.mysql.jdbc. Driver");

        DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DataBaseName=NorthWind","test","test");

方法2

Class.forName("jdbc.drivers","com.microsoft.sqlserver.jdbc.SQLServerDriver");

        DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DataBaseName=NorthWind","test","test");

那么以上这两种方式有什么不同!他们的连接创建过程是怎样的?

在方法1中:我们首先把我们需要的jdbc驱动程序添加到了jdbc.drivers系统属性中(在这里我们可以同时添加多个驱动程序,用:号隔开即可),在调用DriverManager.getConnection

方法获取连接时系统实际是在DriverManagerloadInitialDrivers方法中加载我们第一行中注册的驱动程序,并向DriverManager注册的!loadInitialDrivers方法的主要代码如下:

 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);    

        if (drivers == null)

        {

            return;

        }

        while (drivers.length() != 0)

        {

        //解析系统属性jdbc.drivers的值。

            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

            {

              //加载并初始华系统属性中配置的驱动程序!

                Class.forName(driver, true,ClassLoader.getSystemClassLoader());

            }

            catch (Exception ex)

            {

                println("DriverManager.Initialize: load failed: " + ex);

            }

        }

}

从上面的代码可以看出jdbc驱动程序的加载主要是在上面的绿色代码部分进行的,那么Class.forName方法加载的驱动程序是如何和DriverManager类关联起来的呢?原来JDBC规范中明确要求JDBC的驱动实现必须向DriverManager注册自己,即任何一个JDBC Driver的驱动Driver类的代码都必须类似如下:

public class MyJDBCDriver implements Driver

{

static

{

DriverManager.registerDriver(new MyJDBCDriver());

}

           

}

 

driverManager类中调用Class.forName方法,加载完相应的驱动类,在执行静态代码时,会在静态代码中实例化一个jdbc驱动并把它向DriverManager注册!并最终吧这个实例保存在DriverManager的静态域readDrivers数组中,代码如下:

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();

    //把信息实例保存在Vecotor类型的静态变量writeDriversreadDrivers

    writeDrivers.addElement(di);

    readDrivers = (java.util.Vector) writeDrivers.clone();

    }

现在我们完成了驱动程序的加载!然后DriverManager会根据传入的url参数信息调用driver.connect(url, info)方法并返回连接成功的连接实例,代码如下:

for (int i = 0; i < drivers.size(); i++)

    {

       //循环取出已经注册的驱动程序

        DriverInfo di = (DriverInfo)drivers.elementAt(i);

        if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass )

        {

        continue;

        }

        try

        {

        //尝试用取出的驱动程序进行连接

        Connection result = di.driver.connect(url, info);

        //连接成功返回此链接

        if (result != null)

        {

             return (result);

        }

        }

        catch (SQLException ex)

        {

        //连接过程抛出异常!

           if (reason == null)

           {

               reason = ex;

           }

        }

    }

    //抛出异常

    if (reason != null)   

    {

        throw reason;

    }

    //没有相匹配的驱动程序

    throw new SQLException("No suitable driver found for "+ url, "08001");

方法2和方法1的第一行代码是不一样的,那么它又是通过一个什么养的过程获取连接的呢!

方法2中直接调用Class.forName方法加载相应的数据库驱动!并在加载驱动后执行相应驱动程序的静态代码,实例化驱动,并把驱动实例向driverManager进行注册!,然后DriverManager在循环每一个驱动找出连接成果的连接实例并返回。

从中可以看出这两种获取连接的方法本质上是一样的,都是通过Class.forName方法加载并注册驱动实例,然后在DriverManagergetConnection时调用dirver.connect方法获取连接实例!它们的不同之处在于,方法1是被动的,它把驱动程序的加载交给了DriverManager去做,而方法2是主动地加载相应驱动,并向driverManager进行注册!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值