JDBC学习2:为什么要写Class.forName("XXX")?
2015-10-02 11:11
399 查看
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类:
看到Class.forName("com.mysql.jdbc.Driver")的作用实际上就是调用DriverManager的registerDriver方法注册一个mysql的JDBC驱动(Driver)而已,Driver继承NonRegisteringDriver.java,NonRegisteringDriver.java实现了JDK提供的Driver接口,这个Driver提供了若干数据库连接的方法,每个不同的数据库连接类都必须实现它,并重写和具体的数据库连接的算法。DriverManager也是JDK中的类,截一些关键代码:
底层利用了一个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包。
接上一篇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包。
相关文章推荐
- 现代网络应用中的UI设计-CH1
- ARM板子烧写系统不成功。解决方法
- AndroidUI 布局动画-为布局添加动画
- 可滚动的结果集,向前滚动,绝对定位
- TCP/IP详解笔记
- 10-排序4 统计工龄
- ROS wiki安装及配置
- AndroidUI 布局动画-为布局添加动画
- Hudson 的安装和使用
- Codevs P1004 四子连棋
- JDBC数据库
- 堆排序实现(java)
- 【读书笔记】GCD-API
- Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案
- #LeetCode# #C++# Binary Tree Postorder Traversal
- 博客14:CentOS的安装规划
- java反射机制
- 【读书笔记】GCD-API
- 判断闰年的Java算法
- SPOJ SORTBIT Sorted bit squence (数位DP,入门)