web项目中不适用于java.sql.DriverManager描述的JDBC 4.0 Drivers及以后版本连接数据库是不需要用forName()?
来源:互联网 发布:淘宝客服介入会成功吗 编辑:程序博客网 时间:2024/05/18 15:26
在jdk1.6中java.sql.DriverManager明确指出,在JDBC 4.0 Drivers 版本及以后版本不再需要使用Class.forName() 显式地加载 JDBC 驱动程序。
mysql JDBC Driver源文件
public class Driver extends NonRegisteringDriver implementsjava.sql.Driver {
//
// Register ourselves with theDriverManager
//JDBC4.0Drivers以前,使用Class.forName("com.mysql.jdbc.driver")显示加载驱动程序时就会调用这个静态代码块。
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch(SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driverand register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throwsSQLException {
// Required forClass.forName().newInstance()
}
}
javaSE项目(支持不用forName())
不用forName()显示调用的代码,也能正确连接**************************(支持不用forName())
//连接数据库的URL
String url ="jdbc:mysql://localhost:3306/test";
//设置用户名和密码
Properties props = new Properties();
props.setProperty("user","user");
props.setProperty("password","password");
//应用程序不再需要使用 Class.forName()显式地加载 JDBC驱动程序。
//在调用getConnection方法时,DriverManager会试着从初始化时加载的那些驱动程序以及使用与当前 applet
// 或应用程序相同的类加载器显式加载的那些驱动程序中查找合适的驱动程序。
//连接到具体的数据库(根据url中的连接规范判断连接驱动程序)
Connection connection =DriverManager.getConnection(url, props);
*************************************
那不用显示调用forName(Driver)连接数据库是什么时候加载java.sql.jdbc.Driver的呢?
让我们看一下
java.sql.DriverManager的源代码。
在java.sql.DriverManager类中有一静态码块,里面有 loadInitialDrivers()方法。
/**
* Load the initial JDBCdrivers by checking the System property
* jdbc.properties and thenuse the {@code ServiceLoader} mechanism
*/
static {
loadInitialDrivers(); //用来初始化相关的Drivers
println("JDBCDriverManager initialized");
}
loadInitialDrivers();源代码
private static void loadInitialDrivers() {
Stringdrivers;
省略从META-INF/services/java.sql.Driver文件中或从读取Driver驱动等代码
。。。
String[] driversList = drivers.split(":");
println("number of Drivers:" + driversList.length);
for (StringaDriver : driversList) {
try{
println("DriverManager.Initialize: loading " +aDriver);
Class.forName(aDriver, true, //这里有forName()语句,也就是说,再调用DriverManage静态方法时必定会调用这里的语句。
ClassLoader.getSystemClassLoader()); //所以JDBC 4.0 Drivers及以后版本是不需要显示调用forName语句的。
}catch (Exception ex) {
println("DriverManager.Initialize: load failed: " +ex);
}
}
}
上面在java 项目中完全像JDK中介绍的一样,运行没问题。
java web项目(不支持不用forName())
今天在java web项目中用tomcat服务器试了一下,出现
java.lang.RuntimeException: java.sql.SQLException:No suitable driver found错误
也就是com.mysql.jdbc.Driver类没有找到,我已经把mysql-connector-java-5.1.41-bin.jar放到了WebRoot/WEB-INF/lib/目录下,确提示没有找到匹配的Driver驱动。
加上Class.forName(com.mysql.jdbc.Driver),问题解决,说明mysql的JDBC连接.jar是生效的。
为什么WEB项目中DriverManager静态代码块中的loadInitialDrivers()不能找到自己的com.mysql.jdbc.Driver呢?
这其中的原理还有待研究,菜鸟水平有限,希望高手指导一下。
引用jdk 1.6中文版java.sql.DriverManager
public class DriverManager extends Object
管理一组JDBC驱动程序的基本服务。
注:DataSource接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource对象是连接到数据源的首选方法。(这里看了com.mysql.jdbc.jdbc2.optional.MysqlDataSource源码,也就是利用反射创建com.mysql.jdbc.Driver类,只是不用注册DriverManager了;而且创建驱动获得的连接跟是此方法获得的连接是一样的java.sql.Connection)
作为初始化的一部分,DriverManager类会尝试加载在 "jdbc.drivers"系统属性中引用的驱动程序类。这允许用户定制由他们的应用程序使用的 JDBC Driver。例如,在 ~/.hotjava/properties 文件中,用户可以指定:
jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver
DriverManager 类的方法 getConnection和 getDrivers已经得到提高以支持 Java Standard Edition ServiceProvider机制。 JDBC 4.0 Drivers必须包括 META-INF/services/java.sql.Driver 文件。此文件包含 java.sql.Driver 的 JDBC驱动程序实现的名称。例如,要加载 my.sql.Driver类,META-INF/services/java.sql.Driver文件需要包含下面的条目:
my.sql.Driver
应用程序不再需要使用 Class.forName()显式地加载 JDBC驱动程序。当前使用 Class.forName()加载 JDBC驱动程序的现有程序将在不作修改的情况下继续工作。
在调用 getConnection方法时,DriverManager会试着从初始化时加载的那些驱动程序以及使用与当前 applet或应用程序相同的类加载器显式加载的那些驱动程序中查找合适的驱动程序。
从 Java 2 SDK标准版本 1.3版开始,只有当已授予适当权限时设置日志流。通常这将使用工具 PolicyTool完成,该工具可用于授予 permissionjava.sql.SQLPermission "setLog"权限。
- web项目中不适用于java.sql.DriverManager描述的JDBC 4.0 Drivers及以后版本连接数据库是不需要用forName()?
- MySQL JDBC驱动 - Class.forName和java.sql.DriverManager.registerDriver(new Driver())的区别
- JDBC 连接数据库 中Class.forName的作用
- JDBC 连接数据库 中Class.forName的作用
- Myeclipse web项目中连接sql数据库
- Java Web项目中连接Access数据库的配置方法
- Java Web项目中连接Access数据库
- Java Web项目中连接Access数据库
- JDBC连接数据库的四种方式:DriverManager,DataSource,DBCP,C3P0
- Mysql学习之十二:JDBC连接数据库之DriverManager方法
- JDBC学习笔记(二):连接Oracle数据库(DriverManager)
- JDBC_使用DriverManager实现数据库的连接
- DriverManager连接MySQL数据库
- java项目中使用JDBC连接mysql数据库查询数据
- 对JDBC驱动注册--DriverManager.registerDriver和 Class.forName()的理解
- JDBC是Java用来连接数据库的外交部门
- Java开发中JDBC连接数据库步骤及代码
- jdbc 中Connection DriverManager ResultSet Statement 等类的含义及常用方法
- Shell 递归多个子目录下的文件cp or mv到同一个目录下
- 问题汇总——Tomcat启动报错
- 改变多个ul下第一个li的样式
- ubuntu14.04安装TensorFlow
- leetcode:Remove K Digits
- web项目中不适用于java.sql.DriverManager描述的JDBC 4.0 Drivers及以后版本连接数据库是不需要用forName()?
- android实现多图片放大缩小的切换
- bwlabel函数
- DWR实例浅析
- Animation
- java获取不同时间的工具类
- 7.learningAction(行为库)2
- 网络编程-实验1-C与S通信
- Spring 学习2--Spring特殊语义注释类定义bean