get a head start with jdbc 4.0 using apache derbyyou'll focus primarily on the jdbc 4.0...

22
Get a head start with JDBC 4.0 using Apache Derby The JDBC 4.0 spec may not be final, but you can still learn its basics in a hands-on manner Skill Level: Intermediate Victor J. Soderberg ([email protected]) Freelance Writer Freelance 29 Aug 2006 At the time of this writing, the Java™ Database Connectivity (JDBC) 4.0 specification is expected to be released from beta testing. It offers developers several enhancements to speed development and create a more object-oriented paradigm with regard to accessing and manipulating data stores. This specification relies heavily on existing technologies, such as generics, the Metadata Facility, and JDBC RowSet. This tutorial demonstrates some of the new functions of the JDBC 4.0 specification in conjunction with the Apache Derby database. Section 1. Before you start This tutorial is for Java developers -- all flavors except Java 2 Platform, Micro Edition (J2ME) -- who want to learn about the pertinent methods and interfaces comprising the JDBC 4.0 release. The code snippets contained within demonstrate verbatim how to use this API. About this tutorial This tutorial demonstrates some of the new functions of the JDBC 4.0 specification in conjunction with the Apache Derby database. You'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant data store (but does not support every JDBC 4.0 feature at the time of this writing). The goal is to demonstrate the new JDBC 4.0 methods and Get a head start with JDBC 4.0 using Apache Derby © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 22

Upload: others

Post on 02-Aug-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Get a head start with JDBC 4.0 using ApacheDerbyThe JDBC 4.0 spec may not be final, but you can still learn itsbasics in a hands-on manner

Skill Level: Intermediate

Victor J. Soderberg ([email protected])Freelance WriterFreelance

29 Aug 2006

At the time of this writing, the Java™ Database Connectivity (JDBC) 4.0 specificationis expected to be released from beta testing. It offers developers severalenhancements to speed development and create a more object-oriented paradigmwith regard to accessing and manipulating data stores. This specification reliesheavily on existing technologies, such as generics, the Metadata Facility, and JDBCRowSet. This tutorial demonstrates some of the new functions of the JDBC 4.0specification in conjunction with the Apache Derby database.

Section 1. Before you start

This tutorial is for Java developers -- all flavors except Java 2 Platform, Micro Edition(J2ME) -- who want to learn about the pertinent methods and interfaces comprisingthe JDBC 4.0 release. The code snippets contained within demonstrate verbatimhow to use this API.

About this tutorial

This tutorial demonstrates some of the new functions of the JDBC 4.0 specificationin conjunction with the Apache Derby database. You'll focus primarily on the JDBC4.0 specification and less on capabilities of this early release from Apache, which isa JDBC 4.0-compliant data store (but does not support every JDBC 4.0 feature atthe time of this writing). The goal is to demonstrate the new JDBC 4.0 methods and

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 22

Page 2: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

techniques in the most simplistic manner. This is best done by providing codesnippets written with JavaServer Pages (JSP). Using JSP, I believe, is the easiestway to port code examples because there is less complexity (for less experienceddevelopers) regarding packages, reconfiguring project settings, and so on, which aretypically found in a Java application.

To demonstrate the features of this latest release, you'll perform methods andoperations on a table of automobiles in Apache Derby appropriately named CARS.Each record in this table is defined as follows:

• CAR_ID INT NOT NULL PRIMARY KEY

• CAR_NAME VARCHAR(25) NOT NULL

• MANUFACTURER VARCHAR(15) NOT NULL

• MODEL_YEAR VARCHAR(4) NOT NULL

• CATEGORY VARCHAR(15) NOT NULL

Throughout this tutorial, you'll modify the contents accordingly using the JDBC 4.0API.

Prerequisites

This tutorial is for Java developers who have experience with accessing back-endsystems for data extraction or manipulating. Furthermore, a basic understanding ofSQL is required. Ideally, you should have experience with a prior version of one ormore of the JDBC API's utilizing interfaces, such as ResultSet and Connection. Inaddition, a basic understanding of JSP technology is required.

