import java.sql.*; import java.lang.reflect.*; import org.omg.CORBA.portable.InvokeHandler; import freemarker.template.utility.ObjectConstructor; /** * 定义数据库连接的代理类 * * @author mark * */ public class ConnectionProxy implements InvocationHandler { // 定义连接 private Connection conn = null; // 定义监控连接创建的语句 private Statement statRef = null; private PreparedStatement preStatRef = null; // 是否支持事务标志 private boolean supportTransaction = false; // 数据库的忙状态 private boolean isFree = false; // 最后一次访问时间 long lastAccessTime = 0; // 定义要接管的函数的名字 String CREATESTATE = "createStatement"; String CLOSE = "close"; String PREPARESTATEMENT = "prepareStatement"; String COMMIT = "commit"; String ROLLBACK = "rollbakc"; /** * 构造函数,采用私有,防止被直接创建 * * @param param * 连接参数 */ private ConnectionProxy(ConnectionParam param) { // 记录日志 try { // 创建连接 Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin: @10.8.1.234:1521:WF4PPDB","PP42", "PP42"); DatabaseMetaData dm = null; dm = conn.getMetaData(); // 判断是否支持事务 supportTransaction = dm.supportsTransactions(); } catch (Exception ex) { ex.printStackTrace(); } } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; // 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态 if (CLOSE.equals(method.getName())) { // 设置不使用标志 setFree(false); if (statRef != null) statRef.close(); if (preStatRef != null) preStatRef.close(); return null; } // 判断是使用了createStatement语句 if (CREATESTATE.equals(method.getName())) { try { obj = method.invoke(conn, args); statRef = (Statement) obj; return obj; } catch (ClassCastException ex) { ex.printStackTrace(); } } // 判断是使用了prepareStatement语句 if (PREPARESTATEMENT.equals(method.getName())) { obj = method.invoke(conn, args); preStatRef = (PreparedStatement) obj; return obj; } // 如果不支持事务,就不执行该事物的代码 if ((COMMIT.equals(method.getName()) || ROLLBACK.equals(method .getName())) && (!isSupportTransaction())) { return null; } obj = method.invoke(conn, args); // 设置最后一次访问时间,以便及时清除超时的连接 lastAccessTime = System.currentTimeMillis(); return obj; } /** * 创建连接的工厂,只能让工厂调用 * * @param factory * 要调用工厂,并且一定被正确初始化 * @param param * 连接参数 * @return 连接 */ public static ConnectionProxy getConnection(ConnectionFactory factory, ConnectionParam param) { // 判断是否正确初始化的工厂 if (factory.isCreate()) { ConnectionProxy _conn = new ConnectionProxy(param); return _conn; } else { return null; } } public Connection getFreeConnection() { // 返回数据库连接conn的接管类,以便截住close方法 Connection cn = (Connection) Proxy.newProxyInstance(conn.getClass() .getClassLoader(), conn.getClass().getInterfaces(), this); return cn; } /** * 该方法真正的关闭了数据库的连接 * * @throws SQLException */ public void close() throws SQLException { // 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接 conn.close(); } public void setFree(boolean isFree) { this.isFree = isFree; } public boolean isFree() { return isFree; } /** * 判断是否支持事务 * * @return boolean */ public boolean isSupportTransaction() { return supportTransaction; } } import java.sql.Connection; import java.sql.SQLException; import java.util.*; public class ConnectionFactory { private static ConnectionFactory m_instance = null; // 在使用的连接池 private LinkedHashSet ConnectionPool = null; // 空闲连接池 private LinkedHashSet FreeConnectionPool = null; // 最大连接数 private int MaxConnectionCount = 10; // 最小连接数S private int MinConnectionCount = 2; // 当前连接数 private int current_conn_count = 0; // 连接参数 private ConnectionParam connparam = null; // 是否创建工厂的标志 private boolean isflag = false; // 是否支持事务 private boolean supportTransaction = false; // 定义管理策略 private int ManageType = 0; /** * 构造器 */ private ConnectionFactory() { ConnectionPool = new LinkedHashSet(); FreeConnectionPool = new LinkedHashSet(); } /** * 使用指定的参数创建一个连接池 * * @throws SQLException */ public ConnectionFactory(ConnectionParam param, FactoryParam fparam) throws SQLException { if ((param == null) || (fparam == null)) throw new SQLException("ConnectionParam和FactoryParam不能为空"); if (m_instance == null) { synchronized (ConnectionFactory.class) { if (m_instance == null) { // 参数定制 m_instance = new ConnectionFactory(); connparam = param; m_instance.MaxConnectionCount = fparam .getMaxConnectionCount(); m_instance.MinConnectionCount = fparam .getMinConnectionCount(); m_instance.ManageType = fparam.getManageType(); m_instance.isflag = true; // 初始化,创建MinConnectionCount个连接 System.out.println("connection factory 创建!"); try { for (int i = 0; i < m_instance.MinConnectionCount; i++) { ConnectionProxy conn = ConnectionProxy .getConnection(m_instance,m_instance.connparam); if (conn == null) continue; System.out.println("connection创建"); m_instance.FreeConnectionPool.add(conn); // 加入空闲连接池 m_instance.current_conn_count++; // 标志是否支持事务 m_instance.supportTransaction = conn .isSupportTransaction(); } } catch (Exception ex) { ex.printStackTrace(); } // 根据策略判断是否需要查询 if (m_instance.ManageType != 0) { Thread t = new Thread(new FactoryManageThread( m_instance)); t.start(); } } } } } /** * 标志工厂是否已经创建 * * @return boolean */ public boolean isCreate() { return m_instance.isflag; } /** * 从连接池中取一个空闲的连接 * * @return Connection * @throws SQLException */ public synchronized Connection getFreeConnection() throws SQLException { Connection cn = null; // 获取空闲连接 Iterator ir = m_instance.FreeConnectionPool.iterator(); while (ir.hasNext()) { ConnectionProxy conn = (ConnectionProxy) ir.next(); // 找到未用的连接 if (!conn.isFree()) { cn = conn.getFreeConnection(); conn.setFree(true); // 移出空闲区 m_instance.FreeConnectionPool.remove(conn); // 加入连接池 m_instance.ConnectionPool.add(conn); break; } } // 检查空闲池是否为空 if (m_instance.FreeConnectionPool.isEmpty()) { // 再检查是否能够分配 if (m_instance.current_conn_count < m_instance.MaxConnectionCount) { // 新建连接到空闲连接池 int newCount = 0; // 取得要建立的数目 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; } // 创建连接 for (int i = 0; i < newCount; i++) { ConnectionProxy _conn = ConnectionProxy.getConnection( m_instance, connparam); m_instance.FreeConnectionPool.add(_conn); m_instance.current_conn_count++; } } else { // 如果不能新建,检查是否有已经归还的连接 ir = m_instance.ConnectionPool.iterator(); while (ir.hasNext()) { ConnectionProxy _conn = (ConnectionProxy) ir.next(); if (!_conn.isFree()) { cn = _conn.getFreeConnection(); _conn.setFree(false); m_instance.ConnectionPool.remove(_conn); m_instance.FreeConnectionPool.add(_conn); break; } } } } // 再次检查是否能分配连接 if (cn == null) { ir = m_instance.FreeConnectionPool.iterator(); while (ir.hasNext()) { ConnectionProxy _conn = (ConnectionProxy) ir.next(); if (!_conn.isFree()) { cn = _conn.getFreeConnection(); _conn.setFree(true); m_instance.FreeConnectionPool.remove(_conn); m_instance.ConnectionPool.add(_conn); break; } } if (cn == null) // 如果不能则说明无连接可用 throw new SQLException("没有可用的数据库连接"); } System.out.println("Get Connection"); return cn; } /** * 关闭该连接池中的所有数据库连接 * * @throws SQLException */ public synchronized void close() throws SQLException { this.isflag = false; SQLException sqlError = null; // 关闭空闲池 Iterator ir = m_instance.FreeConnectionPool.iterator(); while (ir.hasNext()) { try { ((ConnectionProxy) ir.next()).close(); System.out.println("Close connection:Free"); m_instance.current_conn_count--; } catch (Exception ex) { if (ex instanceof SQLException) { sqlError = (SQLException) ex; } } } // 关闭在使用的连接池 ir = m_instance.ConnectionPool.iterator(); while (ir.hasNext()) { try { ((ConnectionProxy) ir.next()).close(); System.out.println("Close connection:Using"); } catch (Exception ex) { if (ex instanceof SQLException) { sqlError = (SQLException) ex; } } } if (sqlError != null) throw sqlError; } /** * 返回是否支持事务 * * @return boolean */ public boolean isSupportTransaction() { return m_instance.supportTransaction; } /** * 连接池调度管理 * */ public void schedule() { Connection cn = null; // 再检查是否能够分配 Iterator ir = null; // 检查是否有已经归还的连接 ir = m_instance.ConnectionPool.iterator(); while (ir.hasNext()) { ConnectionProxy _conn = (ConnectionProxy) ir.next(); if (!_conn.isFree()) { cn = _conn.getFreeConnection(); _conn.setFree(false); m_instance.ConnectionPool.remove(_conn); m_instance.FreeConnectionPool.add(_conn); break; } } if (m_instance.current_conn_count < m_instance.MaxConnectionCount) { // 新建连接到空闲连接池 int newCount = 0; // 取得要建立的数目 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; } // 创建连接 for (int i = 0; i < newCount; i++) { ConnectionProxy _conn = ConnectionProxy.getConnection( m_instance, connparam); m_instance.FreeConnectionPool.add(_conn); m_instance.current_conn_count++; } } } } import java.io.Serializable; import com.mark.human.model.*; /** * 实现数据库连接的参数类 * * @author mark * */ public class ConnectionParam implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String driver; // 数据库驱动程序 private String url; // 数据连接的URL private String user; // 数据库用户名 private String password; // 数据库密码 public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public ConnectionParam(String driver, String url, String user, String password) { this.driver = driver; this.url = url; this.user = user; this.password = password; } /** * @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.compareToIgnoreCase(param.getUser()) == 0) && (password .compareToIgnoreCase(param.getPassword()) == 0)); } return false; } } /** * 连接池调度线程 * * @author mark * */ public class FactoryManageThread implements Runnable { ConnectionFactory cf = null; long delay = 1000; public FactoryManageThread(ConnectionFactory obj) { cf = obj; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { while (true) { try { Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run.....run....."); // 判断是否已经关闭了工厂,那就退出监听 if (cf.isCreate()) cf.schedule(); else System.exit(1); } } } /** * 连接池工厂参数 * * @author mark * */ public class FactoryParam { // 最大连接数 private int MaxConnectionCount = 4; // 最小连接数 private int MinConnectionCount = 2; // 回收策略 private int ManageType = 0; public FactoryParam() { } /** * 构造连接池工厂参数的对象 * * @param max * 最大连接数 * @param min * 最小连接数 * @param type * 管理策略 */ public FactoryParam(int max, int min, int type) { this.MaxConnectionCount = max; this.MinConnectionCount = min; this.ManageType = type; } public int getManageType() { return ManageType; } public void setManageType(int manageType) { ManageType = manageType; } public int getMaxConnectionCount() { return MaxConnectionCount; } public void setMaxConnectionCount(int maxConnectionCount) { MaxConnectionCount = maxConnectionCount; } public int getMinConnectionCount() { return MinConnectionCount; } public void setMinConnectionCount(int minConnectionCount) { MinConnectionCount = minConnectionCount; } } import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class testPool { public void test1() { String user = "ppuser"; String password = "ppuser"; String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA"; String driver = "oracle.jdbc.driver.OracleDriver"; 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 ADMINISTRATION"); 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 ADMINISTRATION"); if (rs.next()) { System.out.println("conn5 y"); } else { System.out.println("conn5 n"); } conn2.close(); conn3.close(); conn4.close(); conn5.close(); } catch (Exception ex) { ex.printStackTrace(); } finally { try { cf.close(); } catch (Exception ex) { ex.printStackTrace(); } } } /** * @param args */ public static void main(String[] args) { String user = "ppuser"; String password = "ppuser"; String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA"; String driver = "oracle.jdbc.driver.OracleDriver"; ConnectionParam param = new ConnectionParam(driver, url, user, password); System.out.println("-------" + param.getDriver()); ConnectionFactory cf = null; try { cf = 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 actioncode"); 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.getUrl(), param .getUser(), param.getPassword()); Statement stmt = conn1.createStatement(); ResultSet rs = stmt.executeQuery("select * from actioncode"); if (rs.next()) { System.out.println("conn1 y"); System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); } 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(); } } } }