JDBC剖析篇(1):java中的Class.forName()
一、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()的更多相关文章
- JDBC剖析篇(2):JDBC之PreparedStatement
一次有人问我为什么要使用JDBC中的PreparedStatement,我说可以“防止SQL注入”,其他的却不能说出个一二三,现在来看看其中的秘密 参考文章: http://www.jb51.net/ ...
- Java从入门到精通——数据库篇之JAVA中的对Oracle数据库操作
在Java中对Oracle数据库的操作分为两种:一.查询.二.非查询. 下面是我对其进行总结: 一.查询数据 /** * 根据用户代码查询 * @param userId * @return 如果存在 ...
- Java中的Class.forName
在做JAVA EE开发的过程中,更多的是使用框架来提高开发效率.越来越发现,之前很基础的一些东西,都忘记的差不多了.从今天开始慢慢的复习一下基础.今天在看JDBC的时候,就有一个有趣的地方,之前学的时 ...
- java中的Class.forName的作用
Class.forName有什么作用 Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行.这句话就是装载类用的(和ne ...
- 《Android进阶》之第一篇 在Java中调用C库函数
在Java代码中通过JNI调用C函数的步骤如下: 第一步:编写Java代码 class HelloJNI{ native void printHello(); native void printStr ...
- 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇
本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- java中String类学习
java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...
- java中为什么重写equals时必须重写hashCode方法?
在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...
- Java中的IO流(五)
上一篇<Java中的IO流(四)>记录了一下Properties类,此类不属于IO流,它属于集合框架.接下来说一下IO流中的其它流 一,打印流PrintStream PrintStream ...
随机推荐
- 【洛谷2709】小B的询问(莫队模板题)
点此看题面 大致题意: 有一个长度为\(N\)的序列,每个数字在\(1\sim K\)之间,有\(M\)个询问,每个询问给你一个区间,让你求出\(\sum_{i=1}^K c(i)^2\),其中\(c ...
- [ZJOI2012]小蓝的好友
https://www.luogu.org/problemnew/show/P2611 题解 \(n\times m\)肯定过不去.. 我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵. 然后我们 ...
- 负的CPU保护环
什么是CPU保护环? 在计算机科学中, 分级保护域(英语:hierarchical protection domains),经常被叫作保护环(Protection Rings),又称环型保护(Ring ...
- 整个ssd的网络和multibox_loss_layer
总结说来prior_box层只完成了一个提取anchor的过程,其他与gt的match,筛选正负样本比例都是在multibox_loss_layer完成的 http://www.360doc.com/ ...
- 【JeeSite】角色分配
主要是(roleAssign.jsp , selectUserToRole.jsp )2个jsp页面的JS方法调用比较复杂,主页面要获取弹窗页面的数据 var pre_ids = h.find(&qu ...
- emmet工具使用和技巧
介绍 在前端开发的过程中,一大部分的工作是写 HTML.CSS 代码.特别是手动编写 HTML 代码的时候,效率会特别低下,因为需要敲打很多尖括号,而且很多标签都需要闭合标签等.于是,就有了 Emme ...
- 【洛谷P2447】[SDOI2010]外星千足虫
外星千足虫 题目链接 首先,它一看题解就是个高斯消元 只是改成了奇偶性的判断 性质: 奇数+奇数=偶数 奇数+偶数=奇数 偶数+奇数=奇数 偶数+偶数=偶数 于是我们用1表示奇数,0表示偶数 1+1= ...
- 12java基础继承
26.定义类Human,具有若干属性和功能:定义其子类Man.Woman: 在主类Test中分别创建子类.父类和上转型对象,并测试其特性. package com.hry.test; public ...
- Git相关内容
先聊一点关于gitlab的内容和github的内容 Gitlab和GitHub,都是我们可以存放代码库的地方.不过Gitlab可以免费的存储私人代码,GitHub需要花钱才能够存储私人代码库,不过我想 ...
- SQL、T-SQL与PL-SQL的区别
SQL.T-SQL与PL-SQL的区别 SQL是Structrued Query Language的缩写,即结构化查询语言.它是负责与ANSI(美国国家标准学会)维护的数据库交互的标准.作为关系数据库 ...