106

I am reading the Java JDBC specification (vr. 4) and I encountred this statement:

DataSource — this interface was introduced in the JDBC 2.0 Optional Package API. It is preferred over DriverManager because it allows details about the underlying data source to be transparent to the application

What I am trying to understand is what the difference is between a Connection and a DataSource, and why it exists. I mean, the block above says that the details about a datasource is transparent to the application, but wouldn't externalizing database properties such as username, password, url etc in a property file and then use DriverManager work in the same way?

And is the DataSource interface created only to have a common way of returning connections that can be pooled etc? In Java EE, does the application server implement this interface and the applications deployed to have a reference to a datasource instead of a connection?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
LuckyLuke
  • 47,771
  • 85
  • 270
  • 434

6 Answers6

79

Better scalability and maintenance

For DriverManager you need to know all the details (host, port, username, password, driver class) to connect to DB and to get connections. Externalizing those in a properties file doesn't change anything about the fact that you need to know them.

Using a DataSource you only need to know the JNDI name. The AppServer cares about the details and is not configured by the client application's vendor, but by an admin where the application is hosted.

Scalability:

Suppose you need to create connections yourself, how would you deal with changing load, sometime you have 10 users sometime you have 1000, you can't just get a connection whenever you need one and later 'release' it so the Database server does not get out of connections, which leads you to connection pooling. DriverManager does not provide it, DataSource does.

