JDBC Class.forName vs DriverManager.registerDriver
Class.forName()
is not directly related to JDBC at all. It simply loads a class.
Most JDBC Driver classes register themselves in their static initializers by calling registerDriver()
.
registerDriver()
is the real call that you hardly ever need to call yourself (unless you write your own JDBC driver).
Note that in JDBC 4 you should not need either of those if your JDBC driver is up-to-date, as drivers can be found using the service location mechanisms instead (i.e. simply leave out that call and open your connection as usual). See the documentaton of DriverManager
for details:
The DriverManager methods
getConnection
andgetDrivers
have 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 drivers implementation ofjava.sql.Driver
. For example, to load themy.sql.Driver
class, theMETA-INF/services/java.sql.Driver
file would contain the entry:my.sql.Driver
Applications no longer need to explictly load JDBC drivers using
Class.forName()
. Existing programs which currently load JDBC drivers usingClass.forName()
will continue to work without modification.
Why does calling Class.forName(com.mysql.jdbc.Driver) register the MySQL for JDBC?
It registers it because it loads the class into memory and runs the class's static initializers. The static initializer code then calls into the JDBC framework to say "Hi there, I'm a JDBC driver" (by calling DriverManager.registerDriver
).
E.g., the driver class will look vaguely like this:
package com.example.jdbc;
import java.sql.DriverManager;
public class Driver implements java.sql.Driver {
static {
DriverManager.registerDriver(new Driver());
}
// ...implementation...
}
Then when you do Class.forName("com.example.jdbc.Driver")
, it loads the class and runs the static initializer, which creates an instance and registers it with the DriverManager
.
I should note that as Andreas says, modern JDBC drivers don't need you to do this.
JDBC DriverManager.getConnection vs DriverManager.registerDriver() difference?
These two methods are completely different. You should have asked difference between Class.forName() vs DriverManager.registerDriver().
Anyways,
DriverManager.registerDriver() :
Registers the given driver with the DriverManager. A newly-loaded
driver class should call the method registerDriver to make itself
known to the DriverManager.
Ref : http://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html#registerDriver(java.sql.Driver)
getConnection()
is used for creating the connection once the driver gets loaded
Why does Class.forName not seem to register driver with DriverManager
Since Java 6 (assuming a JDBC 4.0 or higher driver on the initial classpath), JDBC drivers are loaded automatically. This means that the driver was loaded automatically the moment DriverManager
was class loaded and initialized.
The static initializer of the driver class is what registers a driver with the driver manager. This static initializer is run when the class is loaded. As the driver class was already loaded, a subsequent Class.forName
returns the already loaded class, and the static initializer does not run again, so nothing is registered with DriverManager
.
In other words:
DriverManager
is class loaded and loads drivers usingServiceLoader
com.mysql.cj.jdbc.Driver
is loaded throughServiceLoader
and its static initializer registers an instance withDriverManager
- You remove all drivers from
DriverManager
- You call
Class.forName("com.mysql.cj.jdbc.Driver")
- Given the class was already class loaded, Java returns the already loaded class
- Nothing is registered as the static intializer doesn't run again
- You manually register an instance with
DriverManager
(BTW, this is not something you should normally do,DriverManager.registerDriver
is for JDBC drivers to call).
Java Class.forName, JDBC connection loading driver
Class.forName()
attempts to load the named class. In early versions of JDBC, this was necessary as the Driver
class required the class to be loaded in this way. This hasn't been required for ages.
Leave out the call and nothing bad will happen.
For some reason, tutorials and examples persist with the old way.
The only tiny benefit of loading the class manually is that it tells you exactly what the problem is in case you haven't got the right class in the classpath.
What is the actual use of Class.forName(oracle.jdbc.driver.OracleDriver) while connecting to a database?
It obtains a reference to the class object with the FQCN (fully qualified class name) oracle.jdbc.driver.OracleDriver
.
It doesn't "do" anything in terms of connecting to a database, aside from ensure that the specified class is loaded by the current classloader. There is no fundamental difference between writing
Class<?> driverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
// and
Class<?> stringClass = Class.forName("java.lang.String");
Class.forName("com.example.some.jdbc.driver")
calls show up in legacy code that uses JDBC because that is the legacy way of loading a JDBC driver.
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 typejava.sql.Driver
. Each JDBC driver contains one or more classes that implements the interfacejava.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 methodClass.forName
.)
Further reading (read: questions this is a dup of)
- What purpose does Class.forName() serve if you don't use the return value?
- How does Class.forName() work?
- What does 'Class.forName("org.sqlite.JDBC");' do?
- What is the purpose of 'Class.forName("MY_JDBC_DRIVER")'?
- Loading JDBC driver
what exactly does this do Class.forName(com.mysql.jdbc.Driver).newInstance();
The Class
class is located in the java.lang package, so it is distributed with java, and imported automatically into every class.
What the forName()
method does, is just return the Class
object for the paramater that was loaded by the class loader. The newInstance()
method then returns a new instance of the class.
So then what happens is you callClass.forName(...)
it returns com.mysql.jdbc.Driver.class.
You then call newInstance()
on that class which returns an instance of the class, whith no paramaters, so it's basically calling new com.mysql.jdbc.Driver();
.
What is the purpose of 'Class.forName(MY_JDBC_DRIVER)'?
First of: with modern JDBC drivers and a current JDK (at least Java 6) the call to Class.forName()
is no longer necessary. JDBC driver classes are now located using the service provider mechanism. You should be able to simply remove that call and leave the rest of the code unchanged and it should continue to work.
If you're not using a current JDK (or if you have a JDBC driver that does not have the appropriate files set up to use that mechanism) then the driver needs to be registered with the DriverManager
using registerDriver
. That method is usually called from the static initializer block of the actual driver class, which gets triggered when the class is first loaded, so issuing the Class.forName()
ensures that the driver registers itself (if it wasn't already done).
And no matter if you use Class.forName()
or the new service provider mechanism, you will always need the JDBC driver on the classpath (or available via some ClassLoader
at runtime, at least).
tl;dr: yes, the only use of that Class.forName()
call is to ensure the driver is registered. If you use a current JDK and current JDBC drivers, then this call should no longer be necesary.
Related Topics
Read Properties File Outside Jar File
Getting the Class Name from a Static Method in Java
Execute Method on Startup in Spring
Why Invoke Thread.Currentthread.Interrupt() in a Catch Interruptexception Block
Lombok Annotations Do Not Compile Under Intellij Idea
How to Read PDF Files Using Java
How Do Hashcode() and Identityhashcode() Work at the Back End
How to Catch Out of Memory Exception in Java
How to Use "." as the Delimiter with String.Split() in Java
How to Inject Authenticationmanager Using Java Configuration in a Custom Filter
Does Setting Java Objects to Null Do Anything Anymore
How to Remove Special Characters from a String
Where Do I Find a Standard Trie Based Map Implementation in Java
@Runwith(Mockitojunitrunner.Class) VS Mockitoannotations.Initmocks(This)