Switching from DriverManager to DataSource is a best practice in modern Java applications because it supports connection pooling, is more configurable, and decouples your code from the specific database driver implementation.
While DriverManager creates a physical connection every time you call getConnection(), a DataSource (specifically a pooling one) maintains a set of open connections that can be reused, significantly improving performance.
1. The DriverManager Approach (Old way)
You are likely used to this pattern:
// Hardcoded driver details and physical connection creation
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db", "user", "pass");
2. The DataSource Approach (Modern way)
With DataSource, you configure the object once and then use it to get connections throughout your application.
Using Apache Commons DBCP (Connection Pooling)
To use a DataSource with pooling, you can use a library like Apache Commons DBCP’s BasicDataSource.
package org.kodejava.jdbc;
import org.apache.commons.dbcp2.BasicDataSource;
import javax.sql.DataSource;
public class DatabaseConfig {
private static final BasicDataSource dataSource;
static {
dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:mysql://localhost/musicdb");
dataSource.setUsername("music");
dataSource.setPassword("s3cr*t");
// Optional: Configure pooling parameters
dataSource.setInitialSize(5);
dataSource.setMaxTotal(10);
}
public static DataSource getDataSource() {
return dataSource;
}
}
3. Using the Connection in your Code
Once you have the DataSource instance, getting a connection is consistent regardless of the underlying implementation:
public void fetchData() {
DataSource ds = DatabaseConfig.getDataSource();
// The try-with-resources ensures the connection is "closed"
// (returned to the pool) automatically.
try (Connection conn = ds.getConnection()) {
// Use the connection as usual
var stmt = conn.prepareStatement("SELECT * FROM record");
var rs = stmt.executeQuery();
// ... process results
} catch (SQLException e) {
e.printStackTrace();
}
}
Why use DataSource?
- Connection Pooling: Reusing connections is much faster than opening/closing them for every request.
- Decoupling: Your business logic only knows about the
javax.sql.DataSourceinterface. You can switch fromBasicDataSourcetoHikariCP(another popular pool) without changing your data-access code. - JNDI Support: In Jakarta EE environments, you can look up a
DataSourceconfigured in the application server via JNDI, keeping credentials out of your source code. - Spring Integration: If you use Spring Framework,
JdbcTemplateis designed to work directly with aDataSource.
Maven Dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.13.0</version>
</dependency>
