43

I'm trying to follow Sun's JDBC tutorial at http://java.sun.com/docs/books/tutorial/jdbc/basics/connecting.html

It gives the following example code:

DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource()
ds.setPort(1527);
ds.setHost("localhost");
ds.setUser("APP")
ds.setPassword("APP");

Connection con = ds.getConnection();

This code doesn't compile because the DataSource interface has none of these methods, except for the getConnection() method invoked last.

(Here's the javadoc: http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html)

What am I missing?

Edit: I'm actually trying to connect to MySQL (com.mysql.jdbc) and I can't find the javadoc for that. I'll accept an answer that points me to either:

1) documentation for com.mysql.jdbc regarding a DataSource that I can understand, or

2) gives an example to follow for what the tutorial's code should be, for any database.

Eric Wilson
  • 51,818
  • 71
  • 192
  • 262
  • Here are a few examples: http://www.tugay.biz/2016/09/hikaricp-hello-world.html http://www.tugay.biz/2016/09/bonecp-hello-world.html http://www.tugay.biz/2016/07/tomcat-connection-pool-vs-apache.html – Koray Tugay Sep 10 '16 at 11:36

7 Answers7

129

One thing you might want to look at is the Commons DBCP project. It provides a BasicDataSource that is configured fairly similarly to your example. To use that you need the database vendor's JDBC JAR in your classpath and you have to specify the vendor's driver class name and the database URL in the proper format.

Edit:

If you want to configure a BasicDataSource for MySQL, you would do something like this:

BasicDataSource dataSource = new BasicDataSource();

dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setUrl("jdbc:mysql://<host>:<port>/<database>");
dataSource.setMaxActive(10);
dataSource.setMaxIdle(5);
dataSource.setInitialSize(5);
dataSource.setValidationQuery("SELECT 1");

Code that needs a DataSource can then use that.

ColinD
  • 103,631
  • 27
  • 195
  • 199
22

Basically in JDBC most of these properties are not configurable in the API like that, rather they depend on implementation. The way JDBC handles this is by allowing the connection URL to be different per vendor.

So what you do is register the driver so that the JDBC system can know what to do with the URL:

 DriverManager.registerDriver((Driver) Class.forName("com.mysql.jdbc.Driver").newInstance());

Then you form the URL:

 String url = "jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]"

And finally, use it to get a connection:

 Connection c = DriverManager.getConnection(url);

In more sophisticated JDBC, you get involved with connection pools and the like, and application servers often have their own way of registering drivers in JNDI and you look up a DataSource from there, and call getConnection on it.

In terms of what properties MySQL supports, see here.

EDIT: One more thought, technically just having a line of code which does Class.forName("com.mysql.jdbc.Driver") should be enough, as the class should have its own static initializer which registers a version, but sometimes a JDBC driver doesn't, so if you aren't sure, there is little harm in registering a second one, it just creates a duplicate object in memeory.

Yishai
  • 84,976
  • 26
  • 176
  • 250
  • Well that works. I wanted the DataSource, as the tutorial said it was preferred, but I'll take it. – Eric Wilson Aug 26 '09 at 21:14
  • 12
    DataSource is really for application servers and other containers that supply a JNDI service. Without a JNDI service, they don't make much sense, and the tutorial is honestly not really well written on that point. – Yishai Aug 26 '09 at 21:29
  • You could create your own class to implement the DataSource interface using the code above for the getConnection methods. Beyond that you only need to implement getters and setters for loginTimeout and LogWriter. – GregA100k Aug 27 '09 at 02:06
  • @Yishai: Thanks for that clarification. And yes, this tutorial overall is not up to Sun's usual standards. – Eric Wilson Aug 28 '09 at 12:47
  • One important advantage of Datasource is to be able to rely on a connection pool – Rytek Jul 01 '13 at 09:56
  • @Rytek Well, you could use an `DriverManager` which gets the connections from a pool instead of of just opening them (where does that `DriverManager` get the actual new connections from? well, from the "real" `DriverManager` that it wraps). An examples is [org.apache.commons.dbcp2.PoolingDriver](https://commons.apache.org/proper/commons-dbcp/apidocs/index.html) – David Tonhofer Jun 10 '17 at 22:20
21

DataSource is vendor-specific, for MySql you could use MysqlDataSource which is provided in the MySql Java connector jar:

    MysqlDataSource dataSource = new MysqlDataSource();
    dataSource.setDatabaseName("xyz");
    dataSource.setUser("xyz");
    dataSource.setPassword("xyz");
    dataSource.setServerName("xyz.yourdomain.com");
Luke
  • 211
  • 2
  • 2
5

use MYSQL as Example: 1) use database connection pools: for Example: Apache Commons DBCP , also, you need basicDataSource jar package in your classpath

@Bean
public BasicDataSource dataSource() {
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/gene");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}

2)use JDBC-based Driver it is usually used if you don't consider connection pool:

@Bean
public DataSource dataSource(){
    DriverManagerDataSource ds = new DriverManagerDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/gene");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}
Fujian lin
  • 61
  • 1
  • 3
  • When using the second approach, it say's cannot convert from DriverManagerDataSource to javax.sql.DataSource? – Harihara_K Sep 03 '20 at 10:48
2

I think the example is wrong - javax.sql.DataSource doesn't have these properties either. Your DataSource needs to be of the type org.apache.derby.jdbc.ClientDataSource, which should have those properties.

Vinay Sajip
  • 84,585
  • 13
  • 155
  • 165
1

The javadoc for DataSource you refer to is of the wrong package. You should look at javax.sql.DataSource. As you can see this is an interface. The host and port name configuration depends on the implementation, i.e. the JDBC driver you are using.

I have not checked the Derby javadocs but I suppose the code should compile like this:

ClientDataSource ds = org.apache.derby.jdbc.ClientDataSource()
ds.setHost etc....
Kees de Kooter
  • 6,451
  • 5
  • 37
  • 42
0

For postgres, the below works. I actually used it in integ tests. I guess there should be some more consideration for production usage.

PGSimpleDataSource ds = new PGSimpleDataSource() ;  
ds.setServerName( "localhost" );  
ds.setDatabaseName( "your_db_name_here" );   
ds.setUser( "scott" );       
ds.setPassword( "tiger" );   

The class is bundled in the postgres jdbc driver.

The original stackoverflow post i followed: https://stackoverflow.com/a/45091982/3877642