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 ...
随机推荐
- POJ 1011 Sticks 【DFS 剪枝】
题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissio ...
- 【洛谷P2168】[NOI2015]荷马史诗
荷马史诗 建一个k叉哈夫曼树,用堆维护一下 // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #inc ...
- 学习scala trait
// 类接口,但是可以实现方法 // 作用 多重继承 trait traitA{ val tnum: Int def log(msg: String): Unit ={ println(" ...
- postman发送HTTP请求自动生成MD5签名
POSTMAN是常用的接口测试工具 如何进行MD5签名呢? 代码如下: /** * 通过request.data获取body的内容,这个是postman内置变量 * 常用内置参数如下: * reque ...
- ffmpeg视频和声音
推送视频和声音 ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="内装麦克风 ( ...
- HTTP基本内容
*********************HTTP基本交互*************************** HTTP请求格式:HTTP 请求由三部分组成:请求行.请求头和请求正文请求行: 请求方 ...
- D - 湫湫系列故事——减肥记II
虽然制定了减肥食谱,但是湫湫显然克制不住吃货的本能,根本没有按照食谱行动! 于是,结果显而易见… 但是没有什么能难倒高智商美女湫湫的,她决定另寻对策——吃没关系,咱吃进去再运动运动消耗掉不就好了? 湫 ...
- <寒假逆向学习第一天> 破解基础知识之介绍常见工具和壳的特征
对于我们新手来说,程序是什么语言编写的?程序到底有没有加壳?程序加了什么壳?一直在我们心中充满了疑惑,本文我将根据我的近期学习,总结一下常见的工具和壳的特征. 一:程序是什么语言编译的 从目前接触到程 ...
- Linux的开山篇
一.Linux的学习方向 1.2Linux运维工程师 1.2.2Linux嵌入式开发工程师 1.2.3在Linux下做各种程序开发 javaEE 大数据 Python PHP C/ ...
- npm install 报错
今天准备在服务器上部署一下pm2,发现 npm install -g pm2 爆出了错误 error Unexpected end of JSON input while parsing near ...