一、Class.forName()

在Java中我们一般用下面这样的语句来连接数据库(以MySQL为例)

Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://"+dbServerIP+":"+dbPort+"/"+dbName,userName,passWord);

其实我们还可以这样:

com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
con=DriverManager.getConnection("jdbc:mysql://"+dbServerIP+":"+dbPort+"/"+dbName,userName,passWord);

或者:

new com.mysql.jdbc.Driver();
con=DriverManager.getConnection("jdbc:mysql://"+dbServerIP+":"+dbPort+"/"+dbName,userName,passWord);

  在java中使用JDBC连接数据库时,我们需要知道下面这些信息,却很少去一探究竟

    (1)数据库类型:MySQL、SQL Server、Oracle等

    (2)驱动程序jar包:相应的数据库驱动jar包,如mysql-connector-java-5.1.5-bin.jar等

    (3)驱动类:com.mysql.jdbc.Driver

    (4)JDBC URL:jdbc:mysql:// dbServerIP:dbPort/dbName

  从前面的程序段中我们知道,只要在调用DriverManager的getConnection方法之前,保证相应的Driver类已经被加载到jvm中并且完成了类的初始化工作,程序就可以正常运行了。

  注意:如果我们进行如下操作,程序是不能正常运行的,因为这样仅仅使Driver类被装载到jvm中,却没有进行相应的初始化工作。

com.mysql.jdbc.Driver driver = null;

或者:

ClassLoader cl = new ClassLoader();
cl.loadClass("com.mysql.jdbc.Driver");

二、Bridge模式

  JDBC是使用Bridge模式进行设计的,DriverManager是其中的Abstraction(业务抽象角色,公司),java.sql.Driver是Implementor(业务实现角色,产品),com.mysql.jdbc.Driver是Implementor的一个具体实现(某个具体的产品,衣服);需要注意的是,前一个Driver是一个接口,后者却是一个类,它实现了前面的Driver接口。

  Bridge模式中,Abstraction(DriverManager)是要拥有一个Implementor(Driver)的引用的,但是我们在使用过程中,并没有将Driver对象注册到DriverManager中去,这是怎么回事呢?

  JDK文档对Driver的描述如下图所示:

从上图的描述可知com.mysql.jdbc.Driver在装载后自动帮我们完成了创建实例、注册等步骤,根据上述分析可知,按如下方式修改JDBC驱动的装载,程序同样可以执行:

ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("com.mysql.jdbc.Driver");
clazz.newInstance();
Connection conn = DriverManager.getConnection("jdbcurl");

即有:

Class.forName("com.mysql.jdbc.Driver") == cl.loadClass("com.mysql.jdbc.Driver").newInstance();

ClassLoader.loadClass(xxx.xx.xx)仅加载某个类,但并没有实例化;Class.forName(String className)这个方法会做以下几件事情:装载、连接、初始化

Class.forName(xxx.xx.xx) 返回一个类,与 new 的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。


三、Driver的源代码

com.mysql.jdbc.Driver的源代码如下:

package com.mysql.jdbc;

import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// ~ Static fields/initializers
// --------------------------------------------- //
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
} // ~ Constructors
// ----------------------------------------------------------- /**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}

扩展A

现有下面这样一道题目,考察对驱动程序的认识

题目解析:


扩展B

jvm在加载类的时候是不会执行静态代码的,只有在初始化的时候才会去执行


参考资料

(1)http://www.ticmy.com/?p=249

(2)http://www.cnblogs.com/sunzn/p/3187868.html

JDBC剖析篇(1):java中的Class.forName()的更多相关文章

  1. JDBC剖析篇(2):JDBC之PreparedStatement

    一次有人问我为什么要使用JDBC中的PreparedStatement,我说可以“防止SQL注入”,其他的却不能说出个一二三,现在来看看其中的秘密 参考文章: http://www.jb51.net/ ...

  2. Java从入门到精通——数据库篇之JAVA中的对Oracle数据库操作

    在Java中对Oracle数据库的操作分为两种:一.查询.二.非查询. 下面是我对其进行总结: 一.查询数据 /** * 根据用户代码查询 * @param userId * @return 如果存在 ...

  3. Java中的Class.forName

    在做JAVA EE开发的过程中,更多的是使用框架来提高开发效率.越来越发现,之前很基础的一些东西,都忘记的差不多了.从今天开始慢慢的复习一下基础.今天在看JDBC的时候,就有一个有趣的地方,之前学的时 ...

  4. java中的Class.forName的作用

    Class.forName有什么作用 Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行.这句话就是装载类用的(和ne ...

  5. 《Android进阶》之第一篇 在Java中调用C库函数

    在Java代码中通过JNI调用C函数的步骤如下: 第一步:编写Java代码 class HelloJNI{ native void printHello(); native void printStr ...

  6. 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...

  7. java中String类学习

    java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...

  8. java中为什么重写equals时必须重写hashCode方法?

    在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...

  9. Java中的IO流(五)

    上一篇<Java中的IO流(四)>记录了一下Properties类,此类不属于IO流,它属于集合框架.接下来说一下IO流中的其它流 一,打印流PrintStream PrintStream ...

随机推荐

  1. javascript DOM 操作基础知识小结

    经常用到javascript对dom,喜欢这方便的朋友也很多,要想更好的对dom进行操作,这些基础一定要知道的.   DOM添加元素,使用节点属性  <!DOCTYPE html PUBLIC ...

  2. Android学习笔记_76_AsyncQueryHandler的应用

    研究AsyncQueryHandler这个类的时候遇到了几个重要的不清楚的知识点 1. Handler与Thread,Looper的关系 2. HandlerThread是干什么用的 3. Threa ...

  3. HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1110 Equipment Box Time Limit: 2000/1000 MS (Java/Oth ...

  4. Python程序的执行原理(转)

    1. 过程概述 Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行. 2. 字节码 字节码在Python虚拟机程序里对应的是PyCo ...

  5. centOS 7 更改root密码

    Linux忘记密码怎么办,不用重装系统,进入emergency mode 更改root密码即可. 首先重启系统,按下 向下 按钮, 定位在第一个,摁 e ,进行编辑 找到 ro , 把ro改为 rw ...

  6. JDBC jar包

    密码qiij https://pan.baidu.com/share/init?surl=oBfMwQ6rd9t6VNjIluF1qw

  7. CRS

    CRS是集群就绪服务(cluster ready service)的简称,主要负责集群中的资源管理以及OCR管理.为了与10gR2集群管理软件名称crs区分,这里用CRSD代替CRS.相关概念:--资 ...

  8. PL/SQL dev 工具连接远程服务器oracle注意点

    由于Oracle的庞大,有时候我们需要在只安装Oracle客户端如plsql.toad等的情况下去连接远程数据库,可是没有安装Oracle就没有一切的配置文件去支持. 最后终于发现一个很有效的方法,O ...

  9. getElementsByName和getElementById

    1: 今天分享工作中遇到的一个小细节 1.1 先介绍一下两个方法分别是: 1.2 getElementById()  :可返回对拥有指定 ID 的第一个对象的引用,如果您需要查找文档中的一个特定的元素 ...

  10. nmon监控linux系统性能

    Nmon是一款计算机性能系统监控工具,使用 Nmon 可以很轻松的监控系统的 CPU.内存.网络.硬盘.文件系统.NFS.高耗进程.资源等信息.[简单方便] Nmon 安装 到https://sour ...