您的位置:首页 > 数据库 > MySQL

为什么需要Class.forName("com.mysql.jdbc.Driver")

2010-12-22 09:42 501 查看
在使用传统的JDBC连接数据库的时候,总是需要这一句(以MySQL为例):

Class.forName("com.mysql.jdbc.Driver");  

以前我也没深究,只是看网上的例子都这么写,实际上也跑通了,于是便懒得去管内部原理。不过大概还是清楚的,知道这句话是向DriverManage注册了一个MySQL的JDBC Driver。

但为什么要用Class.forName这样看上去不是很优雅的方式呢?

网上还流传了一个这样的版本Class.forName("com.mysql.jdbc.Driver").newInstance(),似乎有点儿多此一举。

经过实验,我发现用com.mysql.jdbc.Driver driver = new
com.mysql.jdbc.Driver() 也是可以的,但是只声明

com.mysql.jdbc.Driver driver = null ,而不实例化却又是不行的。

那么Driver的注册到底是在类的初始化时进行的,还是在类的对象初始化时进行的呢? 我也不知道,最好的办法还是看源码:

package com.mysql.jdbc;

import java.sql.DriverManager;

import java.sql.SQLException;

// Referenced classes of package com.mysql.jdbc:

//            NonRegisteringDriver

public class Driver extends NonRegisteringDriver

{

    public Driver()

        throws SQLException

    {

    }

    static

    {

        try

        {

DriverManager.registerDriver(new Driver());

        }

        catch(SQLException E)

        {

            throw new RuntimeException("Can't register driver!");

        }

    }

}

源码之前没秘密,com.mysql.jdbc.Driver很简单,就是红色的那句,看来是在类的static block里面做的初始化。

那么我们只要搞清楚在java里面,static block执行的时机就可以清楚来龙去脉了。

还是做一个实验吧:package com.javaye;

class A{

     static{

System.out.println("Class A loaded");

      }

     public A(){

System.out.println("create a instance of A");

      }

}

public class Main {

      public static void main(String[] args) throws Exception{

                 Class.forName("com.javaye.A");

     }

}

打印结果:“Class A loaded”

这说明Class.forName可以使类的static block中的代码得到执行。

然后,我们在修改成下面这样:

package com.javaye;

class A{

static{

  System.out.println("Class A loaded");

}

public A(){

  System.out.println("create a instance of A");

}

}

public class Main {

public static void main(String[] args) throws Exception{

com.javaye.A a = null;

}

}

发现没有打印任何东西,这说明只是声明某个类的变量,是不会使static block的到执行的。

再改一下:

package com.javaye;

class A{

static{

  System.out.println("Class A loaded");

}

public A(){

  System.out.println("create a instance of A");

}

}

public class Main {

public static void main(String[] args) throws Exception{

com.javaye.A a = new com.javaye.A();

com.javaye.A a2 = new com.javaye.A();

}

}

输出结果:

Class A loaded

create a instance of A

create a instance of A

这说明实例化一个类的话,static block 也会被执行,而且只会被执行一遍。

package data;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import com.mysql.jdbc.Connection;

import com.mysql.jdbc.Statement;

public class MySql {

    private static String url="jdbc:mysql://127.0.0.1:3306/mydata";

    private static String user="test";

    private static String password="123";

    public static void main(String [] args)

    {

        try

        {

            Class.forName("com.mysql.jdbc.Driver");

        }

        catch (ClassNotFoundException e)

        {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }// 加载驱动   

        Connection conn = null;

        Statement stmt = null;

        ResultSet rs = null;

        try {

            conn = (Connection) DriverManager.getConnection(url, user, password);// 建立连接

            stmt = (Statement) conn.createStatement();

            String sql = "select * from role";

              rs = stmt.executeQuery(sql);

              while (rs.next()) {// 从结果集中取出数据

                     System.out.print(rs.getInt(1) + "/t");

                     System.out.print(rs.getString(2) + "/t");

                     System.out.print(rs.getString(3) + "/n");

              }

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }// 执行sql语句

        System.out.println("Start to do it/n");

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息