获取一个数据库连接的通用模板如下:

String driver = "oracle.jdbc.OracleDriver";
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
String user = "scott";
String password = "ticmy";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);

里面有个Class.forName(driver),这句话有什么作用?将驱动类load到内存?如果没有这句会怎么样?运行发现,如果去掉这一句会有以下异常:
java.sql.SQLException: No suitable driver found for xxx….

在解释具体原因之前先简单看下Class.forName做了什么。

假设一个类以前从来没有被装进内存过,Class.forName(String className)这个方法会做以下几件事情:
1、装载。将字节码读入内存,并产生一个与之对应的java.lang.Class类对象
2、连接。这一步会验证字节码,为static变量分配内存,并赋默认值(0或null),并可选的解析符号引用(这里不理解没关系)
3、初始化。为类的static变量赋初始值,假如有static int a = 1;这个将a赋值为1的操作就是这个时候做的。除此之外,还要调用类的static块。(这一步是要点)

Class.forName(String className)方法会将这三步都做掉,如下面的例子:

package com.ticmy.oracle;
 
public class TestClinit {
    public static void main(String[] args) throws Exception {
        Class.forName("com.ticmy.oracle.ABC");
    }
}
class ABC {
    private static int a = getNum();
    static {
        System.out.println("this is static block");
    }
    public static int getNum() {
        System.out.println("getNum");
        return 1;
    }
}

程序的运行结果是:
getNum
this is static block

那么,Class.forName(driver)这个driver类里有没有什么static块呢?去探究一下。例子用的是Oracle,反编译下oracle.jdbc.OracleDriver,发现其继承了oracle.jdbc.driver.OracleDriver,那么继续看这个oracle.jdbc.driver.OracleDriver,确实有个static块,里面有这样的代码:

static {
    Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
    try {
      if (defaultDriver == null) {
        defaultDriver = new OracleDriver();
        DriverManager.registerDriver(defaultDriver);
      }
    } catch (RuntimeException localRuntimeException) {
    } catch (SQLException localSQLException){}
    _Copyright_2004_Oracle_All_Rights_Reserved_ = null;
}

再看看mysql吧:com.mysql.jdbc.Driver:
同样发现了static块,里面代码如下:

static {
    try {
      DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException("Can't register driver!");
    }
}

再看一个db2:com.ibm.db2.jcc.DB2Driver:
也发现了static块:

static {
    if (o.Nb != null) {
      exceptionsOnLoadDriver__ = dg.a(o.Nb, exceptionsOnLoadDriver__);
    }
 
    try {
      registeredDriver__ = new DB2Driver();
      DriverManager.registerDriver(registeredDriver__);
    }
    catch (SQLException localSQLException) {
      exceptionsOnLoadDriver__ = new SqlException(null,
      "Error occurred while trying to register Jcc driver with JDBC 1 Driver Manager");
      exceptionsOnLoadDriver__.setNextException(localSQLException);
    }
}

无一例外地,发现里面都有DriverManager.registerDriver(driver)的调用。那么是不是可以将开头的例子中的Class.forName换成DriverManager.registerDriver呢?

String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
String user = "scott";
String password = "ticmy";
DriverManager.registerDriver(new OracleDriver());
Connection conn = DriverManager.getConnection(url, user, password);
System.out.println(conn);
conn.close();

经过测试发现OK。现在,已经知道Class.forName(driver)的根本目的就是为了调用DriverManager.registerDriver。

Class.forName还有个重载的方法:Class.forName(String name, boolean initialize, ClassLoader loader),Class.forName(String className)就等价于Class.forName(className, true, currentLoader),注意中间的参数为true,这个参数的含义就是要不要初始化。如果此参数为true且指定的类以前没有被初始化过,就会去初始化。

另外,jdbc4已经不需要显式的调用Class.forName了,在jdbc4中,调用getConnection的时候DriverManager会自动去加载合适的驱动。
http://www.ticmy.com/?p=249

