Why we use Class.forName(“oracle.jdbc.driver.OracleDriver”) while connecting to a database?
What is the actual use of Class.forName("oracle.jdbc.driver.OracleDriver")
while connecting to a database? Why cant we just import the same class, instead why we are loading it.
The basic idea behind using Class.forName()
is to load a JDBC driver implementation. A (normal) JDBC driver must contain a static initializer that registers an instance of the driver implementation with java.sql.DriverManager
:
JDBC drivers must implement the
Driver
interface, and the implementation must contain a static initializer that will be called when the driver is loaded. This initializer registers a new instance of itself with theDriverManager
(from JDBC 4.1, section 9.2)
Since JDBC 4.0 however there is a new way to register drivers: the jar of a JDBC driver needs to include a file /META-INF/services/java.sql.Driver
which contains the name(s) of the java.sql.Driver
implementations in that jar. When you create a connection using the DriverManager
, it will use java.util.ServiceLoader
to enumerate all /META-INF/services/java.sql.Driver
files in the classpath and load all drivers so they get registered.
The
DriverManager.getConnection
method has been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the fileMETA-INF/services/java.sql.Driver
. This file contains the name of the JDBC driver’s implementation ofjava.sql.Driver
.
(from JDBC 4.1, section 9.2.1)
The reasons drivers are loaded this way, is that it allows you to decouple an application from the driver (and database) it uses. This means that you can write, compile and even distribute an application without any drivers, you only need to use the interfaces provided in the java.sql
(and javax.sql
) package - which is part of Java - without needing to access the implementation directly.
The user of the application then adds a valid JDBC driver to the classpath (and configuring things like a connection string) so the application can actually to connect to a database. Before JDBC 4.0, the user would have to specify the driver name so that the application could load it using Class.forName
, with a JDBC 4.0 compliant driver and Java 6 or higher this discovery is automatic.
When you load a driver literally with Class.forName("oracle.jdbc.driver.OracleDriver")
it might feel like overkill, but if you keep in mind that it could also be a string pulled from a config file (or from user input) you might start to understand why it is so powerful.
Of course this driver independence is not 100%, especially not if your application uses vendor specific SQL. But the theory is that your application can be database independent. JDBC also provides some additional mechanisms to address this, eg JDBC escapes to provide a common syntax that the driver translates to the specific syntax, and DatabaseMetaData
which allows you to discover features, reserved words etc which allow you to create or generate compatible queries.
It`s a legacy way to do so. Importing class you will have extra dependency
From The Java Tutorial:
In previous versions of JDBC, to obtain a connection, you first had to initialize your JDBC driver by calling the method Class.forName. This methods required an object of type java.sql.Driver. Each JDBC driver contains one or more classes that implements the interface java.sql.Driver.
...
Any JDBC 4.0 drivers that are found in your class path are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)
A couple reasons to use Class.forName("")
instead of just referencing the class directly:
Using
Class.forName("")
gives you more obvious control over where exactly the first attempt to load the specified class will be made in your code. This makes it more obvious where the code will fail (throw an exception) if that class is not present in the classpath when that code runs.If you simply import the class and then reference it in your code, it becomes slightly less obvious where the code will throw an exception if the class is not present.
Also, using
Class.forName("")
is a way to get around potential compile-time restrictions. If, for example, the person compiling the code does not (for, let's say, licensing or intellectual property reasons) have access to the class oracle.jdbc.driver.OracleDriver, they may find it easier to compile code which references the class byClass.forName("")
rather than directly.If you do not need to use any methods, fields, or inner classes of the specified class, then
Class.forName("")
may be the clearest way to express that the only thing desired is to load the class (and have its static initializers run), and nothing else.
I don't think Class.forName exhibits any different functional behavior than referencing the class directly. It uses the calling class' classloader by default, which should be the same classloader that is used when referencing the class directly. There are some overloads to Class.forName("") that let you customize the class loading behavior a bit more.