1) Introduction
Java Database Connectivity allows Application Programs to interact with the Database to access the Relational Data. JDBC provides the Pluggable Architecture wherein any type of Java Compliant Drivers can be plugged-in even during the run-time. The JDBC API provides functionality to establish Connection to the back-end Database session which can execute the Queries to get the Results. The new version of JDBC that comes along with Mustang (Java 6.0) is JDBC 4.0. JDBC 4.0 is one of the areas that were great affected with the new set of features. Let us look into the major features one by one. The specification of the JDBC 4.0 is maintained under JSR 221.
also read:
There about twenty features are introduced in the JDBC 4.0. The overall features can be categorize under the following four topics:
- Driver and connection management
- Exception handling
- Data type support
- API changes
In this article we explore some of the features mostly used by the programmers. If you have any questions, please post it in the comments section.
2) No need for Class.forName(“DriverName”)
Before the advent of JDBC 4.0, Application Programmers have to manually load the Database Driver before making any Database Calls. The following code shows how to load a Database Driver before JDBC 4.0
Class.forName("FullyQualifiedNameOfTheDriverClass");
This has one major dis-advantage. Suppose if the Database Driver Vendor wishes to change the class name of the Driver, then it will result in Code change. But with the help of Service Provider Mechanism (which is available from Java 5), there is no need for the programmers to manually load the Driver. The Driver will be Loaded Automatically by the JVM if the Jar files that correspond to the Driver Class are in the appropriate class path.
Let us explain how the Service Provider Mechanism works. Two entities are of much interest in the Service Provider Mechanism. One is the Service itself which mostly contains a set of interfaces that deals with what the Service is all about and the other one is the Provider who will give a concrete and a well-defined Implementation for the Service. This Mechanism forces the Provider to package the service as a Jar which has to maintain a Directory Structure like this,
\\META-INF\\services\\FullNameOfTheService
Suppose if the JDBC Driver Provider wishes to make his implementation as a Service, then the Vendor should maintain a Directory Structure along with the file name like this,
\\META-INF\\services\\java.sql.Driver
Note that java.sql.Driver is the name of the File, and the file should contain only one entry which is the Name of the Provider Class that implements the Driver. For example, in the case of My SQL, the content of the file will be looking like the following,
File – Java.sql.Driver
com.mysql.jdbc.Driver # Class name of the Driver
Through this mechanism, the JDBC Drivers will get Automatically Loaded by the Java Program. If there are Multiple Drivers in the Application’s class-path, then the first matching Driver will be taken into consideration and the rest of them will just be ignored.
3) Changes in Connection and Statement Interface
Certain new useful methods are added to the Connection interface. The following sections list down the commonly used methods. To check whether an Connection object is still valid/active or not, then the following method can be used,
int tenSeconds = 10; Connection.isValid(tenSeconds);
The argument to Connection.isValid(int) is the Timeout value, which specifies the time duration the API should take to find out whether the Connection is valid. If the timeout interval exceeds, then false will be returned. A value of 0 for the time-out interval specifies an Infinite Time-out Duration.
Also there are methods for populating and retrieving the Client Information that a particular Driver supports with the help of Connection.getClientInfo() and Connection.setClientInfo(Properties) methods. Client information can also be set and retrieved individually using Connection.setClientInfo(String,String) and Connection.getClientInfo(String) methods.
The following methods are added into the Statement interface, Statement.isClosed(), Statement.setPoolable(boolean) and Statement.isPoolable(). Statement.isClosed() will return true if the Statement Object is closed by calling the Statement.close() method. By default, only PreparedStatement and CallableStatement are pooled by the Implementation. The call to Statement.setPoolable(true) will only act as a request to the Implementation to pool this Statement Object for better performance. Not all the implementations may support this feature and hence Applications should not depend on this feature always.
4) Enhanced SQL Exception Handling
Exception handling in JDBC has been enhanced a lot in JDBC 4.0. The following are the major areas where the enhancements are done.
- Iterable SQL Exception
- Concreate Sub Classes for specific SQL Exception
4.1) Iterable SQL Exception
The java.sql.SQLException now implements the Iterable<Throwable> interface which means that it can be iterated over to get the Next Set of Exceptions and can also be used in Enhanced For-Loops (available from Java 5.0). Consider the following piece of code,
try{ // Some Database Access Code }catch(SQLException exception){ for(Throwable throwable: exception){ System.out.println(throwable.getMessage()); } }
Before JDBC 4.0, Applications depended on SQLException.getNextException() to get the next Exception and looped over until the returned exception is not null.
try{ // Some Database Access Code }catch(SQLException exception){ System.out.println(exception.getMessage()); SQLException nextException = exception.getNextException(); while (nextException != null){ System.out.println(nextException.getMessage()); nextException = nextException.getNextException(); } }
4.2) Concreate Sub Class for specific SQL Exception
More number of SQL Exception related Sub-Classes are added to the API which encapsulates the State of the SQL Error. In general, these Exceptions fall into 3 categories namely Transient, Recoverable and Non-Transient.
Assume that some kind of SQL Exception has occurred during the Program run-time. If again when a try is made and if there is a possibility such that the program can recover from the Exception without making any application specific change, then it is a kind of Transient Exception. This exception is represented by the java.sql.TransientException class and the following are the identified Transient Exceptions in the JDBC 4.0 API.
- SQLTimeoutException
- SQLTransactionRollbackException
- SQLTransientConnectionException
Minute variation of this Transient Exception is the Recoverable Exception which is represented by java.sql.SQLRecoverableException. Here the exception that has happened can be recovered by performing some Application Specific Recovery.
The last flavour of SQL Exception is the Non-Transient Exception and it is represented by java.sql.TransientException. It tells that an exception can never be recovered even though Infinite Number of Tries is performed by the Application Program. The following are the Exceptions available in this Category,
- SQLDataException
- SQLFeatureNotSupportedException
- SQLIntegrityConstraintViolationException
- SQLInvalidAuthorizationSpecException
- SQLNonTransientConnectionException
- SQLSyntaxErrorException
4.3) Support for SQL RowId
Most of the popular Databases support the concept of a Row Id. A Row Id is an unique Identifier which is used to identify a Row. Support for Retrieving and setting the Row Id for a row is made available from JDBC 4.0 version. For example, consider the following piece of code, which will retrieve the value of the Row Id for a particular Row.
String selectQuery = " select rowid from Employees where id ='123' "; ResultSet resultSet = statement.executeQuery("selectQuery"); java.sql.Rowid rowId = resultSet.getRowId();
The Row Id is represented by java.sql.RowId class. Before doing any kind of manipulation on the Row Id, it is wise to check whether the under-lying Database implementation provides Support for Row Id(s), as well as the Lifetime of the Row Id objects. The life-time of the Row Id determines how long the Row Id is valid, whether the Row Id exists only for a particluar Session or for a Set of Transactions within a Session or Outside the Database Session etc. This availability can be known with the help of DatabaseMetaData like the following,
RowIdLifeTime rowIdLifeTime = DatabaseMetaData.getRowIdLifetime(); if (rowIdLifeTime != ROWID_UNSUPPORTED){ // Row Id support is there for this Data source. }
The returned RowIdLifeTime is an Enum which tells about the Life-Time of the Row Id object. Possible values are ROWID_UNSUPPORTED, ROWID_VALID_FOREVER, ROWID_VALID_OTHER, ROWID_VALID_SESSION, ROWID_VALID_TRANSACTION and ROWID_VALID_FOREVER.
5) Conclusion
The new existing features of JDBC 4.0 like the Automatic Driver Loading, various new methods added to em>Connection/Statement interface and Enhanced SQL Exception Handling are also explained.
Please refer our recommended java books section for the complete list of books. Hope this helps. If you are interested in receiving our future Java articles, please subscribe here.