|
It's common to inherit a bit of code written with neither DataSources nor connection pooling of any sort in mind at all. For a variety of reasons, it may not be feasible to change your existing program logic (beyond editing the JDBC connection strings). Fortunately, DBCP supports the notion of a PoolingDriveran implementation of a JDBC driver that implements a connection pool behind the scenes. As long as your application code opens and closes connections properly, you can add connection pooling at any time. Listing 6-4 shows how a bit of legacy code can be adapted to support a connection pool. As you can see, you will still need to add a bit of code to initialize the connection pool (as shown in the registerPoolingDriver() method) to your legacy application's initialization process. Listing 6-4. Legacy JDBC Application Connection Poolingpackage com.cascadetg.ch06; import org.apache.commons.pool.ObjectPool; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.dbcp.*; import java.sql.DriverManager; import java.sql.Driver; import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.util.Properties; public class LegacyJDBCExample { public static void main(String[] args) { registerPoolingDriver(); legacyJDBCCode(); } /** This method represents a bit of legacy code. It's assumed that * in your "real" legacy code, you have at least broken out or can * easily change the Driver and JDBC URL. The legacy username and * password are ignored when connecting to the new pool. */ public static void legacyJDBCCode() { // Note the commented out "old driver" and "old JDBC URL" //String legacyDriver = "com.mysql.jdbc.Driver"; String legacyDriver = "org.apache.commons.dbcp.PoolingDriver"; //String legacyJdbcConnection = // "jdbc:mysql://localhost/commons"; String legacyJdbcConnection = "jdbc:apache:commons:dbcp:example"; // The legacy username and password are ignored String legacyUsername = "ralph"; String legacyPassword = "bingo"; Connection myConnection = null; try { Driver myDriver = (Driver)Class.forName(driver).newInstance(); // The connection is obtained as before, but now the // connection comes from the pool. myConnection = DriverManager.getConnection( legacyJdbcConnection, legacyUsername, legacyPassword); Statement myStatement = myConnection.createStatement(); String testSQL = "SELECT NOW()"; ResultSet myResults = myStatement.executeQuery(testSQL); while (myResults.next()) { System.out.println(myResults.getString(1)); } myResults.close(); myStatement.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (myConnection != null) try { // When closed, the connection is returned // to the pool. If your legacy code doesn't // do this, eventually the pool will starve - // although you are likely already running into // problems. myConnection.close(); } catch (Exception x) { } } } // These are the real database connectivity strings, // used by the pool. private static final String driver = "com.mysql.jdbc.Driver"; private static final String username = "root"; private static final String password = ""; private static final String jdbcConnection = "jdbc:mysql://localhost/commons"; public static void registerPoolingDriver() { // An object pool is used to maintain the connections. Any // pool may be used - for more information, see chapter 6 ObjectPool connectionPool = new GenericObjectPool(null); // The connection pool factory can pass properties on // as needed. The obvious candidates are username and // password, others will depend on your database, driver, // etc. Properties myDriverConnectionProps = new Properties(); myDriverConnectionProps.put("username", username); myDriverConnectionProps.put("password", password); // The factory is used by the driver to create new // JDBC connections, based on the driver provided. ConnectionFactory connectionFactory = null; try { Class.forName(driver); Driver myDriver = (Driver)Class.forName(driver).newInstance(); connectionFactory = new DriverConnectionFactory( myDriver, jdbcConnection, myDriverConnectionProps); // The PoolableConnectionFactory wraps the actual // Connections created by the ConnectionFactory // with pooling driver classes that implement the // pooling functionality. PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( connectionFactory, connectionPool, null, null, false, true); // Next, attach our pooling driver as a registered driver Class.forName("org.apache.commons.dbcp.PoolingDriver"); PoolingDriver driver = (PoolingDriver)DriverManager.getDriver( "jdbc:apache:commons:dbcp:"); // Associate the identifier example with this connection // pool. We might register two different pools for // different database connectivity options. driver.registerPool("example", connectionPool); } catch (Exception e) { e.printStackTrace(); } } } |
|