Because the work needs to be used to connect the pool, I have read the article on the Internet, I have learned a lot of experience. Here I want to be a summary, plus my thoughts and together, I hope to give you some help. Objective: To eliminate the overhead and bottlenecks that the database frequently connected. Solution: But more limiting users, there is no much requirement to get and use databases as specified and use databases to keep users' habits. Many of the methods are required to use users to use them according to regulations, cannot be used. Turn off the method of data connection directly. The solution is to use the proxy class to solve the intermediate. You can refer to http://www-900.ibm.com/developerworks/cn/java/developroxy/index.shtml to maintain the normal status of the connection to get the user's habit of maintaining the user by specified method Many methods are required to use the user to use the connection by the specified method, and cannot use a method of directly shutting down the data connection. The solution is to use the proxy class to solve the intermediate. You can refer to http://wwworks/cn/java/developerworks/cn/java/l-connpoolproxy/index.SHTML to maintain the normal state of the connection because the resources created for database connections, if it is not possible to release, it will affect The next time the data connection is used. For example, in SQL 2K, a connection differently creates a plurality of statement otherwise there is an exception of data connection, so these resources must be released after returning the connection. // Judgment is the use of createStatement statement if (CreateState.equals)) {obj = method.invoke (conn, args); statref = (statement) OBJ; // record statement returno;} // Determine if a Close method is called, if the CLOSE method is called to use the connection to useless status if (Close.equals ()) {// setting does not use the flag setisfree (false); // Check if there is subsequent Work, clear the connection free resource IF (statref! = Null) statref.close (); if (Prestatref! = Null) preStatref.close (); return null;} The correct protection class is not used by violations, it is not allowed to make users Just use the proxy class, but only you can use it yourself, one is to use the internal private class, one is the use of only the specified classes can be called. My implementation is the latter. / *** Create a connection factory, only allow factory call * @Param factory to call the factory, and must be correctly initialized * @param param connection parameters * @return connection * / static public _Connection getConnection (ConnectionFactory Factory, ConnectionParam param) {IF (Factory.Iscreate ()) // Determines whether the factory {_connection _conn = new _connection (param); returnne_conn;} elsereturn NULL;} Elsereturn NULL; To get a connection, just like a completely and ordinary Connection method, there is no limit. At the same time, the connection parameter class and factory parameter class are set for convenience.
ConnectionParam param = new ConnectionParam (driver, url, user, password); ConnectionFactory cf = null; // new ConnectionFactory (param, new FactoryParam ()); try {cf = new ConnectionFactory (param, new FactoryParam ()); Connection conn1 = cf.getFreeConnection (); Connection conn2 = cf.getFreeConnection (); Connection conn3 = cf.getFreeConnection (); Statement stmt = conn1.createStatement (); ResultSet rs = stmt.executeQuery ( "select * from requests"); if (rs.next ()) {system.out.println ("conn1 y");} else {system.out.println ("conn1 n");} stmt.close (); conn1.close (); for implementation The normal operation of the connection pool, uses a single mode / *** to create a connection pool using the specified parameters * / public connectionFactory (ConnectionParam param, factoryparam fparam) throws SQLException {// does not allow parameters empty IF ((param == NULL) || (fParam == NULL) "Throw new SQLEXCEPTION (" ConnectionParam and FactoryParam cannot be empty); if (m_instance == null) {synchronized (connectionFactory.class) {if (m_instance == null) {//// New instance // Parameter custom m_instance = new connectionFactory (); m_instance.connparam = param; m_instance.maxconnectioncount = fParam.getmax Conn (); m_instance.MinConnectionCount = fparam.getMinConn (); m_instance.ManageType = fparam.getType (); m_instance.isflag = true; // initialize, create MinConnectionCount connection System.out.println ( "connection factory to create! "); Try {for (int i = 0; i }}}} catch (Exception E) {E.PrintStackTrace ();} // Depending on the policy to determine if IF (M_instance.manageType! = 0) {thread t = new thread (M_Instance); T.Start ( );}}}}} The management of the connection pool For the management of the connection pool, I envision the use of static management and dynamic management, setting up the maximum limit, and constant connections. 2 pools, an idle pool, a pool. Static is used, I found that the idle connection is not enough to check. The dynamic is to use a line-of-time check. / / Determine if the policy is required to query if (m_instance.managetype! = 0) {thread t = new thread (new factoryMANGETHREAD (M_Instance)); T.Start ();} // Connection pool scheduling thread public class factoryMANGETHREAD IMPLEMENTS RunNable { ConnectionFactory Cf = NULL; long delay = 1000; public factoryMANGETHREAD (ConnectionFactory obj) {cf = obj;} / * (non-javadoc) * @see java.lang.Runnable # Run () * / public void Run () {while (TRUE) {TREAD.SLEP (DELAY);} catch (interruptedException e) {} system.out.println ("eeeee"); // Judgment whether it has closed the factory, then exit the listener IF (CF.iscreate ()); elseSystem.exit (1);}}} Finally give a complete source code: _Connectio.javaPackage scut.ailab.connectionpool; import java.lang.reflect. *; import java.sql. *; / *** @author youyongming * proxy class defines the database connection * / public class _Connection implements InvocationHandler {// define the connection private connection conn = null; // define statement monitor connections created private statement statRef = null; private PreparedStatement PRESTATREF = NULL; / / Whether to support transaction logo private boilean supporttransaction = false; // Database busy status private bolean isfree = false; // Last access time long lastaccesstime = 0; // Define the name of the function to take over String Creat ESTATE = "createstatement"; string close = "close"; string prepareStatement = "preparestatement"; string commit = "commit"; string rollback = "rollback"; / *** Constructor, using private, prevent direct creation * @ @@ PARAM PARAM Connection Parameters * / Private_Connection (ConnectionParam Param) {// Record Day to Try {// Create Connection Class.Forname (param.getdriver ()). NewInstance (); conn = drivermanager.getConnection (param.geturl () , param.getuser (), param.getpassword ()); DatabaseMetadata DM = NULL; DM = conn.getMetadata (); // Judgment whether to support transaction supportTransaction = dm.supportstransactions ();} catch (Exception E) {e. PRINTSTACKTRACE ();}} / * (non-javadoc) * @ see java.lang.reflect.InvocationHandler # invoke * (java.lang.Object, java.lang.reflect.Method, java.lang.Object []) * / public Object invoke (Object proxy, Method method, Object [] args "throws throwable {Object obj = null; // Determine whether to call a Close method, if the CLOSE method is called, the connection is set to the useless status IF (Close.equals ()) {// Settings not using the flag Setisfree (false); // Check if there is a follow-up, clear the connection free resource IF (StATREF! = null) statref.close (); if (PRESTATREF! = null) Prestatref.close (); Return null;} // Judgment is the use of createStatement statement if (createState.equals)) {obj = method.invoke (conn, args); statref = (statement) OBJ; // record statement returna;} // judgment is Used prepaarestatement statement if (preparestatement.equals) {obj = method.invoke (conn, args); PRESTATREF = (preparedStatement) Obj; return obj;} // If you do not support transactions, The code IF ((method.getname ()) || rollback.equals (Method.GetName ()) && (! Issupporttransaction ()) Return Null; Obj = method.invoke (conn, args ); // Set the last access time to clear the timeout connection LastAccesstime = system.currenttimemillis (); return obj;} / *** Create a connection factory, only allow factory call * @Param FAC Tory wants to call the factory, and must be correctly initialized * @Param param connection parameters * @return connection * / static public _connection getConnection (ConnectionFactory Factory, ConnectionParam param) {if (factory.iscreate ()) // Determine whether it is correctly initialized factory {_Connection _conn = new _Connection (param); return _conn;} elsereturn null;} public connection getFreeConnection () {// return the database connection conn takeover classes so as to capture close method connection conn2 = (connection) Proxy.newProxyInstance (conn . GetClass (). getClassLoader (), conn.getclass (); getInterface (); return conn2;} / *** This method is really turned off the connection of the database * @throws sqlexception * / void Close () THROWS SQLEXCEPTION {// Since the class attribute CONN is not a connected connection, once the Close method is called, connect the connection conn.close (); } Public void setIsFree (boolean value) {isFree = value;} public boolean isFree () {return isFree;} / *** Analyzing supports transactions * @return boolean * / public boolean isSupportTransaction () {return supportTransaction;}} ConnectionFactory .java package scut.ailab.connectionpool; / *** @author youyongming ** / import java.util.LinkedHashSet; import java.sql *;. import java.util.Iterator; public class ConnectionFactory {private static ConnectionFactory m_instance = null ; // use the connection pool private LinkedHashSet ConnectionPool = null; // free connection pool private LinkedHashSet FreeConnectionPool = null; // maximum number of connections private int MaxConnectionCount = 4; // minimum number of connections private int MinConnectionCount = 2; // current the number of connections private int current_conn_count = 0; // connection parameters private ConnectionParam connparam = null; // whether to create a private boolean flag factory isflag = false; // whether to support the transaction private boolean supportTransaction = false; // define management strategies private int ManageType = 0; private connectionFactory () {connectionPool = new linkedHashSet (); freeConnectionPool = new linkedHashSet ();} / *** Create a connection pool * / public connectionFact ORY (ConnectionParam PARAM, FACTORYPARAM FPARAM) THROWS SQLEXCEPTION {// Does not allow parameters i ((param == null) | (fparam == null)) Throw new SQLEXCEPTION ("ConnectionParam and FactoryParam can not be empty); if (m_instance == null) {synchronized (ConnectionFactory.class) {if (m_instance == null) {// new instance // custom parameter m_instance = new ConnectionFactory (); m_instance.connparam = param; m_instance.MaxConnectionCount = fparam.getMaxConn (); m_instance.MinConnectionCount = fparam.getMinConn (); m_instance.ManageType = fparam.getType (); m_instance.isflag = true; // initialize, create MinConnectionCount connection System.out.println ( "connection factory to create! "); try {for (int i = 0; i m_instance.freeConnectionPool.add (_CONN); m_instance.current_conn_count ;}} else {// If you can't create it, check if there is a returned connection iter = m_instance.connectionpool.iterator (); while (ore (it)) {_Connection _conn = (_Connection) iter.next (); if (! _ conn.isFree ()) {conn = _conn.getFreeConnection (); _ conn.setIsFree (false); m_instance.ConnectionPool.remove (_conn); m_instance.FreeConnectionPool .add (_conn); break;}}}} // if (FreeConnectionPool.iseMpty ()) // checks if it can allocate connection if (conn == null) {{it oderator (); while iter.hasnext () {_ connection _conn = (_Connection) ney.next (); if (! _ conn.isfree ()) {conn = _conn.getfreeConnection (); _ conn.setisfree (true); m_instance.freeConnectionPool.remove ( _CONN); m_instance.connectionpool.add (_); break;}} if (conn == null) // If you can't explain that there is no connection to use Throw new SQLException ("Database connection available");} System.out. Println ("Get Connection"); Return Conn;} / *** Close all database connections in the connection pool * @throws sqlexception * / public synchronized void close () throws sqlexception {this.isflag = false; sqlexception eXCP = null ; // Turn off the idle pool Iter ATORTORTER = m_instance.freeConnectionPool.iterator (); while (ore.hasnext ()) {try {((_ connection) ney.next ()). Close (); System.out.Println ("Close Connection: Free") ; m_instance.current_conn_count -;} catch (eXception e) {if (e instanceof sqlexception) eXCP = (sqlexception) e;}} // Close the connection pool Iter = m_instance.connectionpool.ITERATOR (); While (Iter) .hasNext ()) {Try {(_ connection) iter.next ()). Close (); system.out.println ("Close Connection: Inused"); m_instance.current_conn_count -;} catch (Exception E) { IF (e instanceof sqlexception) EXCP = (SQLException) E;}}} if (eXCP! = null) throw eXCP;} / *** Return to support transaction * @ Return Boolean * / Public Boolean IssupportTransaction () {return m_instance.supporttransaction;} / *** Connection pool scheduling management ** / public void schedule () {connection conn = null; // Check if you can assign iterator iter = NULL; / / Check if there is a returned connection {{{itrator (); while (ore (ore.hasnext ()) {_ connection _conn = (_ecion) ney orext (); if (! _ Conn.isfree ()) {conn = _conn.getFreeConnection (); _ conn.setIsFree (false); m_instance.ConnectionPool.remove (_conn); m_instance.FreeConnectionPool.add (_conn); break;}}} if (m_instance.current_conn_count } Public String getPassword () {return password;} public String getUrl () {return url;} public String getUser () {return user;} public void setDriver (String driver) {this.driver = driver;} public void setPassword ( String password) {this.password = password;} public void seturl (string URL) {this.url = url;} public void setuser {this.user = user;} / *** @see java.lang . Object # clone () * / public object clone () {ConnectionParam param = New ConnectionParam (driver, url, user, password); return param;} / *** @see java.lang.object # equals (java.lang .Object) * / public boolean equals (Object obj) {if (obj instanceof ConnectionParam) {ConnectionParam param = (ConnectionParam) obj; return ((driver.compareToIgnoreCase (param.getDriver ()) == 0) && (url.compareToIgnoreCase (param.geturl ()) == 0) && (user.comparetoirenorecase (param.getuser ()) == 0) && (Parasword.comParetoIgnore (param.getpassword ()) == 0));} Return False; } FactoryMangethread.java / ** created on 2003-5-13 ** To change the Template for this generated file go to * Window> Preferences> Java> Code Generation> Code and Comments * / package scut.ailab.connectionpool; / *** @author youyongming ** /// connection pool scheduling threads public class FactoryMangeThread implements Runnable {ConnectionFactory cf = null; long DELAY = 1000; Public FactoryMANGETHREAD (ConnectionFactory obj) {cf = obj;} / * (non-javadoc) * @see java.lang.Runnable # Run () * / public void run () {while (true) {TRY { Thread.sleep (delay);} catch (interruptedException e) {} system.out.println ("eeeee"); // Judgment whether the factory has closed, then exit the listener IF (cf.iscreate ()) cf.schedule (); elsesystem.exit (1); }}} FactoryParam.java / ** Created on 2003-5-13 ** To change the template for this generated file go to * Window> Preferences> Java> Code Generation> Code and Comments * / package scut.ailab.connectionpool; / *** @Author youyongming ** /// Connection pool plant parameter PUBLIC CLASS FACTORYPARAM {// Maximum connection number private int maxConnectionCount = 4; // Minimum connection number private int minConnectionCount = 2; // Recycling Policy Private Int ManageType = 0; public factoryparam () {} / *** Sign in connection pool factory parameters * @Param max Maximum connection * @Param min minimum connection * @Param Type management policy * / public factoryParam (int MAX, int Min, int type) {this.ManageType = type; this.MaxConnectionCount = max; this.MinConnectionCount = min;} / *** set the maximum number of connections * @param value * / public void setMaxConn (int value) {this.MaxConnectionCount = Value;} / *** Get the maximum number of connections * @ return * / public int getMaxConn () {return this.maxconnectioncount;} / *** Set the minimum connection * @Param value * / public void setminconn (int value) { THIS.MINCONNECNT = value;} / *** Get minimum connections * @ return * / public int getminConn () {return.com;} public int GETTYPE () {Return this.manageTyp e;}} testmypool.java / ** Created on 2003-5-13 ** To change the template for this generated file go to * Window> Preferences> Java> Code Generation> Code and Comments * / package scut.ailab.connectionpool / *** @Author Youyongming ** / import java.sql. *; Public class test1 () {String user = "devteam"; string password = "devteam"; string driver = "sun.jdbc. odbc.JdbcOdbcDriver "; String url =" jdbc: odbc: gfqh2 "; ConnectionParam param = new ConnectionParam (driver, url, user, password); ConnectionFactory cf = null; // new ConnectionFactory (param, new FactoryParam ()); try {cf = new ConnectionFactory (param, new FactoryParam ()); Connection conn1 = cf.getFreeConnection (); Connection conn2 = cf.getFreeConnection (); Connection conn3 = cf.getFreeConnection (); Statement stmt = conn1.createStatement (); ResultSet rs = Stmt.executeQuery ("Select * from requests"); if (rs.next ()) {system.out.println ("conn1 y");} else {system.out.println ("conn1 n");} stmt .close (); conn1.close (); Connection conn4 = cf.getFreeConnection (); Connection conn5 = cf.getFreeConnection (); stmt = conn5.createStatement (); rs = stmt.executeQuery ( "select * from requests") ; if (rs.next ()) {System.out.Println ("Conn5 Y");} else {system.out.println ("conn5 n");} conn2.close (); conn3.close (); Conn4.close (); conn5.close ();} catch (exception e) {E.PrintStackTrace ();} finally {try {cf.close ();} catch (exceptstacktrace ();} }}} Public static void main (string "args) {string user =" devteam "; string password =" devteam "; string driver =" sun.jdbc.odbc.jdbcodbcdriver "; string url =" jdbc: odbc: gfqh2 " ConnectionParam param = new co nnectionParam (driver, url, user, password); ConnectionFactory cf = null; // new ConnectionFactory (param, new FactoryParam ()); try {cf = new ConnectionFactory (param, new FactoryParam ()); ConnectionFactory cf1 = new ConnectionFactory ( Param, New FactoryParam (); connection conn1 = null; long time = system.currenttimemillis (); for (int i = 0; i <10; i ) {conn1 = cf.getfreeConnection (); statement stmt = conn1.creatementStatement (); ResultSet RS = Stmt.executeQuery ("SELECT * from Requests"); if (rs.next ()) {system.out.println ("conn1 y");} else {system.out.println ("