Keywords: Java, JDBC, Connection Pool, Database, Database Connection Pool, SourceCode
Although J2EE programmers generally have a JDBC database connection pool belonging from ready-made application servers, it is not much for developing a general Java Application, Applet or JSP, Velocity, there are not many JDBC database connecting pools, and general performance is not Great. Java programmers are envious of Windows ADO, just need to return to the database directly from the Database Connection Pool. And ADO Connection is a thread safe, multiple threads can share a connection, so the ASP program generally places the getConnection in the global.asa file, and establish a database connection when IIS is started. ADO's Connection and Result have a good buffer and is easy to use. In fact, we can write a JDBC database connection pool. Precautions for writing JDBC Connection Pool are: 1. A simple function gets a connection from the connection pool. 2. The Close function must put the Connection back to the database connection pool. 3. When there is no idle Connection in the database connection pool, the database connection pool must be able to automatically increase the number of Connection. 4. When the number of Connection in the database connection pool is very large in a particular time, only one of the small parts will be used for a long time, and you should automatically turn off excess Connection. 5. If possible, you should provide the debug information report that does not close NEW Connection. If you want to return to the database connection pool directly, you can write (Mediator Pattern) (Chinese full-width space): public class easyconnection imports java.sql.connection = null; public; EasyConnection () {m_delegate = getConnectionFromPool ();} public void close () {putConnectionBackToPool (m_delegate);} public PreparedStatement prepareStatement (String sql) throws SQLException {m_delegate.prepareStatement (sql);} // ...... other Method} It doesn't seem to be difficult. However, this way is not recommended, because you should try to avoid using Java Interface, the shortcomings of Java Interface I will write another article discussions. Everyone pays attention to the implementation of Connection Pool. A implementation method is given below.
import java.sql *;. import java.lang.reflect *;. import java.util *;. import java.io *;. public class SimpleConnetionPool {private static LinkedList m_notUsedConnection = new LinkedList (); private static HashSet m_usedUsedConnection = new HashSet (); private static String m_url = ""; private static String m_user = ""; private static String m_password = ""; static final boolean DEBUG = true; static private long m_lastClearClosedConnection = System.currentTimeMillis (); public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000; // 4 hours static {initdriver ();} private simpleconnetic () {} private static void = null; // load mysql driver try {driver = (driver) Class.Forname ("com.mysql.jdbc.driver). NewInstance (); installDriver;} catch (exception e) {} // load postgreSQL driver try {driver = (driver) class.forname (" ORG) .postgresql.driver "). Newinstance (); installDriver;} catch (Exception e) {}} public static void installDriver (Driver driver) {try {DriverManager.registerDriver (driver);} catch (Exception e) {e.printStackTrace ();}} public static synchronized Connection getConnection () {clearClosedConnection ( ); while (m_notUsedConnection.size ()> 0) {try {ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst (); if (wrapper.connection.isClosed ()) {continue;} m_usedUsedConnection.add (wrapper); if ( DEBUG) {wrapper.debuginfo = new throwable ("Connection Initial Statement");
} Return wrapper.connection;} catch (Exception e) {}} int newCount = getIncreasingConnectionCount (); LinkedList list = new LinkedList (); ConnectionWrapper wrapper = null; for (int i = 0; i } Catch (Exception e) {}} m_usedUsedConnection.clear (); return count;} private static void clearClosedConnection () {long time = System.currentTimeMillis (); // sometimes user change system time, just return if (time } / ** * get decreasing connection count, not just remove 1 connection * @return count * / public static int getDecreasingConnectionCount () {int count = 0; int current = getConnectionCount (); if (current <10) {return 0; } return current / 3;} public synchronized static void printDebugMsg () {printDebugMsg (System.out);} public synchronized static void printDebugMsg (PrintStream out) {if (DEBUG == false) {return;} StringBuffer msg = new StringBuffer ( ); Msg.Append ("Debug Message IN" SimpleConnepool.class.getName ()); msg.Append ("/ r / n"); msg.append ("Total Count Is Connection Pool:" getConnectionCount ()) Msg.Append ("/ r / n"); msg.append ("NOT USED Connection Count: GetNotusedConnectionCount ()); msg.append (" / r / n "); msg.append (" Used Connection, Count: " getusedConnectionCount ()); out.println (msg); iterator itrator = m_usedusedconnection.iterator (); while (iterator.hasnext ()) {ConnectionWrap per wrapper = (ConnectionWrapper) iterator.next (); wrapper.debugInfo.printStackTrace (out);} out.println ();} public static synchronized int getNotUsedConnectionCount () {return m_notUsedConnection.size ();} public static synchronized int getUsedConnectionCount () {return m_usedUsedConnection.size ();} public static synchronized int getConnectionCount () {return m_notUsedConnection.size () m_usedUsedConnection.size ();} public static String getUrl () {return m_url;} public static void setUrl (String URL) {if (URL == NULL) {RETURN;} m_url = url.trim (); } Public static String getUser () {return m_user;} public static void setUser (String user) {if (user == null) {return;} m_user = user.trim ();} public static String getPassword () {return m_password ;} public static void setPassword (String password) {if (password == null) {return;} m_password = password.trim ();}} class ConnectionWrapper implements InvocationHandler {private final static String CLOSE_METHOD_NAME = "close"; public Connection connection = null; private Connection m_originConnection = null; public long lastAccessTime = System.currentTimeMillis (); Throwable debugInfo = new Throwable ( "Connection initial statement"); ConnectionWrapper (Connection con) {Class [] interfaces = {java.sql.Connection. class}; this.connection = (Connection) Proxy.newProxyInstance (con.getClass () getClassLoader (), interfaces, this.); m_originConnection = con;} void close () throws SQLException {m_originConnection.close (); } Public Object invoke (Object proxy, Method m, Object [] args) throws Throwable {Object obj = null; if (CLOSE_METHOD_NAME.equals (m.getName ())) {SimpleConnetionPool.pushConnectionBackToPool (this);} else {obj = m.invoke (m_originConnection, args);} lastAccessTime = System.currentTimeMillis (); return obj;}} use public class TestConnectionPool {public static void main (String [] args) {SimpleConnetionPool.setUrl (DBTools.getDatabaseUrl ()) SimpleConNetionPool.Setuser (DBTools.GetDatabaseUserName ()); SimpleConnepool.SetPassword (DBTools.getDatabasePassword ()); connection con =