System requirements

The following tools are used with this tutorial:

App serverJava-compliant application servers meeting Java Servlet specification 2.3 andJSP specification 1.2 (minimally) should suffice with the included examples. Allresults in this document were generated with Jakarta's Tomcat 5.5.12.

JavaThe Java SE Development Kit (JDK 1.6) is used in this tutorial (specifically,beta2-b86). As mentioned above, this tutorial uses JSP for the code snippetsfor ease of integrating these samples to your Web-based app.

DatabaseThis tutorial uses Apache Derby 10.2.03 (beta release), which is open sourceand lightweight. Read the getstarted guide to declare and configure systemvariables. The derbyadmin tutorial will demonstrate how to configure/run a

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 2 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 3: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

database server. This tutorial was created using theSimpleNetworkServerSample (embedded connection).

Section 2. Connectivity evolution, Java style

JDBC 4.0 provides new data accessibility and manipulation features with the goal ofsimplifying a developer's life. With the use of automatic driver loading (no moredeclaration of Class.forName(..) ), generics, and annotations, familiarity withthese new features can lead to reduced development time and improved codeportability. This section demonstrates JDBC 4.0 performing operations on the CARStable. The contents of this table are visible in Figure 1.

The generic DataSet and annotations

One of the more significant features of JDBC 4.0 is the introduction of the DataSetinterface. This interface works similarly to the ResultSet interface, but allows datato be represented via the fields of a public declared class called a data class. Tobest demonstrate how to utilize a data class with the DataSet interface, refer to atable created in Derby called CARS that contains the data displayed in Figure 1.

Figure 1. Table of vehicles

The above table in Derby was created with standard SQL/DDL statements (createtable and insert statements) whereby the primary key field is an int field, and theremaining four are varchar. Here you'll create a data class that matches the

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 22

Page 4: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

signature of the CARS table -- in other words, the variable types of the data classmatch the field types -- as in Listing 1.

Listing 1. The connection (dbConnect.jsp) and data class

dbConnect.jsp<%@ page import="java.sql.*, java.util.*"%><%

String DBNAME="NSSimpleDB";int NETWORKSERVER_PORT=1527;String DERBY_CLIENT_DRIVER = "org.apache.derby.jdbc.ClientDriver";

// URL for the Derby client JDBC driver.String DERBY_CLIENT_URL = "jdbc:derby://localhost:"+

NETWORKSERVER_PORT+"/"+DBNAME+";create=true";

String url = DERBY_CLIENT_URL;String jdbcDriver = DERBY_CLIENT_DRIVER;

Connection conn = null;

try{

Class.forName(jdbcDriver).newInstance();

Properties properties = new java.util.Properties();

properties.setProperty("user","cloud");properties.setProperty("password","scape");conn = DriverManager.getConnection(url,properties);

}catch(SQLException e){

out.print(e.getErrorCode() + "<br>"); //<br> is a htmlline break

out.print(e.getCause() + "<br>");out.print(e.getMessage() + "<br>");if(conn != null)

conn.close();}

%>obtainData.jsp<%@ include file="dbConnect.jsp" %><%!

// note: the public access modifier is not required// in a JSP declaration, it's just here to remind Java app users

// that a class MUST be public.public class Car{

public int id;public String manufacturer;

public String make;public String modelYear;public String category;}

%>

As opposed to a ResultSet, our class, Car, will act as a collection containing dataobtained from database operations.

DataSet navigation

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 4 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 5: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

With predecessors to JDBC 4.0, obtaining and navigating queried data was typicallydone via the ResultSet interface, as indicated in Listing 2.

Listing 2. The old way of navigating queried data

<%// excludes try-catch-finally blocksConnection conn = DriverManager.getConnection(url,properties);Statement stmt = conn.createStatement();rs = stmt.executeQuery("SELECT * FROM CARS");while(rs.next())

