This topic describes how to access connection pools from application components such as servlets and JavaServer Pages (JSP) files. This includes instructions for obtaining a connection from a connection pool and returning that connection back to the pool once the application component is finished using it.
Connection pooling is defined as part of the JDBC 2.0 Optional Package. Another part of the Optional Package provides for the use of the Java Naming and Directory Interface (JNDI) and DataSource objects to access relational databases. IBM has implemented these extensions in WebSphere Application Server - Express. These extensions are explained using code fragments that show how relational databases are accessed by application components using the JDBC 2.0 Optional Package.
JDBC 2.0 defines the Java APIs for access to relational databases. With the introduction of JDBC 2.0, the APIs have been split into two parts:
The JDBC 2.0 Core API
The Core API contains evolutionary improvements, but has been kept small and focused in order to promote ease of use. The 2.0 API classes and interfaces are located in the java.sql package that is shipped with each JDBC driver. You can use these classes and interfaces in your application components by using this import statement: import java.sql.*;
The JDBC 2.0 Optional Package
The Optional Package defines specific kinds of additional functionality when vendors are ready to provide the functionality and programmers are ready to use the functionality. WebSphere Application Server - Express supports the JDBC 2.0 Optional Package and implements connection pooling. Therefore, application components can be coded to make efficient use of database connection resources.
The JDBC 2.0 Optional Package classes and interfaces are located in the javax.sql package that is shipped with each JDBC driver. You can use these classes and interfaces in your application components by using this import statement: import javax.sql.*;
WebSphere Application Server - Express uses JNDI caching. This function has implications on the results received from JNDI lookups. Because data sources are generally static, this should not affect most application components using connection pooling.
Connection pooling can be used by application components such as servlets and JSP files.
To obtain a connection in your application components, you must obtain a connection from a connection pool using a data source object, use that connection, and then return the connection back to the connection pool. These coding concepts are shown in the code fragments in these steps:
Make sure that j2ee.jar is specified in your classpath. These files are necessary to import the packages mentioned in the next step and to successfully compile your application component. These files are in the /QIBM/ProdData/WebASE/ASE5/lib directory.
Import JDBC packages and IBM implemented extensions. Import the JDBC 2.0 Core classes, the IBM implementation of the JDBC 2.0 Optional Package classes, and the JNDI naming classes. These are the classes needed for database access:
import java.sql.*; import javax.sql.*; import javax.naming.*;
Additionally, import the application component specific packages required for the application components that you are writing. For example, import the following packages if you are writing a servlet application component:
import javax.servlet.*; import javax.servlet.http.*;
Using JNDI, obtain the initial JNDI context for the naming service. (For more information, see Obtain the initial JNDI context for the component.) JNDI provides a way to store objects and files (such as DataSource objects) as well as a way to retrieve them. The initial JNDI context is used to access the JNDI naming server to retrieve a reference to a DataSource object.
Using the initial JNDI context, look up a data source object. (For more information, see Use JNDI to look up Java components.) The DataSource object is defined in the JDBC 2.0 Optional Package. The actual name to look up is defined by the DataSource object. See Configure WebSphere Application Server - Express to access databases for information on configuring a data source and its JDBC provider using the WebSphere Application Server administrative console.
DataSource objects are stored in the jdbc context. For example, if you have a DataSource named AccountDataSource, the JNDI name for that DataSource would be jdbc/AccountDataSource.
Note: The JNDI name can be read from an external property file or application environment variable, making the application component more portable.
The DataSource object is a factory that you use to get an actual JDBC Connection object. For each client request made to the application component, a connection is retrieved from the DataSource object. For example:
conn = ds.getConnection();
Note: Obtaining a connection from the DataSource object retrieves an available connection from the connection pool that is associated with the DataSource object.
Use the Connection object to create one or more Statement objects. Queries and updates use Statement objects to perform SQL interactions with the database. The JDBC 2.0 Core API provides classes and interfaces for accessing relational database. For example, you could use a Statement object to run an SQL SELECT statement against a relational database file that returns its results in the form of a ResultSet object.
Close all result set and statement objects that were used by the connection:
myResultSet.close() myStatement.close()
Note: Implicitly, these objects are closed when the connection is closed, but explicitly closing them can improve performance and can eliminate JDBC timing issues that can cause memory leaks in your application components.
At the end of each client request, free the connection resource:
conn.close()
Note: The Connection object is not actually closed when the close() method is invoked on it, so there is no close-related overhead. Instead, the Connection object is returned to the connection pool for reuse. In a similar fashion, the earlier getConnection() method on the DataSource object did not incur the overhead of creating a new Connection object, but instead returned an existing Connection object from the connection pool. (A new Connection object is created only if the connection pool does not have an available Connection object.)
In some application environments or with some data sources, there might be no automatic connection pooling mechanism associated with a DataSource object. Thus, every getConnection() method call on a DataSource object and the related close() operation can in fact incur the overhead of creating a new connection and closing that connection. Within WebSphere Application Server - Express, however, using a DataSource object to get a Connection object automatically provides the efficiencies of connection pooling.