from JDK6 onward the JDBC drivers automatically get loaded if JVM found any Driver class in classpath. There is no need of Class.forName statement in JDK6. That's why you are getting drivers because they werein your classpath and loaded by JVM.
Difference between loading the driver and registering drivers
-
25-06-2023 - |
質問
I am very new to JDBC, and I have written a small program to check the drivers registered. I wanted to do the following
I checked the number of registers without loading any drivers:
I was expecting it to give nothing to my surprise it gives 3 drivers registered.
I loaded a driver using Class.forName();
I was expecting it to show me four drivers yet again got a shock, it shows 3 drivers only
Lastly I register the driver using DriverManager
Now it shows four drivers.
Could anyone help me in understanding what is happening here. My question are the following
- Are these three drivers loaded/registered by default.
- Won't loading the class using
Class.forName
register the driver? (I guess the answer is not for this as from my experience, I am asking this just to be sure) if no then is loading the class just to seek the implementation of the inferfaces like(DriverManager etc...) - Lastly what is the difference between loading the driver and register the driver
I have listed both the program and the output for your reference.
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import oracle.jdbc.driver.OracleDriver;
class Test3{
public static void main(String[] args) throws Exception{
//checking for registered drivers
System.out.println("Drivers registered initially");
Enumeration enumm = DriverManager.getDrivers();
int count=1;
while(enumm.hasMoreElements()){
Driver dr=(Driver)enumm.nextElement();
System.out.println(count+" "+dr);
count++;
}
//loading the driver
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("\n\nDrivers after class loading");
enumm = DriverManager.getDrivers();
count=1;
while(enumm.hasMoreElements()){
Driver dr=(Driver)enumm.nextElement();
System.out.println(count+" "+dr);
count++;
}
//After Registering driver
OracleDriver odr= new OracleDriver();
DriverManager.registerDriver(odr);
System.out.println("\nAfter registering oracle driver");
enumm = DriverManager.getDrivers();
count=1;
while(enumm.hasMoreElements()){
Driver dr=(Driver)enumm.nextElement();
System.out.println(count+" "+dr);
count++;
}
}
}
Output:
Drivers registered initially
1 sun.jdbc.odbc.JdbcOdbcDriver@2c84d9
2 oracle.jdbc.OracleDriver@8bdcd2
3 com.mysql.jdbc.Driver@1f31ad9
Drivers after class loading
1 sun.jdbc.odbc.JdbcOdbcDriver@2c84d9
2 oracle.jdbc.OracleDriver@8bdcd2
3 com.mysql.jdbc.Driver@1f31ad9
After registering oracle driver
1 sun.jdbc.odbc.JdbcOdbcDriver@2c84d9
2 oracle.jdbc.OracleDriver@8bdcd2
3 com.mysql.jdbc.Driver@1f31ad9
4 oracle.jdbc.driver.OracleDriver@167acf2
解決 2
他のヒント
The JDBC specification requires that compliant drivers register themselves with java.sql.DriverManager
when they are loaded (using a static initializer block). You should never have to register a driver yourself.
Starting from JDBC 4.0 (Java 6), JDBC drivers are required to specify a services definition declaring all java.sql.Driver
implementations provided by the driver (usually one). This is done through a file META-INF/services/java.sql.Driver
.
The DriverManager
will query all instances of this file on the classpath (using java.util.ServiceLoader
and load all driver implementations contained in these files. As a (compliant) driver is required to register itself, all these implementations are now registered with DriverManager
.
So:
- It is no longer necessary to use
Class.forName(...);
to load a driver (unless the driver is not JDBC 4 compliant) - You should never have to manually register a driver with
DriverManager
(unless the driver is not JDBC 1 compliant, or was specifically built to not register itself)
In your specific code you have three JDBC 4 compliant drivers (at least with regard to the services definition) so they are loaded automatically. Executing Class.forName(..)
has no effect because the class is already loaded (so it won't be loaded again). When you manually register a driver (which as I said before, you should never do), it will add an additional instance to the list of registered drivers.