...%>

While this approach may be functional, it doesn't offer a way to manipulate data in atrue object-oriented paradigm.

Before you use the DataSet interface, you have to create an interface that extendsBaseQuery. Your interface, called AutoQueries here, will contain the SQLstatements that you'll use against your data store. Note that these queries are statedas an annotation to a particular method. Think of annotations as metadata forwhichever declaration it decorates (that the annotation is coupled with). A commonexample of an annotation is @deprecated when using the javadoc command. Inthis interface, you want to select the table contents utilizing the @Select annotationto decorate a method called, appropriately, getAllAutoData(). Refer to Listing 3to see the specifics.

Listing 3. Creating a query interface utilizing DataSet and Annotations

obtainData.jsp<%@ include file="dbConnect.jsp" %><%!

// note: the public access modifier is not required// in a JSP declaration, it's just here to remind Java app users

// that a class MUST be public.public class Car{

public int id;public String manufacturer;

public String make;public String modelYear;public String category;}

%><%!

interface AutoQueries extends BaseQuery{

// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();}

%>

Now that you have your interface declared, it's time to use this in conjunction withyour data class. To begin, you call upon the Connection interface'screateQueryObject(Class<T> ifc) method. This method, when invoked,returns an implementation of an interface that extends BaseQuery (which, if you

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 22

Page 6: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

refer to our definition of AutoQueries, it does just that) utilizing the JDBC driver.You then call your annotated method, getAllAutoData(), which returns theresults of the query into a DataSet type of your data class, Car. Listing 4 showsspecifically how this operation is performed.

Listing 4. Implementing and navigating the DataSet

obtainData.jsp<%@ include file="dbConnect.jsp" %><%!

// note: the public access modifier is not required// in a JSP declaration, it's just here to remind Java app users

// that a class MUST be public.public class Car{

public int id;public String manufacturer;

public String make;public String modelYear;public String category;}

%><%!

interface AutoQueries extends BaseQuery{

// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();}

%><%

AutoQueries autoQry = conn.createQueryObject(AutoQueries.class);DataSet<Car> dsRows = autoQry.getAllAutoData();

// The below is the JDK 1.5 released for each constructfor(Car c: dsRows){

out.print(c.id + " " + c.manufacturer + " " + c.make +" " + c.modelYear + " " + c.category); // - non bindingspace

// parameter (HTML space)}

%>

Successfully implementing Listing 4 yields results similar to that displayed in Figure1. As you can see, in lieu of the old ResultSet's getXXX() methods to obtaindata, now a more object-oriented standard is used.

Now add an additional method to the AutoQueries interface to accommodateparameters (for the query). Parameters are used either in numeric order in relationto the signature of the decorated method (for example, as shown in Listing 5, the ?1relates to the first parameter, year of getAutoByYear(String year)), or theparameter can be used directly in the query itself (for example, {year} can be usedin place of ?1). Note that with @Select, the sql= annotation element is assumed ifomitted and additional annotation elements are not used. Listing 5 shows how theexample can use parameters.

Listing 5. Parameterized query

obtainData.jsp

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 6 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 7: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

<%@ include file="dbConnect.jsp" %><%!

// note: the public access modifier is not required// in a JSP declaration, it's just here to remind Java app users// that a class MUST be public.public class Car{

public int id;public String manufacturer;

public String make;public String modelYear;public String category;}

%><%!

interface AutoQueries extends BaseQuery{

// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();

@Select(sql="SELECT * FROM CARS WHERE CARS.MODEL_YEAR= ?1")DataSet<Car> getAutoByYear(String year);

}%><%

// Invoke and navigateAutoQueries autoQry = conn.createQueryObject(AutoQueries.class);DataSet<Car> dsRows = autoQry.getAutoByYear("2006");

// The below is the JDK 1.5 released for each constructfor(Car c: dsRows){out.print(c.id + " " + c.manufacturer + " " + c.make

