package com.xiangyi.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionFactory {
public static Connection getConn() throws ClassNotFoundException, SQLException {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
}
public static void main(String[] args){
try {
ConnectionFactory.getConn().close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
要问Class.forName有什么用?我想大家都知道,加载驱动类。深入思考,我们会有很多疑惑
1、class什么时候加载?
2、既然是加载类,用loadClass()方法行不行
3、为什么这个驱动要手动加载,而我们自己写的class不需要?
4、为什么现在比较新的版本不写Class.forName也可以?
先准备两个版本的mysql驱动,一个比较老的,一个比较新的,可以去maven库下载
mysql-connector-java-5.0.2.jar
mysql-connector-java-5.1.29.jar
1、class什么时候加载?
先用老版本做实验。注意这个版本的url中必须要写数据库名,不然会报错,说没有合适的驱动。把Class.forName(driver);注释掉程序会报错
2、既然是加载类,用loadClass()方法行不行
用loadClass是不可以的,loadClass用于加载类,Class.forName其实包含两个操作:加载类并初始化,注册驱动这个操作是在静态块中实现的,所以一定要初始化才会调用,loadClass只是加载,没有初始化的操作,所以没有。另外Class.forName还有个重载的方法,可以指定是否初始化。
3、为什么这个驱动要手动加载,而我们自己写的class不需要?
这涉及什么时候会触发类加载操作的问题。一般我们自己的代码都会有通过关键字new实例化对象或调用静态方法的操作,这个时候就会触发类加载和初始化,所以我们不需要手动加载。
4、为什么现在比较新的版本不写Class.forName也可以?
新版本的驱动使用了一种叫做SPI的技术,在jvm启动时会自动注册,所以我们不用手动注册