When learning JDBC, there are usually two methods to register the database Driver (MySQL database is used here:
Java code
Drivermanager. registerdriver (New Driver ());
Class. forname ("com. MySQL. JDBC. Driver ");
So what are the similarities and differences between the two methods? First, let's go to drivermanager to see,
Java code
Public static synchronized void registerdriver (Java. SQL. Driver driver)
Throws sqlexception {
If (! Initialized ){
Initialize ();
}
Driverinfo di = new driverinfo ();
Di. Driver = driver;
Di. driverclass = driver. getclass ();
Di. driverclassname = Di. driverclass. getname ();
// Not required -- drivers. addelement (DI );
Writedrivers. addelement (DI );
Println ("registerdriver:" + DI );
/* Update the read copy of drivers vector */
Readdrivers = (Java. util. Vector) writedrivers. Clone ();
}
Obviously, drivermanager encapsulates the driver information we need to register into driverinfo into a writedrivers. This writedrivers is a static type vector variable declared in drivermanager. It will be used again during getconnection.
So class. forname ("com. mySQL. JDBC. driver ") how to register the driver? We know the class. forname ("Class Name") is used to instantiate a class instance to a VM. Let's take a look at com. mySQL. JDBC. driver source code.
Java code
Public class driver extends nonregisteringdriver implements java. SQL. Driver {
//~ Static fields/initializers
//---------------------------------------------
//
// Register ourselves with the drivermanager
//
Static {
Try {
Java. SQL. drivermanager. registerdriver (New Driver ());
} Catch (sqlexception e ){
Throw new runtimeexception ("can't register driver! ");
}
}
There is a static code block in COM. MySQL. JDBC. Driver, which registers a driver instance with drivermanager. In this way. forname ("com. mySQL. JDBC. driver "), it will first execute this static code block, so it and drivermanager. registerdriver (New Driver () has the same effect.
For these two methods, we recommend the second method, class. forname ("Class Name. There are two reasons
1. When we run drivermanager. registerdriver (New Driver (), the static code block has also been executed, which is equivalent to instantiating two Driver objects.
2. drivermanager. registerdriver (New Driver () generates a dependency on MySQL. The class. forname method can be dynamically changed during running.
All JDBC books tell us that using class. forname can force the JDBC driver to be loaded, but no one has ever told us how to implement it. This statement should be first provided by think in Java, and I am confused about this 1.1.
Class. forname is used to load the class into the memory, create a corresponding class instance, and then return a handle. If you do not need this method to explicitly create a class instance, instead, you can directly use new to create an actual class instance, then, the class instance will still be obtained using classloader (if not in the memory) before the instance is created, and then the class instance will be created. Therefore, the class instance can be obtained using the getclass method.
We know that when an instance is created, it will call its build function, which is called initialization. This step includes initializing its properties. However, if an instance is not created and the corresponding class instance is created, what will be done like class. forname? Initialization of static variables (attributes) will be completed at this stage, which is why static variables can be called without creating an instance. Other static code, that is, the code in static {}, will also be executed here.
Initially I thought that the automatically registered Code was completed by JVM. It will detect the loaded class. If the driver interface is implemented, it will directly call drivermanager. registerdriver (New Driver () to complete registration, but this is obviously irrelevant to the work that classloader needs to complete. Is drivermanager used to complete the detection? This requires a thread dedicated for detection, which will obviously affect JVM performance. Therefore, another implementation scheme is to use static code, so the following code static {drivermanager must exist in the driver implementation class. registerdriver (New Driver ();}, the code is automatically executed to complete registration when the class file is loaded to create a class.
So what is the truth? According to our estimation, if drivermanager is used. when registerdriver (New Driver () is explicitly registered, it will actually be registered twice, once when the class is loaded by the Code static {drivermanager. registerdriver (New Driver ();} to complete, one is to execute the drivermanager we write. registerdriver (New Driver () code.
When drivermanager. registerdriver (New jdbcodbcdriver () is used for explicit registration, drivers obtained by drivermanager. getdrivers () is used,
Sun. JDBC. ODBC. jdbcodbcdriver @ 42e816
Sun. JDBC. ODBC. jdbcodbcdriver @ 9304b1
Apparently Sun. JDBC. ODBC. jdbcodbcdriver was registered twice.
Therefore, when registering a driver, using class. forname is the best method. It ensures the uniqueness of the driver in drivermanager. Drivermanager. although registerdriver (New jdbcodbcdriver () does not produce code errors, it will obviously affect the execution efficiency, because when you query drivers in sequence, the existence of multiple identical drivers will obviously increase the query volume.