El varsiones anteriores a JDBCTM 2.0 cada sesión de base de datos requería una nueva conexión y un login incluso si la conexión anterior usaba la misma tabla y cuenta de usuario. Si estámos usando versioens anteriores al JDBC 2.0 y queremos mejorar el rendimiento, podemos cachear las conexiones JDBC.
Las conexiones cacheadas se mantienen un objeto pool en tiempo de ejecución y pueden ser utilizadas y reutilizadas cuando las necesite la aplicación. Una forma de implementar un objeto pool es hacer una una simple hashtable de objetos conection. Sin embargo, una forma más sencilla de hacerlo es escribir un driver JDBC envuelto que es un intermediario entre la aplicación y la base de datos.
La envoltura trabaja particulamente en los Beans de Enterprise que san persistencia manejada por el Bean por dos razones: 1) Sólo se carga una clase Driver por cada Bean, y 2) los detalles específicos de la conexión se manejan fuera del Bea.
Esta sección explica cómo escribir una clase Driver JDBC envuelta
Un objeto JDCConnectionManager es creado por una aplicación que pretende una conexión con una base de datos. La aplicación proprociona el ULR para la base de datos, el ID del usuario y la password.
El constructor JDCConnectionManager hace esto:
public JDCConnectionDriver(String driver,
String url,
String user,
String password)
throws ClassNotFoundException,
InstantiationException,
IllegalAccessException,
SQLException {
DriverManager.registerDriver(this);
Class.forName(driver).newInstance();
pool = new JDCConnectionPool(url, user, password);
}
Cuando el programa llamante necesita una conexión con la base de datos, llama al método JDCConnectionDriver.connect, que a su vez, llama al método JDCConnectionPool.getConnection.
public synchronized Connection getConnection()
throws SQLException {
JDCConnection c;
for(int i = 0; i < connections.size(); i++) {
c = (JDCConnection)connections.elementAt(i);
if (c.lease()) {
return c;
}
}
Connection conn = DriverManager.getConnection(
url, user, password);
c = new JDCConnection(conn, this);
c.lease();
connections.addElement(c);
return c;
}
La clase JDCConnection.java representa una conexión JDBC en el almacen de conexiones, y esencialmente es una envoltura alrededor de un conexión real JDBC. El objeto JDCConnection mantiene una bandera de estado para indicar si la conexión está en uso y el momento en que la conexión se sacó del almacen. Este tiempo es usado por la clase ConnectionReaper.java para identificar las conexiones colgadas.
La clase ConnectionReaper decide que una clase está muerta cuando se cumplen las siguientes condiciones:
public boolean validate() {
try {
conn.getMetaData();
}catch (Exception e) {
return false;
}
return true;
}
public void close() throws SQLException {
pool.returnConnection(this);
}
Cuando se crea el primer objeto RegistrationBean, crea un ejemplar estático de la clase JDCConnectionDriver. Este objeto driver estático se registra a sí mismo con el DriverManager en el constructor JDCConnectionDriver poniendo disponibles la solicitudes de conexiones para todos los objetos RegistrationBean creados por la aplicación cliente.
Pasar la URL como jdbc:jdc:jdcpool en el método getConnection permite que el DriverManager corresponda la getConnection solicitada al driver registrado. El DriverManager usa un sencillo String para encontrar un driver disponible que pueda manejar URLs en ese formato.
public class RegistrationBean implements EntityBean{
private transient EntityContext ctx;
public String theuser, password;
public String creditcard, emailaddress;
public double balance;
//Static class instantiation
static {
try{
new pool.JDCConnectionDriver(
"COM.cloudscape.core.JDBCDriver",
"jdbc:cloudscape:ejbdemo",
"none", "none");
}catch(Exception e){}
}
public Connection getConnection()
throws SQLException{
return DriverManager.getConnection(
"jdbc:jdc:jdcpool");
}
}