+ " " + c.modelYear + " " + c.category);}

%>

Running this query with a parameter of 2006 will yield the results shown in Figure 2.

Figure 2. Table of vehicles with parameter 2006

Modifying a DataSet

Let's say you want to modify a particular row in a DataSet and change the categoryfor a make of Jeep to Party Wagon. As indicated in Listing 6, this can be achievedvery simply by iterating through your Car collection, defining the condition underwhich you want to operate, changing the field(s) you want to update (via your Carclass), and calling DataSet's modify() method. If you want these changes to bepropagated to the database, the sync(Connection con) method must beinvoked (or sync() if the DataSet is disconnected, which can be set as such usingthe appropriate annotation element with @Select).

Listing 6. Modifying a row

obtainData.jsp<%@ include file="dbConnect.jsp" %><%!

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 22

Page 8: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

// note: the public access modifier is not required// in a JSP declaration, it's just here to remind Java app users

// that a class MUST be public.public class Car{

public int id;public String manufacturer;

public String make;public String modelYear;public String category;}

%><%!

interface AutoQueries extends BaseQuery{

// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();

@Select(sql="SELECT * FROM CARS WHERE CARS.MODEL_YEAR= ?1")DataSet<Car> getAutoByYear(String year);

}%><%

AutoQueries autoQry = conn.createQueryObject(AutoQueries.class);DataSet<Car> dsRows = autoQry.getAllAutoData();for(Car c: dsRows){

// Define a condition to be hit in the iterationif(c.make.equalsIgnoreCase("Jeep")){c.category = "Party Wagon";if(dsRows.modify())// Returns true if successful && !read{ // only

dsRows.sync(conn);}

}}

%>

Now that you have updated your DataSet and synchronized it with the data store,you can run your query from Listing 3, which selects the all the contents from theCARS table. The results are displayed in Figure 3, which successfully shows thatCar Id 9 was updated as per our condition above.

Figure 3. Modified table of vehicles

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 8 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 9: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

If you prefer to modify table data using the SQL Update statement, you can useannotations similar to how you did with @Select. Using the @Update annotation,you can achieve table modifications by adding a method to the AutoQueriesinterface, as shown in Listing 7.

Listing 7. Modifying the query interface to accommodate table modifications

<%!interface AutoQueries extends BaseQuery{// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();

@Select(sql="SELECT * FROM CARS WHERE CARS.MODEL_YEAR = ?1")DataSet<Car> getAutoByYear(String year);

@Update("UPDATE CARS SET CATEGORY = ?1 WHERE MAKE = {make}")int setCategoryByMake(String category, String make);

}%><%

// Invoke and navigateAutoQueries autoQry = conn.createQueryObject(AutoQueries.class);int updateCnt = autoQry.setCategoryByMake("Party Wagon",

"Jeep");out.print(updateCnt);

%>

The updateCnt variable stores the returned number of rows affected by theUpdate statement, which in this case, is 1.

Now you can proceed with the next basic SQL operation: record insertion.

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 22

Page 10: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Inserting into a DataSet

Inserting data into a table is also easily facilitated by the @UPDATE annotation. InListing 8 you'll make one last modification to your query interface to demonstratehow to do this.

Listing 8. Modifying the query interface to accommodate table modifications

interface AutoQueries extends BaseQuery{// Annotations do not utilize a concluding semicolon(;)@Select("SELECT * FROM CARS")

DataSet<Car> getAllAutoData();

@Select(sql="SELECT * FROM CARS WHERE CARS.MODEL_YEAR = ?1")DataSet<Car> getAutoByYear(String year);

@Update("UPDATE CARS SET CATEGORY = ?1 WHERE MAKE = {make}")int setCategoryByMake(String category, String make);

@Update(sql="INSERT INTO CARS('manufacturer', 'make', 'year','Category') VALUES (?1, ?2, ?3, ?4)",keys=GeneratedKey.RETURNED_KEYS_DRIVER_DEFINED)

DataSet<CarPK> insertCar(String mnfctr, String make,String year,

String cat);}