If you are going to program a connection pool yourself then you have to use DriverManager, otherwise go with DataSource.

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
A4L
  • 17,353
  • 6
  • 49
  • 70
  • Now I understand it better. Who creates an implementation of a datasource? Is it the company like MySQL or is it for instance Glassfish? I guess it is the last since it is only a way to obtain a connection? Could you explain a litte more about that? – LuckyLuke Mar 04 '13 at 10:56
  • 5
    the Datasource implmentation is provided by the driver vendor (let's say MySQL). The appserver needs to know the driver to be able create the Datasource. After that it takes care of binding it to the JNDI name (logical name) that has been configured. Note that for this configuration step all the details (driver class, url, username, password etc.) have to be known. but this is still better than having these known by the client application. – A4L Mar 04 '13 at 14:05
  • What i cant explain is how an application server ca create a `DataSource` instance using a specific driver, all examples i could find must know the implementation of the `DataSource` interface so they can do something like `DataSource ds = new com.db.SomeDBVendorDatasource();`. I just cant belive that an application server does it this way :/ ... here some lecture i found: SQL Datasources http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html and Package javax.sql : http://docs.oracle.com/javase/6/docs/api/index.html?javax/sql/package-summary.html – A4L Mar 04 '13 at 14:06
  • @A4L: Can you please provide some small code snipt that clear's the DataSource usage.means How to use DataSource – kTiwari Sep 25 '13 at 09:21
  • @krishnaChandra, since you are asking about the usage, i guess you have already obtained a `DataSource`. What's left is just to retrieve connections from it see the javadoc for [javax.sql.DataSource](http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html) – A4L Sep 25 '13 at 09:35
  • 4
    `If you are going to program a connection pool then you have to use DriverManager, otherwise go with Datasource.` - did you flip the names? – arun Aug 07 '14 at 03:41
  • 3
    @arun I don't think so, DriverManager is a lower level API than DataSource. – A4L Aug 07 '14 at 06:54
  • 10
    @CodeChieftain I think he means, if you want to implement a Connection Pool yourself, so there is nothing to flip. – Koray Tugay Jul 29 '16 at 19:54
  • 1
    You know you do not have to use DataSource with JNDI. Also, if you wanted to, you might as well use DriverManager with JNDI as well. – Koray Tugay Sep 10 '16 at 11:43
  • 2
    Datasource provides connection polling. Last statement states if you wish to program connection polling go for DataManager. It can be bit misleading at first. It should be if you wish to have connection polling in your app go for datasource. – Aniket Thakur Feb 12 '17 at 19:16
  • @AniketThakur **1.** `DataManager` is not mentioned anywhere else other than in your comment on this page. **2.** `polling` and `pooling` are two different things. **3.** The last statement refers to **programming** a connection pool not **acquiring** connections. – A4L Dec 04 '17 at 11:59
  • I hear what people (and even the JDBC spec) is saying, but the JavaDoc contract of both `DataManager` and `DataSource` does not forbid or require a connection pool to be used. Both simply states that "a connection is returned". So I fail to see the difference. – Martin Andersson Nov 29 '21 at 08:51
43

DriverManager

  • hampers the application performance as the connections are created/closed in java classes.
  • does not support connection pooling.

DataSource

  • improves application performance as connections are not created/closed within a class, they are managed by the application server and can be fetched while at runtime.
  • it provides a facility creating a pool of connections
  • helpful for enterprise applications
Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
NaveenKumar1410
  • 1,565
  • 14
  • 20
  • But if you created your own class such as MyConnectionPool and did some magic inside it with the DriverManager would that be the same as using a class that implements the DataSource interface? Is the DataSource interface only for having a common interface to get a connection? – LuckyLuke Mar 04 '13 at 09:52
  • 1
    Not exactly same.Framework like spring shows the capability of dataSource and its performance. – NaveenKumar1410 Mar 04 '13 at 10:01
5

DataSource objects can provide connection pooling and distributed transactions, so you may have to use DataSource if you need one of or both these features.

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
4

Below code shows two way for getting connection.

There is no need to know about URL in case of mySqlDataSource as this line is commented.

public class MySqlDataSourceTest {

public static void main(String[] args) throws SQLException, ClassNotFoundException {


    /************** using MysqlDataSource starts **************/
    MysqlDataSource d = new MysqlDataSource();
    d.setUser("root");
    d.setPassword("root");
//  d.setUrl("jdbc:mysql://localhost:3306/manavrachna");
    d.setDatabaseName("manavrachna");
    Connection c =  (Connection) d.getConnection();
    /************** using MysqlDataSource ends**************/


    /************** using DriverManager start **************/
    Class.forName("com.mysql.jdbc.Driver");
    Connection c=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/manavrachna","root","root");
    /************** using DriverManager ends **************/

    Statement st=(Statement) c.createStatement();
    ResultSet rs=st.executeQuery("select id from employee");
    while(rs.next())
    {
        System.out.println(rs.getInt(1));
    }

}

}
Thomas Rollet
  • 1,573
  • 4
  • 19
  • 33
Ram Tiwary
  • 49
  • 2
4

tl;dr

  • DataSource is a way of externalizing the info needed to connect to a database server: server name or address, user name, user password, settings specific to your particular database engine, etc.
  • DriverManager is fine during your initial learning. But when deploying to production, you’ll not want to hard-code connection info within your codebase. In real work, use DataSource instead of DriverManager to access the externalized configuration info (address, name, password, etc.).
  • Connection is your live connection to the database. A DataSource object will make use of a DriverManager to get a Connection object for you to use in making queries to the database.

Details

Let's look at the specifics of your Question.

What I am trying to understand is what the difference is between a Connection and a DataSource

A Connection object represents a live session with your database server, going back and forth to make queries and get results.

A DataSource object holds the credentials needed to get a connection to the database. Typically, a DataSource holds a user name recognized by the database server, a password for that user, and various settings to customize any future sessions with the database. A DataSource is not "open" or "closed"; it merely holds the info needed to make a Connection which is open or closed.

why it exists

Connection exists as the conduit for conversation with a database server.

DataSource exists as a way to avoid hard-coding connection info (user name, password, options) within your app’s code base. In real work, after you deploy your app you’ll not want to have to edit your code, recompile, and redeploy just because the DBA rotated passwords.

As a programmer, you do not want to be affected by deployment issues such as the database server’s machine network address, user names, user passwords, and such. You’ll want that info externalized outside of your codebase.

externalizing database properties such as username, password, url etc in a property file and then use DriverManager work in the same way?

No. Your code would still be hard-coded to look for that property file. But there are other ways for DBAs and SysAdmins to configure and communicate that connection info (user name, passwords, server address, etc.). The Java programmer should not make assumptions about the choices and changes to be made during deployment.

The principal way to externalize that info is to place the info within a directory server. There are many directory server implementations. These are commonly accessed via a standardized interface, such as the LDAP interface.

Java provides a facility for your Java-based app to interact with a directory service through the standardized interface. This facility is known as Java Naming and Directory Interface (JNDI).

Through JNDI, your app can ask a directory service to provide a DataSource object with your necessary connection info. By using JNDI, your app need not make assumptions about how your DBAs/SysAdmins chose to deliver this connection info to your app. Indeed, as a programmer you need know nothing about their deployment choices and changes.

is the DataSource interface created only to have a common way of returning connections that can be pooled etc?

The connections returned by a call to DataSource#getConnection may or may not be part of a connection pool. As the Java programmer, you generally do not care. At deployment time, the DBAs/SysAdmins may initially deploy with non-pooled connections. Then later they may change to using pooled connections. Again, you need not care, and there is no need to edit your code, recompile, and redeploy. The DBAs can change the pooling without your involvement.

In Java EE, does the application server implement this interface and the applications deployed to have a reference to a datasource instead of a connection?

FYI, Java EE is now known as Jakarta EE, after Oracle Corp transferred responsibility to the Eclipse Foundation.

You can use JDBC and DataSource objects in any kind of Java app: console, desktop (JavaFX/Swing/SWT), web app, microservice, etc.

By "this interface", if you mean the DataSource interface… No, the Jakarta EE implementation such as Tomcat, Jetty, Glassfish, Payara, WildFly, JBoss, Open Liberty, does not implement DataSource. Typically the JDBC driver provides an implementation, or your connection pool implementation does.

Again, this is configured at deployment by the DBA/SysAdmin rather than you the programmer during development. You should not bundle a JDBC driver with your Jakarta EE app. Instead configure your dependency manager (Maven, Gradle, etc.) to make a driver available transiently, only during development for your work, but not in the final artifact (.war file etc.) for deployment.

The Jakarta EE implementation handles getting your app a DataSource object. The implementation may itself act as the directory service; for example Tomcat can hold the connection info within its own configuration files, and then deliver that info to your app as a DataSource object. Or the DBAs/SysAdmins may configure the Jakarta EE implementation to connect to a separate directory server implementation such as Microsoft Active Directory or OpenLDAP. Again, all these details are none of your concern as the Java programmer.

the applications deployed to have a reference to a datasource instead of a connection?

In a Jakarta EE deployment, the Jakarta EE implementation delivers a DataSource object to your app. Your app code then calls getConnection when needing to talk to the database server. Your app code then closes the resulting Connection object when done talking to the database server.

Tip: Use try-with-resources syntax to automatically close connections, statements, and other JDBC resources. As mentioned above, the DataSource object is not a resource in that sense, and is never opened or closed itself.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

We can get connection using a datasource as follows. Use the connection to perform any database query.

DataSource datasource = (DataSource) new InitialContext().lookup(dataSourceName);
Connection connection = datasource.getConnection();
ansraju
  • 304
  • 3
  • 12