Hi Guillaume,
Thanks for considering HikariCP.
I'll do my best to defend the DataSource, but ultimately you may remain unconvinced. First, I'll quote some from Oracle:
The JDBC 2.0 extension API introduced the concept of datasources, which are standard, general-use objects for specifying databases or other resources to use. Datasources can optionally be bound to Java Naming and Directory Interface (JNDI) entities so that you can access databases by logical names, for convenience and portability.
This functionality is a more standard and versatile alternative to the connection functionality described under "Opening a Connection to a Database". The datasource facility provides a complete replacement for the previous JDBC DriverManager
facility.
You can use both facilities in the same application, but ultimately we encourage you to transition your application to datasources. Eventually, Sun Microsystems will probably deprecateDriverManager
and related classes and functionality.
Because of its properties, a DataSource
object is a better alternative than the DriverManager
class for getting a connection. Programmers no longer have to hard code the driver name or JDBC URL in their applications, which makes them more portable. Also, DataSource
properties make maintaining code much simpler. If there is a change, the system administrator can update data source properties and not be concerned about changing every application that makes a connection to the data source. For example, if the data source were moved to a different server, all the system administrator would have to do is set the serverName
property to the new server name.
Aside from portability and ease of maintenance, using a DataSource
object to get connections can offer other advantages. When the DataSource
interface is implemented to work with a ConnectionPoolDataSource
implementation, all of the connections produced by instances of that DataSource
class will automatically be pooled connections. [yada yada]
Which is more readable/maintainable?
jdbc:mysql://localhost:3306/mysql?user=foo&password=bar&socketTimeout=30&connectionLifecycleInterceptors=com.company.app.MySqlLifecycleInterceptor&useCompression=true&tcpRcvBuf=16384&tcpSndBuf=16384&autoReconnect=true&selfDestructOnPingMaxOperations=3&useSSL=true&clientCertificateKeyStoreType=PKCS12&trustCertificateKeyStorePassword=secret&metadataCacheSize=250&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048&cachePrepStmts=true&cacheResultSetMetadata=true&characterEncoding=UTF-8&continueBatchOnError=false
or
dataSource.user=foo
dataSource.password=bar
dataSource.socketTimeout=30
dataSource.connectionLifecycleInterceptors=
com.company.app.MySqlLifecycleInterceptor
dataSource.useCompression=true
dataSource.tcpRcvBuf=16384
dataSource.tcpSndBuf=16384
dataSource.autoReconnect=true
dataSource.selfDestructOnPingMaxOperations=3
dataSource.useSSL=true
dataSource.clientCertificateKeyStoreType=PKCS12
dataSource.trustCertificateKeyStorePassword=secret
dataSource.metadataCacheSize=250
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
dataSource.cachePrepStmts=true
dataSource.cacheResultSetMetadata=true
dataSource.characterEncoding=UTF-8
dataSource.continueBatchOnError=false
dataSourceClassName=com.mysql.jdbc.jdcb2.optional.MysqlDataSource
And that's not even setting everything I would set in a production environment. MySQL has well over
one hundred properties that can be set, of which 20-30 would probably be adjusted in a high-traffic environment.
Switching between DataSources can be as simple as:
HikariConfig config = new HikariConfig(System.getProperty("db.propfile"));
DataSource ds = new HikariDataSource(config);
or the Spring/IOC equivalent. Then simply setting the db.propfile System property can be used to switch DataSources:
-Ddb.propfile=mysql.properties
-Ddb.propfile=pgsql.properties
There are many other ways to bake the configuration cake, that's just one cheap recipe.
Basically, the JDBC URL anti-pattern needs to die a horrible death. Where else in the Java ecosystem would we put up with configuration by URL?
spring://context?annotation-config=true&component-scan-base-package=com.your.package&bean-id-MainDataSource-com.zaxxer.hikari.HikariDataSource&jpa-repositories=com.your.package.dao&transactionManager=org.springframework.orm.jpa.JpaTransactionManager...
log4j://root?log4j.rootLogger=INFO&log4j.appender.stdout=org.apache.log4j.ConsoleAppender&log4j.appender.stdout.layout=org.apache.log4j.PatternLayout...
You get the idea. URLs are Uniform Resource Locators, not a configuration mechanism. The Sun engineer who concocted the idea to abuse URLs in that way should die in a fire.
Does that help explain the rationale?
-Brett
ps. The company I work for has a product that supports 3 databases (MySQL, PostgreSQL, Derby) all configuration driven; without a URL in sight.