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

Class.forName(String name)

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

上一篇文章的第4点,getConnection()方法里面,我把从.properties里面获取mysqlpackage的地方替换成实际的 value值,那么替换后的应该是Class.forName("com.mysql.jdbc.Driver"),实际上所有的JDBC连接先写的基本 上也都是这一句。另外,哪怕删除这一句,也是可以运行成功的。那为什么还要 Class.forName("com.mysql.jdbc.Driver")呢?OK,分点讲解。

1、为什么要Class.forName("com.mysql.jdbc.Driver")?

JDBC是23种模式中的桥接模式的 典型应用,熟悉桥接模式的基本上稍微看一下源代码就知道为什么了,那桥接模式这里不讲,只讲为什么要这么做。 Class.forName(String className)的作用有两个,第一是CLASSPATH下指定名字的.class文件加载到Java虚 拟机内存中, 第二是初始化这个类。看到这句话,返回值都没有,那写在这里的作用很明显了,就是初始化"com.mysql.jdbc.Drvier"。初始化做了什 么?给静态资源赋值以及执行静态代码块,所以,反编译一下"mysql-connector-java-5.1.20-bin.jar"这个jar包,查 看一下Driver类:

public class Driver extends NonRegisteringDriver
  implements java.sql.Driver
{
  public Driver()
    throws SQLException
  {
  }

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

看到Class.forName("com.mysql.jdbc.Driver")的作用实际上就是调用DriverManager的 registerDriver方法注册一个mysql的JDBC驱动(Driver)而已,Driver继承 NonRegisteringDriver.java,NonRegisteringDriver.java实现了JDK提供的Driver接口,这个 Driver提供了若干数据库连接的方法,每个不同的数据库连接类都必须实现它,并重写和具体的数据库连接的算法。DriverManager也是JDK 中的类,截一些关键代码:

private static final CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList();

public static synchronized void registerDriver(Driver paramDriver)
    throws SQLException
  {
    if (paramDriver != null)
      registeredDrivers.addIfAbsent(new DriverInfo(paramDriver));
    else
      throw new NullPointerException();
    println("registerDriver: " + paramDriver);
  }

底层利用了一个CopyOnWriteArrayList作为容器(这是一个线程安全的容器,不过每次add的时候都会对底层数组进行一次新的复制,所以在读远多于写的时候建议可以使用这个),放那些注册进去的DriverInfo。最终getConnection(...)的时候就拿registerDrivers里面注册进去的具体的某个数据库的DriverInfo(像MySql的Driver就在DriverInfo里面)去连接具体的数据库。OK,所以总结一下整个流程:

JDK不负责和数据库连接打交道,也没必要,只提供一个具体的接口Driver,告诉所有第三方,要连接数据库,就去实现这个接口,然后通过DriverManager注册一下,到时候连接某个数据库的时候,你已经在我这里注册了,我会调用你注册进来的Driver里面的方法去对指定数据库进行连接的。然后Mysql就实现自己的Driver,Oracle就实现自己的Driver,通过static块注册一下,再然后,就没有然后了。

2、为什么不直接new?

意思是这么写"com.mysql.jdbc.Driver d = new com.mysql.jdbc.Driver();",可以啊,因为在new的时候会自动触发对一个类的初始化。问题是new出来干嘛?com.mysql.jdbc.Driver里面的方法我们会用到吗,并且我们知道怎么用吗?仅仅为了初始化一个类而new一个类实例出来还不如不去new,直接使用Class.forName(String name)初始化就可以了。DriverManager类的getConnection(...)方法的存在本身就是帮助用户调用Driver里面的各种方法连接数据库,JDK都做好了,开发者就没必要自己写了。

3、为什么删除Class.forName("com.mysql.jdbc.Driver")还是可以运行?

1996年1月23日JDK1.0发布,Java语言有了第一个正式版本的运行环境。JDBC是1997年2月19日,在JDK1.1的版本中发布的,从版本就看得出,JDBC属于Java技术的一些最基础的功能点。那在JDK1.5之后,其实已经不需要去显式调用Class.forName("com.mysql.jdbc.Driver")了,DriverManager会自动去加载合适的驱动,但是前提是CLASSPATH下必须有驱动jar包

时间: 2024-11-10 11:14:00

JDBC学习2:为什么要写Class.forName("XXX")?的相关文章

JDBC学习笔记一

JDBC JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: 连接到数据库 创建SQL或MySQL语句 在数据库中执行SQL或MySQL查询 查看和修改记录 JDBC架构   JDBC API支持两层和三层的处理模式对数据库的访问,但一般JDBC体系结构由两层组成: JDBC API: 这提供了应用程序到JDBC管理器连接. JDBC Driver API: 这支持J

JDBC学习笔记二

Statement执行更新操作 Statement:Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.Statement对象,用于执行不带参数的简单SQL语句. 通过JDBC向指定的数据表中插入一条记录,需要注意下面的几点: * 1.Statement:用于执行SQL语句的对象 * 1).通过COnnection的createStatement()方法来获取 * 2).通过excuteUpdate(sql)可以执行S

