JDBC详解系列(二)之加载驱动
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78848637)---
在[JDBC详解系列(一)之流程](http://blog.csdn.net/weixin_37139197/article/details/78838091)中,我将数据库的连接分解成了六个步骤。
>JDBC流程:
第一步:加载Driver类,注册数据库驱动;
第二步:通过DriverManager,使用url,用户名和密码建立连接(Connection);
第三步:通过Connection,使用sql语句打开Statement对象;
第四步:执行语句,将结果返回resultSet;
第五步:对结果resultSet进行处理;
第六步:倒叙释放资源resultSet-》preparedStatement-》connection。
接着将第一步的加载数据库驱动讲解一下。加载驱动就是这一句代码啦:
public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
Class.forName(JDBC_DRIVER);
//以上也可以直接替换为 new com.mysql.jdbc.Driver();
Class.forName(String className)返回的是一个类,在这个过程中,会把该类加载到jvm中,即这个类的静态代码会执行。为什么不使用new com.mysql.jdbc.Driver()这种方式呢?
如果使用new com.mysql.jdbc.Driver()这种方式,会对这个具体的类产生依赖。后续如果你要更换数据库驱动,就得重新修改代码。而使用反射的方式,只需要在配置文件中,更改相应的驱动和url即可。
加载驱动的过程中,发生了什么?我们来看一下mysql的驱动类代码。
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* 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()
}
ok,就是说其实起作用的是这一句代码:
java.sql.DriverManager.registerDriver(new Driver());
查看了一下registerDriver的源码,大致是如果DriverManager中没有这个类,就将这个类添加到到DriverManager的list中。在实际的使用过程中,我们完全可以用上面这一句代码将下面加载驱动的代码替换掉,但也会对具体的类产生依赖,导致后续更改不便。
Class.forName(JDBC_DRIVER);
到此,我想测试一下把加载驱动的代码去掉,然后看会报什么错误。结果竟然没问题。这是在逗我吗?书里面不是这么教的。只能进行google了,原因如下:
JDBC4.0以后新增了新特性:JDBC4.0不再需要显示调用class.forName()注册驱动,DriverManager初始化中会通过ServiceLoader类,在我们classpath中jar(数据库驱动包)中查找,使用META-INF\services\java.sql.Driver文本中的类名称去注册。
也就说,在启动的时候,通过jar包下面的java.sql.Driver里的文本内容,帮你把驱动给加载了。
OK,明白了这个之后,我将mysql驱动jar包中java.sql.Driver中的文本内容删除了,然后就将Class.forName(JDBC_DRIVER)注释掉,果然报错了:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/jdbc_test
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78848637)---
JDBC详解系列(二)之加载驱动的更多相关文章
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...
- JDBC详解系列(三)之建立连接(DriverManager.getConnection)
在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...
- JDBC详解系列(一)之流程
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- JDBC概述 使用JDBC也挺长 ...
- Eureka详解系列(二)--如何使用Eureka(原生API,无Spring)
简介 通过上一篇博客 Eureka详解系列(一)--先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka. 在此之前,先说明一点.网上几乎所 ...
- 《Windows驱动开发技术详解》之编程加载NT式驱动
之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似:
- QT自定义控件系列(二) --- Loading加载动画控件
本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...
- Spring详解(十)加载配置文件
在项目中有些参数经常需要修改,或者后期可能会有改动时,那我们最好把这些参数放到properties文件中,在源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ...
- Web.xml配置详解之context-param (加载spring的xml,然后初始化bean看的)
http://www.cnblogs.com/goody9807/p/4227296.html(很不错啊) 容器先加载spring的xml,然后初始化bean时,会为bean赋值,包括里面的占位符
- 详解composer的自动加载机制
composer是一个用PHP开发的用来管理项目依赖的工具,当你在项目中声明了依赖关系后,composer可以自动帮你下载和安装这些依赖库,并实现自动加载代码. 安装composer composer ...
随机推荐
- Strategic Game
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- Luogu P1541 乌龟棋(NOIP2010TG)
自己的第一篇博文 祭一下祭一下 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点, ...
- 面试经典算法题集锦——《剑指 offer》小结
从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...
- Golang源码探索(二) 协程的实现原理
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻 ...
- Linux网络中接收 "二进制" 流的那些事 --- 就recv的返回值和strlen库函数进行对话
1. 前言 很多朋友在做网络编程开发的时候可能都遇到这样的问题,在进行接收二进制流的数据的时候,使用strlen库函数来得到 二进制数据长度的时候并不准确.为什么呢??首先,使用strlen进行 ...
- [转载] 网络IO模型
转载自http://blog.csdn.net/zhoudaxia/article/details/8974779 同步(synchronous) IO和异步(asynchronous) IO,阻塞( ...
- [Egret]长按图片分享、分享图片、本地存储
egret 分享有API可以把一个显示对象树渲染成一个位图纹理,我把它赋值给 HTML 的 Image 元素,就实现了图片的显示,在微信中,通过长按图片可以分享出去.当然在其他浏览器可以保存在本地. ...
- array_unique和array_flip 实现去重间的区别
array_unique和array_flip 实现去重间的区别 php有内置函数array_unique可以用来删除数组中的重复值, phperz~com (PHP 4 >= 4.0.1, ...
- 六、VueJs 填坑日记之初识*.Vue文件
上一篇博文中,我们将接口的地址通过webpack代理到了本地,解决了跨域的问题.在之前的文章中,我们一直对项目进行配置,并没有真正的切入正题,可能很多人还不明白我们要做什么?那么今天,我们就要开写代码 ...
- short s1 = 1; s1 = s1 + 1;有错而short s1 = 1; s1 += 1正确。为何?
如果你认为表达式(x += i)只是表达式(x = x + i)的简写方式,这并不准确.这两个表达式都被称为赋值表达式.第二个表达式使用的是简单赋值操作符(=),而第一个表达式使用的是复合赋值操作符. ...