When using JDBC, we will naturally use the following statement:
The code copy is as follows:
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
String user = "";
String psw = "";
Connection con = DriverManager.getConnection(url,user,psw);
Why is it natural? Because the examples in both online and book tutorials are like this, and the program is indeed running normally, so everyone is at ease to copy it.
Is this necessary? No, we can replace it with this sentence:
The code copy is as follows:
com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
//or:
//new com.mysql.jdbc.Driver();
String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
String user = "";
String psw = "";
Connection con = DriverManager.getConnection(url,user,psw);
You may have seen a rough idea. We only need to ensure that the corresponding Driver class has been loaded into jvm before calling the DriverManager's getConnection method and complete the class initialization work. How to implement this function But there is no particularity. Both of the above methods can implement this function, so the program can run normally. Note that if we perform the following operations, the program will not run normally, because this only causes the Driver class to be loaded into jvm, but does not perform corresponding initialization work.
The code copy is as follows:
com.mysql.jdbc.Driver driver = null;
//or:
ClassLoader cl = new ClassLoader();
cl.loadClass("com.mysql.jdbc.Driver");
We all know that JDBC is designed using Bridge mode. DriverManager is the Abstraction. java.sql.Driver is Implementor, and com.mysql.jdbc.Driver is a specific implementation of Implementor (please refer to the description of GOF's Bridge mode). Please note that the previous Driver is an interface, while the latter is a class, which implements the previous Driver interface.
In Bridge mode, Abstract (DriverManager) needs to have a reference to Implementor (Driver), but during the use, we did not register the Driver object into the DriverManager. What's going on? There is a sentence in the jdk document's description of Driver:
When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager
Oh, it turns out that com.mysql.jdbc.Driver automatically completed this step after loading. The source code is like this:
The code copy is as follows:
package com.mysql.jdbc
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// ~ Static fields/initializers
// Register ourselves with the DriverManager
//
static {
t ry {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
// ~ Constructors
/**
*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()
}
}
PS: Revise the loading of JDBC driver
The code copy is as follows:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("com.mysql.jdbc.Driver");
clazz.newInstance();
Connection conn = DriverManager.getConnection("jdbcurl");
It can also be executed. But in this way, we construct an additional instance of com.mysql.jdbc.Driver. Same as Class.forName("com.mysql.jdbc.Driver").
Right now:
The code copy is as follows:
Class.forName("com.mysql.jdbc.Driver")==cl.loadClass("com.mysql.jdbc.Driver").newInstance();
Class.forName and ClassLoader.loadClass are two different things: one instantiated class and the other loaded class