【转】JDBC学习笔记(1)——JDBC概述

转自:http://www.cnblogs.com/ysw-go/ JDBC JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: 连接到数据库 创建SQL或MySQL语句 在数据库中执行SQL或MySQL查询 查看和修改记录 JDBC架构   JDBC API支持两层和三层的处理模式对数据库的访问,但一般JDBC体系结构由两层组成: JDBC API: 这提供了应用程

【转】JDBC学习笔记(2)——Statement和ResultSet

转自:http://www.cnblogs.com/ysw-go/ Statement执行更新操作 Statement:Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.Statement对象,用于执行不带参数的简单SQL语句. 通过JDBC向指定的数据表中插入一条记录,需要注意下面的几点: * 1.Statement:用于执行SQL语句的对象 * 1).通过COnnection的createStatement()方

JDBC学习笔记(一)

public static void main(String[] args) { ResultSet rs = null; Statement stmt = null; Connection conn = null; try { /** * 1.加载JDBC驱动程序: * 加载目标数据库驱动到JVM * 成功加载后,会将Driver类的实例注册到DriverManager类 * oracle-Driver:oracle.jdbc.driver.OracleDriver * MySQL-Drive

javaweb学习总结(三十二)——JDBC学习入门【转】

原文地址:javaweb学习总结(三十二)——JDBC学习入门 一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后 才能够使用声卡和网卡,同样道理,我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数 据库打交道,如下所示: 1.2.JDBC介绍 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作

JDBC学习第一站之Statement与PreparedStatement

Statement: 通过类的名字,把类(元数据对象)加载到内存中,加载驱动,由于是对数据流做操作,一定要加异常处理,后面也是 <span style="white-space:pre"> </span>// 通过类的名字,把类(元数据对象)加载到内存中 <span style="white-space:pre"> </span>Class.forName("com.mysql.jdbc.Driver&quo

jdbc学习

加载并注册数据库驱动:在项目里配置数据库驱动,移除也是在这里面移除:右击项目-> Build Path -> Configure Build Path ->libraries -> Add Exteranl JARs Driver接口: 数据库的jdbc驱动类名:com.mircrosoft.jdbc.sqlserver.SQLServlerDriver. oracle.jdbc.driver.OracleDriver com.mysql.jdbc.Driver 数据库连接:Con

java之jvm学习笔记五(实践写自己的类装载器)

java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类装载器和安全管理器是可以被动态扩展的,或者说,他们是可以由用户自己定制的,今天我们就是动手试试,怎么做这部分的实践,当然,在阅读本篇之前,至少要阅读过笔记三. 下面我们先来动态扩展一个类装载器,当然这只是一个比较小的demo,旨在让大家有个比较形象的概念. 第一步,首先定义自己的类装载器,从Clas