To capture numbers generated by the back end (for example, an index andauto_increment), you need to take note of two additional criteria:

1. The annotation element keys (in the @UPDATE annotation) need to bepresent and contain a value ofGeneratedKeys.RETURNED_KEYS_DRIVER_DEFINED, meaning thatthe JDBC driver will return the field(s) that represent the generatednumber. If you wish to specify which fields are returned, then utilize avalue of GeneratedKeys.RETURNED_KEYS_COLUMNS_SPECIFIED,which will return only those columns specified (the field names, verbatim)in your class.

2. A keys value of one of the two described above (the third isGeneratedKeys.NO_KEYS_RETURNED, which is the default setting ifthis element is omitted) means you have to perform one additional step,the declaration of a class to capture the back-end generated number. Thisis done by creating a data class, but with an additional step, decoratingthis class with the @AutoGeneratedKeys annotation, as shown inListing 9.

Listing 9. Annotated data class and navigation

<%!@AutoGeneratedKeyspublic class CarPK{

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 10 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 11: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

public int primKey;}

%><%

// Invoke and navigateAutoQueries autoQry = conn.createQueryObject(AutoQueries.class);DataSet<CarPK> dsRows = autoQry.insertCar("Yugo", "Cracker Box","1981", "POS");

for(CarPK pk: dsRows){

out.println(pk.primKey);}

%>

Listing 9 will return the automatically generated number, which in this scenario is 11(see Figure 4).

Figure 4. Inserted record (Car Id 11)

After you become familiar with the annotated methods for data retrieval andmanipulation, you'll be more efficient in comparison to PreparedStatements byoffering an enhanced API and being more conducive to code reuse.

Section 3. Exception handling

JDBC 4.0 shows its greatest sign of evolution with the new exception modelregarding SQLExceptions. The specific catalyst of an SQLException is no longerleft to the imagination; you can now get to the root cause.

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 22

Page 12: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

New exception hierarchies enhance Java application reliability

JDBC 4.0 has created an improved hierarchy for handling SQLExceptions. Twonew classes of exceptions have been introduced: SQLTransientException andSQLNonTransientException, both of which inherit from SQLException.Successfully catching a SQLTransientException represents an opportunity toretry the code that threw this exception, as it may be successful upon a secondattempt. Conditions such as connection and timeout exceptions represent eventsthat may be successful if reattempted. Inversely, a SQLNonTransientExceptionrepresents an event that needs to be corrected via code or environmentmodification. Scenarios such as invalid data store access or improperly formattedSQL statements fall under this classification.

Another major improvement offered by JDBC 4.0 involves chainedSQLExceptions. This functionality allows a developer to iterate over theSQLException hierarchy to find every exception that is thrown and identify the rootcause. This is done by recursively invoking SQLException'sgetNextException() method.

Capturing and iterating over the exception chain

As mentioned above, to iterate over the SQLException hierarchy, you make use ofgetNextException(). This returns the next exception in the chain until a nullvalue is discovered.

See what happens if, when you try to connect to the data store, the database is notavailable. (You bring the Derby server down manually, as shown in Listing 10).

Listing 10. SQLException iteration

dbConnect.jsp<%@ page import="java.sql.*, java.util.*"%><%try{

// omitted details present in Listing 1Class.forName(jdbcDriver).newInstance();Connection conn = DriverManager.getConnection(url, properties);

}catch(SQLException e){

while(e != null){

out.print("SQL State: " +e.getSQLState());out.print("Vendor Specific code: " +e.getErrorCode());

e = e.getNextException();}

}%>

The exception yields the following, shown in Figure 5.

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 12 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 13: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Figure 5. SQLException output

What's causing that exception?

