views:

448

answers:

4

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.

+1  A: 

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
+1  A: 

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
+2  A: 

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
+2  A: 

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
Well that works. I wanted the DataSource, as the tutorial said it was preferred, but I'll take it.
FarmBoy
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
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.
G_A
@Yishai: Thanks for that clarification. And yes, this tutorial overall is not up to Sun's usual standards.
FarmBoy