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 use, that is, the user does not require users to get and use database connections according to the specified methods, and try to maintain the user's habits. Many of the methods are required to use users to use them according to regulations. You 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 2000, a connection cannot create multiple statement, otherwise, there is an exception of the 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, can only let the 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 it is correctly initialized factory {_connection _conn = new _connection (param); return_con;} Else Return NULL;} Provide a good user interface, simple and practical use of static methods to create a factory, Then come to get the connection, which is not limited using the fully and ordinary Connection method. 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 / ** * 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 connection ctionFactory (); 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 a MINCONNECNT connection system.out.println ("" Connection Factory creates! "); Try {for (int i = 0; i m_instance.FreeConnectionPool.add (_conn); // Add free connection pool m_instance.current_conn_count ; // support transaction flag m_instance.supportTransaction = _conn.isSupportTransaction ();}} catch (Exception e) {e.printStackTrace () } // 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 management for connectivity The pool management, I envisage two strategies to use static management and dynamic management, set maximum, 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 ()); Else system.exit (1);}}} Finally give a complete source code: ---------------------- -------------------------------------------------- --------_Connectio.javaPackage scut.ailab.connectionpool; import java.lang.reflect. *; Import java.sql. *; / ** * @Author YouYongming * Define database connection proxy * / public iC Class _Connection Implements InvocationHandler {// Defines Connection Private Connection Conn = NULL; // Defines the Scriptures created by Monitor Connection Private Statement StatRef = Null; Private PreparedState Prestatref = NULL; / / Whether to support transaction logo private boilean supportTransaction = false; // Database busy status private boolean isfree = false; // Last time access time long lastaccesstime = 0; // Define the name of the function to take over String CreateState = "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 date 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 support 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 if a Close method is called, if the CLOSE method is called, the connection is set to the useless state IF (Close.equals ()) {// setting is not Use the logo 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 returno;} // Judgment is the use of PrePareStatement statement if (preparestatement.equals)) {obj = method.invoke (conn, args); PRESTATREF = (preparedStatement) Obj; Return Obj;} // If the transaction is not supported, the code IF is not implemented ((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, It can only be called * @Param Factory to call the factory, and must be initialized correctly * @param param connection parameters * @return connection * / static public _Connection getConnection (connectionParam param) {if (factory.iscreate ()) / / Judgment whether it is correctly initialized factory {_connection _conn = new _Connection (param); return_conn;} else return null; } Public connection getfreeConnection () {// Returns the trap connection of CONN to CONN to intercept the Close method connection conn2 = (conn.getclass (). GetClassLoader (), conn.getClass (). GetInterfaces ); return conn2;} / ** * This method is really turned off the database of the database * @throws sqlexception * / void close () throws sqlexception {// Because the class attribute conn is not connected to the connection, After calling the close method, close the connection conn.close ();} public void setisfree (isfree = value;} public boolean isfree () {return isfree;} / ** * Judging whether to support 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; // connected in use Pool Private LinkedHashSet ConnectionPool = NULL; // Free Connection Pool Private LinkedHashSet FreeConnection Pool = null; // Maximum number of connections private int MaxConnectionCount = 4; // minimum number of connections private int MinConnectionCount = 2; // current number of connections private int current_conn_count = 0; // connection parameters private ConnectionParam connparam = null; // if create a factory logo private boolean 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 using the specified parameters * / public connectionFactory (ConnectionParam param, factoryparam fparam) throws sqlexception {// does not allow parameters to empty IF ((param == null) || (fParam == null )) Throw new sqlexception (" ConnectionParam and FactoryParam 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 Create!"); try {for (int i = 0; i While (ore.hasnext ()) {_connection _conn = (_connection) ney orext (); // Find unused connection if (! _ conn.isfree ()) {conn = _conn.getfreeConnection (); _conn.setisfree (True ); // remove idle area m_instance.freeConnectionPool.remove (_CONN); // Add to connect pool m_instance.connectionpool.add (_con); break;}} // check if the idle pool is empty if (m_instance.freeConnectionPool.iseMpty) )) {// check if it can re-allocation if (m_instance.current_conn_count _Connection_Conn = _Connection.getConnection (m_instance, m_instance.connparam); m_instance.freeConnectionPool.Add (_conn); m_instance.current_conn_count ;}} Else { // If you can't create it, check if there is a connection that has been returned. iter = m_instance.connectionpool.ITERATOR (); While (item.hasnext ()) {_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;}}}}} FREECONNECTIONPOOL.ISEMPTY ()) / / Check if it can be assigned a connection again IF (conn == null) {{= M_instance.freeConnectionPool.iterator (); While (item.hasnext ()) {_CONNECTION _CONN = (_Connection) iter.next (); IF (! _ conn.isfree ()) { CONN = _Conn.getfreeConnection (); _Conn.setisfree (TRUE); m_instance.freeConnectionPool.Remove (_CONN); m_instance.connectionpool.add (_conn); Break;}} if (conn == null) // If you can't, you will use it without connection. 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; // Close the idle pool Iterator it = m_instance.freeConnectionPool.iterator (); While (item.hasnext ()) { Try {(_Connection) iter.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 in use iter = m_instance.connectionpool.ITERATOR (); While (item.hasnext ()) { Try { ((_Connection) ore.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 transactions * @Return Boolean * / Public Boolean IssupportTransaction () { Return m_instance.supporttransaction;} / ** * Connection pool scheduling management * * / public void schedule () {Connection conn = null; / / Check if it is possible to assign Iterator it = null; / / Check if there is a connection that has been returned { iter = m_instance.connectionpool.ITERATOR (); While (item.hasnext ()) {_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 (m_instance.current_conn_count { // Newly connected to idle connection pool INT newcount = 0; // to achieve the number of established IF (m_instance.maxconnectioncount - m_instance.current_conn_count> = m_instance.minConnectionCount) { Newcount = m_instance.minConnectionCount; } Else { Newcount = m_instance.maxConnectionCount - m_instance.current_conn_count;} // Create a connection For (int i = 0; i { _Connection_Conn = _Connection.getConnection (m_instance, m_instance.connparam); m_instance.freeConnectionPool.Add (_conn); m_instance.current_conn_count ;}}}} -------------------------------------------------- ------------------------------ ConnectionParam.java Package scut.aiLab.connectionpool; Import java.io.serializable; / ** * @Author YouYongming * Implement the parameter class for database connections * / Public Class ConnectionParam IMPLEments Serializable {Private string driver; // Database driver Private string url; // data connection URL Private string user; // Database Username Private string password; // Database password / ** * Unique constructor, you need to specify four necessary parameters * @Param Driver Data Drive * @Param URL Database Connection URL * @Param User User Name * @Param Password password * / Public ConnectionParam (String Driver, String Url, String User, String Password) {This.driver = driver; this.url = url; this.user = user; this.password = password;} Public string getDriver () {returnid;} 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 (String user) {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.comParetoIgnore (param.geturl ()) == 0) && ()) == 0) && () get (Password.comPareToIgnore ") == 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 * * / // Connect 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) { Try { Thread.sleep (delay); } Catch (interruptedexception e) {} System.out.println ("eeeee"); / / Judgment whether the factory has closed, then you will exit the monitor IF (cf.iscreate ()) Cf.schedule (); Else System.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 * * /// Connect pool plant parameters Public Class FactoryParam { // maximum connection number Private int maxConnectionCount = 4; // minimum connection number Private int minConnectioncount = 2; // Recycling strategy Private Int ManageType = 0; Public factoryparam () {} / ** * Structure of the object to connect the pool plant parameters * @Param Max maximum connection * @Param min minimum connection number * @Param Type management strategy * / Public FactoryParam (int Max, int min, int type) { THIS.ManageType = Type; this.maxConnectioncount = max; THIS.MINCONNECNT = min;} / ** * Set the maximum number of connections * @Param Value * / Public void setMaxConn (int value) { THIS.MAXCONNECNT = Value;} / ** * Get the maximum number of connections * @Return * / Public int getMaxconn () {Return this.maxConnectioncount; / ** * Set the minimum number of connections * @Param Value * / Public void setminconn (int value) {This.minConnectioncount = value;} / ** * Get minimum connections * @Return * / Public int getminConn () { Return this.minConnectionCount; } Public int GETTYPE () {Return this.manageType; } -------------------------------------------------- ---------------------------- 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 TestmyPool { Public void 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 (exception e) { E.PrintStackTrace (); }}} 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 ConnectionParam (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.createstatement (); ResultSet RS = Stmt.executeQuery ("SELECT * from Requests"); if (rs.next ()) {System.out.println ("conn1 y"); Else {System.out.println ("conn1 n");} CONN1.CLOSE (); System.out.println ("pool:" (System.currentTimeMillis () - TIME)); Time = system.currenttimemillis (); Class.Forname (param.getdriver ()). Newinstance (); For (int i = 0; i <10; i ) { Conn1 = drivermanager.getConnection (param.getUr (), param.getuser (), param.getpassword (); 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"); } Conn1.close (); } System.out.println ("NO POOL:" (System.currentTimeMillis () - TIME)); } Catch (Exception E) {E.PrintStackTrace (); Finally { Try { Cf.close (); } Catch (Exception E) { E.PrintStackTrace (); } } } }