If you reference the JDBC 4.0 specification document, an SQL state beginning with08 indicates either an SQLNonTransientConnectionException or anSQLTransientConnectionException. The data store implementationdetermines which one of these is thrown under this scenario. Naturally, your codeshould catch one of these exceptions and handle it accordingly. The vendor-specificcode is implementation specific, meaning that with regard to code portability, youshouldn't handle exceptions based on this returned value. Behind the scenes, thisvalue is mapped to an SQL state, making the vendor-returned error code even lesssignificant (unless a particular app needs to be debugged at the granular level).

You can navigate up the exception chain recursively to obtain a complete printout ofall exceptions, including non SQLExceptions (which may be causing thisexception). To perform this, you'll want to modify your code, as shown in Listing 11.

Listing 11. Complete exception chain iteration

dbConnect.jsp<%try{

// omitted details present in Listing 1Class.forName(jdbcDriver).newInstance();Connection conn = DriverManager.getConnection(url, properties);

}catch(SQLException e){

while(e != null){

out.print("SQL State: " +e.getSQLState());out.print("Vendor Specific code: " +e.getErrorCode());

Throwable te = e.getCause();while(te != null){

out.print("Throwable: " + te);te = te.getCause();

}

e = e.getNextException();}

}%>

Successfully executing the code above results in the output displayed in Figure 6.

Figure 6. Full exception chain output

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 22

Page 14: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

At the beginning of this section, you learned how an SQL state with a prefix of 08tells you that there is a connectivity issue and may or may not be a transientexception depending on the condition. Naturally, in this case, performing a catch onSQLTransientConnectionException would allow you to try to reconnect to thedatabase and prevent this condition from becoming a fatal error. A pseudo exampleof how code should handle this exception is shown in Listing 12.

Listing 12. Complete exception chain iteration

