源代码: /* * @Title 连接池 * @Author: zxg * @Version 1.0 * @Memo:定义数据库连接及其数据库连接池等 */ package com.drsl.db; import Java.io.*; import java.sql.*; import java.util.*; import java.util.Date; import java.lang.reflect.*; import com.mysql.jdbc.Driver; import com.drsl.db.*; public class ConnectionManager { static private ConnectionManager instance; // 唯一实例 static private int clients; static private int maxonlinetime=30*60*1000; private Vector drivers = new Vector(); private Hashtable pools = new Hashtable(); private Timer checkConnTimer=new Timer(); static private PrintWriter log; /** * 返回唯一实例.假如是第一次调用此方法,则创建实例 * * @return ConnectionManager 唯一实例 */ static synchronized public ConnectionManager getInstance() { if (instance == null) { instance = new ConnectionManager(); } // clients++; return instance; } /** * 建构函数私有以防止其它对象创建本类实例 */ private ConnectionManager() { init(); } /** * 读取属性完成初始化 */ private void init() { try { InputStream is = getClass().getResourceAsStream("db.properties"); Properties dbProps = new Properties(); dbProps.load(is); } catch (Exception e) { e.printStackTrace(); System.err.println("不能读取属性文件= " + "请确保db.properties在CLASSPATH指定的路径中"); return; } String logFile = dbProps.getProperty("logfile", "log.txt"); try { log = new PrintWriter(new FileWriter(logFile, true), true); } catch (IOException e) { System.err.println("无法打开日志文件: " + logFile); log = new PrintWriter(System.err); } loadDrivers(dbProps); createPools(dbProps); } /** * 装载和注册所有JDBC驱动程序 * * @param props 属性 */ private void loadDrivers(Properties props) { String driverClasses = props.getProperty("drivers"); StringTokenizer st = new StringTokenizer(driverClasses); while (st.hasMoreElements()) { String driverClassName = st.nextToken().trim(); try { Driver driver = (Driver)Class.forName(driverClassName).newInstance(); if(driver!=null){ DriverManager.registerDriver(driver); drivers.addElement(driver); log("Begin"); log("成功注册JDBC驱动程序" + driverClassName); } else{ log("Begin"); log("注册JDBC驱动程序" + driverClassName+"失败"); } } catch (Exception e) { log("Begin"); log("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " + e); } } } /** * 根据指定属性创建连接池实例. * * @param props 连接池属性 */ private void createPools(Properties props) { Enumeration propNames = props.propertyNames(); while (propNames.hasMoreElements()) { String name = (String) propNames.nextElement(); if (name.endsWith(".url")) { String poolName = name.substring(0, name.lastIndexOf(".")); String url = props.getProperty(poolName + ".url"); if (url == null) { log("没有为连接池" + poolName + "指定URL"); continue; } String user = props.getProperty(poolName + ".user"); String passWord = props.getProperty(poolName + ".password"); String maxconn = props.getProperty(poolName + ".maxconn", "0"); String minconn = props.getProperty(poolName + ".minconn", "10"); String option=props.getProperty(poolName+".option",""); int max,min; try { max = Integer.valueOf(maxconn).intValue(); } catch (NumberFormatException e) { log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName); max = 0; } try { min = Integer.valueOf(minconn).intValue(); } catch (NumberFormatException e) { log("错误的最小连接数限制: " + minconn + " .连接池: " + poolName); min = 0; } try{ ConnectionPool pool = new ConnectionPool(poolName, url,user,password,min,max,option); pools.put(poolName, pool); //2秒钟后开始每个一分钟检查一次连接池情况 checkConnTimer.schedule(pool,2000,60*1000); log("成功创建连接池" + poolName); }catch(Exception e){ log(e,"创建DBConnectionPool出错"); } } } } /** * 将连接对象返回给由名字指定的连接池 * * @param name 在属性文件中定义的连接池名字 * @param con 连接对象 */ public void freeConnection(String name, Connection conn) { ConnectionPool pool = (ConnectionPool) pools.get(name); if (pool != null) { pool.freeConnection(conn); } } /** * 获得一个可用的(空闲的)连接.假如没有可用连接,且已有连接数小于最大连接数 * 限制,则创建并返回新连接 * * @param name 在属性文件中定义的连接池名字 * @return Connection 可用连接或null */ public Connection getConnection(String name) { ConnectionPool pool = (ConnectionPool) pools.get(name); if (pool != null) { return pool.getConnection(); } return null; } /** * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接. * * @param name 连接池名字 * @param time 以毫秒计的等待时间 * @return Connection 可用连接或null */ public Connection getConnection(String name, long time) { ConnectionPool pool = (Con
|