JDBC在getConnection之前为什么要调用Class.forName(转)的更多相关文章

  1. JDBC对MySQL数据库存储过程的调用

    一.MySQL数据库存储过程: 1.什么是存储过程 存储过程(英文:Stored Procedure)是在大型数据库系统中,为了完成特定功能而编写的一组的SQL语句集.存储过程经编译存储在数据库中,用 ...

  2. JDBC学习2:为什么要写Class.forName("XXX")?

    Class.forName(String name) 接上一篇JDBC.本来这个内容是放在前面的一篇里面的一起的,后来发现越写越多,想想看就算了,还是单独开一篇文章好了,这样也能写得更加详细点. 上一 ...

  3. mysql jdbc性能优化之mybatis/callablestatement调用存储过程mysql jdbc产生不必要的元数据查询(已解决,cpu负载减少20%)

    INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProce ...

  4. 调用Class.forName()要抛出异常

    今天学JDBC时,用到下面的程序: package bo; import java.sql.Connection; import java.util.ArrayList; import java.ut ...

  5. 为什么要使用class.forname在DriverManager.getConnection之前

    JDBC在getConnection之前为什么要调用Class.forName 获取一个数据库连接的通用模板如下: String driver = "oracle.jdbc.OracleDr ...

  6. eclipse 连接数据库记录

    两篇很好的文章介绍给大家: Eclipse使用JDBC方式连接SQLServer2016 通过Driver与DriverManager连接数据库 --------------------------- ...

  7. Class.forName和registerDriver的区别

    我们都知道JDBC的代码怎么写,比如以MySQL JDBC为例 //注册JDBC驱动 Class.forName("com.mysql.jdbc.Driver"); //然后就可以 ...

  8. 在Jena框架下基于MySQL数据库实现本体的存取操作

    在Jena框架下基于MySQL数据库实现本体的存取操作 转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统. ...

  9. JDBC调用存储过程

    一. JDBC调用存储过程 (1)使用存储过程SQL编写的程序代码,等一段语句和控制流语句.在创建时被编译成机器代码和存储在数据库中的client转让. 存储过程具有以下优势: 1.所生成的机器代码被 ...

随机推荐

  1. deinstall oracle 11g on linux

    deinstall oracle 11g on linux   From 11gR2, oracle provide us an deinstall tool. With that now we ca ...

  2. jquery下php与ajax的数据交换方式

    参考链接:http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2013/0122/11971.html 一.前台传递字符串变量,后台返回字符串变量( ...

  3. VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT

    VMware虚拟机上网络连接(network type)的三种模式--bridged.host-only.NAT VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换 ...

  4. iOS 多线程开发之OperationQueue(二)NSOperation VS GCD

    原创Blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...

  5. linux下Oracle11g RAC搭建(九)

    linux下Oracle11g RAC搭建(九) 八.创建ASM仓储 相同在图形化界面操作 [root@node1 ~]#  su - grid [grid@node1 ~]$ asmca   //创 ...

  6. CheckBoxList的操作查询是否被选中设置或者得到

    在项目中我们可能会经常遇到一收集多选信息的情况,比如做注册的时候要收集个人爱好,那时候大家第一个想到的肯定是CheckBoxList.那我们怎么来获取到CheckBoxList的值并且存入数据库呢?? ...

  7. Mercurial简介

    前言     目前所在的公司的版本控制使用的是Mercurial,它也有一个对应的客户端小乌龟,但是Mercurial跟我们之前使用的SVN有着本质的区别,对于其区别会在下一篇中介绍到,这次主要是带领 ...

  8. Qt国际化相关类

    QTextCodec QTextCodec为文本编码之间提供转换. Qt用Unicode 来存储,绘制和操作字符串.在很多情况下你可能希望操作不同编码的数据.例如,大部分日本文档是以Shift-JIS ...

  9. Oracle SQL Lesson (3) - 使用单行函数自定义输出

    大小写转换函数LOWER('SQL Course') = sql courseUPPER('SQL Course') = SQL COURSEINITCAP('SQL Course') = Sql C ...

  10. Form表单中的action路径问题

    今天刚接触web,在用jsp和servlet做一个简单的登陆的时候在Form表单action属性和method属性的一些问题:  我遇到的是Form表单提交到servelet处理时遇到的问题:  (1 ...