dbConnect.jsp<%try{

Class.forName(jdbcDriver).newInstance();Connection conn = DriverManager.getConnection(url, properties);

}catch(SQLTransientConnectionException tce){

if(tce.getSQLState().substring(0, 2).equals("08")){

// ... attempt to reconnect}

}catch(SQLException e){

while(e != null){

out.print("SQL State:\t" + e.getSQLState());out.print("Vendor Specific code:\t" + e.getErrorCode());

Throwable te = e.getCause();while(te != null){

out.print("Throwable:\t" + te);te = te.getCause();

}

e = e.getNextException();}

}%>

As partially illustrated in Listing 12, a good design attempts to catch each specifictransient exception with an attempt at appropriate recovery measures. Furthermore,the chained exception navigation serves its best purpose utilized within the catch-allblock (for example, the last block catching SQLException) when searching for theroot cause of an exception.

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 14 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 15: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Section 4. Connection handling

JDBC 4.0 also offers vast improvements regarding connections to back-endsystems, which you'll examine in this section.

Zap that latency

As most seasoned developers know, stale connections to a database when asystem uses connection pooling are a common cause of slowing down anapplication's performance. Not only does this result in a programmer wasting time onproduction support, but users also get frustrated, which, for those of us who work ina corporate environment, earns the programming department a bad rap.

One of the newly available tools to combat this, the Connection interface nowfeatures a new method, isValid(int timeout), to determine whether aconnection in the pool is still valid. If this method returns false, it provides anopportunity for this particular connection to be closed.

Listing 13 shows a pseudo example of how a clean-up routine can be written tomake use of this function.

Listing 13. Freeing up connection resources

<%try{

for(Connection c: connections){

if(!c.isClosed()){if(!c.isValid(5))

c.close(); // Willassist garbage collection}}

}catch(SQLException e){

while(e != null){

out.print("SQL State:\t" +e.getSQLState());

out.print("Vendor Specificcode:\t" + e.getErrorCode());

Throwable te = e.getCause();while(te != null){

out.print("Throwable:\t" + te);te = te.getCause();

}

e = e.getNextException();}

}%>

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 22

Page 16: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Behind the scenes, isValid(..) determines if a connection is still valid byperforming a query on the data store that will run no longer than the timeout periodspecified via the parameter (this timeout period is specified in seconds, notmilliseconds). If the query returns before the timeout period, this method returnstrue.

Other components of the Connection interface that can be used to address andpinpoint specific connections that, for example, may be bogging down the systemare the setClientInfo(..) and getClientInfo() methods. When aconnection is established, it can be named using the setClientInfo(..)method. When system slowness occurs, connections can now be identified bycalling getClientInfo() to view the culprit.

For those still intent on using the Statement interface to perform databaseoperations, notable API additions include the setPoolable(boolean poolable)and isPoolable() methods. By default, Statements are not poolable whencreated. However, if pooling is possible (determined via isPoolable()), you canuse setPoolable(true) to attempt to pool the statement. Note, however, thatcalling the latter method is not a guarantee that pooling will occur.

No more searching for driver names

Driver loading has been simplified more with JDBC 4.0. In previous JDBC versions,you had to invoke, for example,Class.forName(jdbcDriver).newInstance() to load a particular driver. Youno longer need this line of code. To comply with JDBC 4.0, a vendor will now includea driver file, named java.sql.Driver, located at META-INF\services (typically within a.jar) directory. This file contains text specifying the location and name of the driver. Acall to DriverManager.getConnection(..) will load the appropriate(registered) JDBC driver. Listing 14 shows an example of automatic driver loading.Note, however, that calls to Class.forName(jdbcDriver).newInstance() willstill work.

Figure 7. Driver file location and contents

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 16 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 17: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Listing 14. JDBC 4 driver loading

try{

// The commented line below is NO LONGER NEEDED.// Class.forName(jdbcDriver).newInstance();Connection conn = DriverManager.getConnection(url, properties);

}catch(SQLTransientConnectionException tce){

// ... attempt to reconnect}catch(SQLException e){

while(e != null){

out.print("SQL State:\t" + e.getSQLState());out.print("Vendor Specific code:\t" + e.getErrorCode());

Throwable te = e.getCause();while(te != null){

out.print("Throwable:\t" + te);te = te.getCause();

}

e = e.getNextException();}

}

Section 5. Wrappers

Vendors frequently provide data-store-specific APIs that are not part of the JDBCspecification. These APIs are typically wrapped inside of standard JDBC classesand interfaces, which, when utilizing JDBC 4.0, is now a less error-prone process.Take a look at how wrappers are handled in JDBC 4.0.

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 22

Page 18: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

See what's inside before you unwrap

The wrapper interface consists of two new methods:

• isWrapperFor(Class<T> iface) provides a Boolean reference if theobject this method is invoked upon is a wrapper for the parameter.

• unwrap(Class<T> iface) should be used onceisWrapperFor(...) returns true for the desired vendor class.

The unwrap(...) method returns an object that must be cast into the appropriatevendor class. See Listing 15 for specifics.

Note that calling on vendor-specific APIs, even via the new wrapper interface, stillcompromises application portability.

Listing 15. Exposing wrapped resources

<%@ page import="java.sql.*, java.util.*,org.apache.derby.client.net.NetConnection40"%><%// Excluding the above

import(NetConnection40) causes compilererrors

Properties properties = newjava.util.Properties();

properties.setProperty("user","cloud");properties.setProperty("password","scape");

Connection conn =DriverManager.getConnection(url,properties);String className =

"org.apache.derby.client.net.NetConnection40";Class drbyResource =

Class.forName(className);if(conn.isWrapperFor(drbyResource)){

NetConnection40 drbyDataSource =(NetConnection40)conn.unwrap(drbyResource);

out.print("Result of getServerVersion: "+

drbyDataSource.getServerVersion());}

%>

With regard to Listing 15, the class,org.apache.derby.client.net.NetConnection40, is a subclass ofNetConnection and contains a method called getServerVersion(). The JDBCConnection class acts as a wrapper around NetConnection. With this new API,the statement conn.isWrapperFor(drbyResource) returns true and allows youto unwrap this resource (with casting) to utilize this class and accessible methods.Implementing Listing 15 should result in similar results to that of Figure 8.

Figure 8. Wrapper demonstration

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 18 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 19: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Section 6. Summary

Most of the JDBC 4.0 methods are easy to incorporate, and they add importantfeatures not available to past Java applications. A prime example is if an applicationloses connectivity due to a brief network disruption, a paradigm now exists to planand remedy the situation programmatically. However, if you're resistant to changeand intimidated by the appearance of generics and annotations, don't despair. Thepopular JDBC flavors of the past (such as ResultSet and PreparedStatement)are not deprecated and don't show signs of going away anytime soon.

This tutorial has given you a good look at some of the new functions of the JDBC 4.0specification using the Apache Derby database, and it should be obvious why it'sworth taking advantage of this new API.

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 22

Page 20: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Downloads

Description Name Size Download method

Source code derby.jdbc.source.zip5KB HTTP

Information about download methods

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 20 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 21: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

Resources

Learn

• Learn the basics of generic types introduced in JDK 5.0 in "Introduction togeneric types in JDK 5.0" (developerWorks, December 2004).

• Read "Annotations in Tiger, Part 1: Add metadata to Java code"(developerWorks, September 2004) for a tutorial on custom and standardannotations.

• See "Introduction to JavaServer Pages technology" (developerWorks, August2001) if you're new to JSP.

• Read more about the goals and evolution of JDBC 4.0 in the JSR-221specification request.

• Read "Data management and persistence in J2EE applications"(developerWorks, June 2004) to examine two data management strategiesavailable on the Java platform: Java object serialization and JDBC.

• Read "Using JDBC to create database objects" (developerWorks, May 1998).

• Get more information about wrappers.

• Read a tutorial about generics from Sun.

• Check out a survey of key JDBC 4.0 features.

• Read about coverage of SQLExceptions and some SQL statements.

• Visit the developerWorks Open source zone for extensive how-to information,tools, and project updates to help you develop with open source technologiesand use them with IBM® products.

• Browse all the Apache articles and free Apache tutorials available in thedeveloperWorks Open source zone.

• Browse for books on these and other technical topics at the Safari bookstore.

• Check out the developerWorks Apache Derby project area for articles, tutorials,and other resources to help you get started with Derby today.

• Learn more about the IBM Cloudscape™ database, which is built using theApache Derby code base.

• Visit the Apache Derby Project Web site.

Get products and technologies

• Get JDK 1.6 from Sun Microsystems or IBM.

• Download Tomcat, the preferred Web container for this.

• Get the current JDBC 4.0 specification.

• Download Apache Derby 10.2, the JDBC 4.0-compliant data store used in this

ibm.com/developerWorks developerWorks®

Get a head start with JDBC 4.0 using Apache Derby© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 22

Page 22: Get a head start with JDBC 4.0 using Apache DerbyYou'll focus primarily on the JDBC 4.0 specification and less on capabilities of this early release from Apache, which is a JDBC 4.0-compliant

tutorial.

• Innovate your next open source development project with IBM trial software,available for download or on DVD.

Discuss

• Get involved in the developerWorks community by participating indeveloperWorks blogs.

About the author

Victor J. SoderbergVictor J. Soderberg earned a bachelor's degree from St. Joseph's College in 1994and has been involved in the technology field since 1995 as a software designer,developer, and business analyst. He's also a Sun-certified Java developer and has apatent pending related to J2ME technology (involving mobile devices detectingselected destinations aboard mass-transit vehicles). He is employed by a largecommunications company in the New York region creating Web-based applications.

developerWorks® ibm.com/developerWorks

Get a head start with JDBC 4.0 using Apache DerbyPage 22 of 22 © Copyright IBM Corporation 1994, 2008. All rights reserved.