目录
方式一(最初始方法):
方式二:
方式三:
方式四:
后话:为什么Class.forName(driverName)可以实现驱动的加载呢?
在正式讲连接方式前我们应先明确JDBC连接的四个要素:
要素一:Driver接口实现类
- java.sql.Driver
- 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类 java.sql.DriverManager
- MySQL的驱动为com.mysql.jdbc.Driver
要素二:URL
- URL定义了连接数据库时的协议、子协议、数据源标识。
- URL格式:jdbc:<子协议>:<子名称>,我们在mysql连接中子协议为mysql,子名称包含主机名、端口号、数据库名
- Mysql连接URL示例:jdbc:mysql://locoalhost:3306/Conan
要素三:数据库用户名
要素四:数据库密码
- user和password均可以通过 'name' = 'value' 的形式设置
别急,开始前我们还要简单说一下JDBC连接的步骤:
- 加载驱动程序,我们需要将驱动类加载到JVM
- 提供连接所需参数
- 建立数据库连接
正篇开始:
方式一(最初始方法):
1. 首先获取Driver的实现类对象,com.mysql.jdbc.Driver位于第三方jar包中
Driver driver = new com.mysql.jdbc.Driver();
2. 提供url,指明要操作的的数据库
String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";
//locoalhost为可选ip地址
//mysql默认本地端口号为3306
//Conan为要操作的数据库名称
//u'seSSL=false为可选项,视数据库版本而定,MySQL8.0及以上版本需要指明
3. 提供Properties对象,并设置用户名及密码
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "xxxxxx");
4. 通过Driver类中的connect方法获取连接,connect方法源码如下
Connection connection = driver.connect(url, properties);
//得到一个Connection类的对象
数据库连接获取完成。
方式二:
1. 我们可以通过java.lang.Class类的静态方法forName(String className)实现驱动的加载驱动
Class clazz = Class.forName("com.mysql.jdbc.Driver");
2. 提供url,指明要操作的的数据库
String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";
3. 提供Properties对象,并设置用户名及密码
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "xxxxxx")
4. 通过Driver类中的connect方法获取连接
Driver driver = clazz.newInstance();
//通过instance方法获取类的实例
//newInstance方法自jdk9.0之后弃用,建议写法为clazz.getDeclaredConstructor().newInstance()
Connection connection = driver.connect(url, properties);
//得到一个Connection对象
数据库连接获取完成。(2、3、4步与方式一一致)
方式三:
1. 通过静态方法forname加载驱动
Class.forname("com.mysql.jdbc.Driver");
//注意,这里与方式二不同,没有实例化Class类对象
2. 使用DriverManager类中的静态方法
getConnection(String url,String user,String password)
请求获得Connection对象
String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";
String user = "root";
String password = "xxxxxx";
Connection conn = DriverManager.getConnection(url, user, password);
数据库连接获取完成。
方式四:
1. 通过配置文件加载要素信息;
(此方法实现了代码和数据的分离,修改信息只需要修改配置文件,而不需要 接触代码 ,而且省去重新编译的过程。)
首先我们先建立一个配置文件(.properties)并在其中写入要素如下
InputStream inputstream = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
//通过流读取配置文件中内容
Properties properties = new Properties();//提供Properties对象
properties.load(inputstream);//通过load方法讲流中配置文件信息设置到对象中
2. 通过properties对象获取配置文件内容
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driverClass = properties.getProperty("driverClass");
3. 通过静态方法forname加载驱动
Class.forname("driverClass");
4. 使用DriverManager类中的静态方法
getConnection(String url,String user,String password)
请求获得Connection对象
Connection conn = DriverManager.getConnection(url, user, password);
数据库连接获取完成。
至此,我们得到了四种获得数据库连接的方式
后话:为什么Class.forName(driverName)可以实现驱动的加载呢?
驱动加载实际上就是JVM将.class字节码文件加载到内存,而加载过程分为三步
其中, 在链接的准备阶段会为类变量(static变量)分配存储空间并设置默认初始值。
先来看看源码中forname方法是怎样写的
public static Class<?> forName(String className)throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}
//这里调用了另一个方法forname0
那么forname0又是个什么方法呢
private static native Class<?> forName0(String name, boolean initialize,ClassLoader loader,Class<?> caller)
//name为全限定类名
//initializeb表示是否初始化该类,默认为true
//loader为对应的类加载器
//caller为对应类的对象
所以调用forname方法不仅会将类加载到JVM中去,还会进行初始化,也就意味着会执行static块中的代码
而上文我们用Class.forName(driverName)实现驱动的加载,就是利用了这样的机制。
我们看到mysql的Driver类中静态代码块中有一个registerDriver方法,正是执行静态代码块时,该方法替我们加载了驱动程序。真相大白了呢!
留个问题,我们可不可以用这个方法加载驱动呢?
ClassLoader.getSystemClassLoader().loadClass(String name);