`
citybuster_one
  • 浏览: 20052 次
  • 性别: Icon_minigender_2
  • 来自: Mars
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

自写数据库连接池

阅读更多
  前段时间因为不小心删掉了这篇文章,经高人指点,决定再次粘上来。也由衷地感谢这位高人。企业项目中的数据库连接池都是已经写好,程序员直接拿来用就可以了。自己写一下算是了解一下底层的东西吧!写得不好的地方,希望大家多多指教!

public class DbConnectionManager {
	private static DbConnectionManager dbConnectionManager= null;
	private static int clientCount = 0;
	private static Vector<Driver> drivers = new Vector<Driver>();//存放数据库驱动
	//pools存放数据库连接池
	private static Hashtable<String,DbConnectionPool> pools = new Hashtable<String,DbConnectionPool>();
	private PrintWriter log = null;
	
	private DbConnectionManager(){
		init();
	}
	/**
	 * 〈得到DbConnectionManager实例<单例模式>〉
	 */
	public static synchronized DbConnectionManager getInstance(){
		if(null == dbConnectionManager){
			dbConnectionManager = new DbConnectionManager();
		}
		clientCount++;
		return dbConnectionManager;
	}
	/**
	 * 〈获取连接〉
	 */
	public synchronized Connection getConnection(String name){
		DbConnectionPool dbConnectionPool = pools.get(name);
		Connection connection = null;
		if(null != dbConnectionPool){
			connection = dbConnectionPool.getConnection();
		}
		return connection;
	}
	/** 
	 * 〈释放连接〉
	 */
	public void freeConnection(String name,Connection connection){
		DbConnectionPool dbConnectionPool = pools.get(name);
		if(null != dbConnectionPool){
			dbConnectionPool.freeConnection(connection);
		}
	}
	/** 
	 * 〈加载数据库属性文件〉
	 */
	private void init(){
		InputStream inputStream = this.getClass().getResourceAsStream("/db.properties");
		Properties properties = new Properties();
		try {
			properties.load(inputStream);
		} catch (IOException e) {
		    System.err.println("Can't read the properties file. " + "Make sure db.properties is in the CLASSPATH");
		    return;
		}
		String logFile = properties.getProperty("logfile", "DBConnectionManager.log");
		try {
			log = new PrintWriter(new FileWriter(logFile, true), true);
		} catch (IOException e) {
			System.err.println("Can't open the log file: " + logFile);
		    log = new PrintWriter(System.err);
		}
		loadDrivers(properties);//加载驱动
		createPool(properties);//创建数据库连接池
	}
	/**
	 * 〈创建连接池〉
	 */
	
	private void createPool(Properties properties) {
		Enumeration propertyNames = properties.propertyNames();
		String propertyName = null;
		while(propertyNames.hasMoreElements()){
			propertyName = (String) propertyNames.nextElement();
			if(propertyName.endsWith("url")){
				String poolName = propertyName.substring(0, propertyName.lastIndexOf("."));
				String url = properties.getProperty(propertyName);
				String userName = properties.getProperty(poolName+".userName");
				String password = properties.getProperty(poolName+".password");
				String maxConn = properties.getProperty(poolName+".maxConn");
				int max = 0;
				try{
					max = Integer.parseInt(maxConn);
				}catch(NumberFormatException e){
					max = 0;
				}
				DbConnectionPool dbConnectionPool = new DbConnectionPool(
				poolName,url,userName,password,max);
				pools.put(poolName, dbConnectionPool);
				
			}
		}
	}
	/**
	 * 〈释放连接池〉
	 */
	public void freePools(){
		if(0 == --clientCount){
			Enumeration<DbConnectionPool> allPools = pools.elements();
			DbConnectionPool dbConnectionPool = null;
			while(allPools.hasMoreElements()){
				dbConnectionPool = allPools.nextElement();
				dbConnectionPool.freeConnections();
			}
			Enumeration<Driver> allDrivers = drivers.elements();
		    while (allDrivers.hasMoreElements()) {
			    Driver driver = (Driver) allDrivers.nextElement();
			    try {
				    DriverManager.deregisterDriver(driver);				
			    } catch (SQLException e) {			    	
			    }
		   }
		}
	}
	/**
	 * 〈加载驱动〉
	 */
	private void loadDrivers(Properties properties){
		String  driverClass = properties.getProperty("drivers"); 
		Driver driver = null;
		try {
			driver = (Driver) Class.forName(driverClass).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		drivers.addElement(driver);
	}
	
	
	private class DbConnectionPool{
		private String poolName;
		private String url;
		private String userName;
		private String password;
		private int maxConn;
		private final Vector<Connection> freeConnections = new Vector<Connection>();
		private int checkedOut;
		public DbConnectionPool(String poolName,String url,String userName,String password,int maxConn){
			this.poolName = poolName;
			this.url = url;
			this.userName = userName;
			this.password = password;
			this.maxConn = maxConn;
		}
		/**
		 * 〈获取连接〉
		 */
		public Connection getConnection() {
			Connection connection = null;
			if(freeConnections.size()>0){
				connection = freeConnections.firstElement();
				freeConnections.remove(0);
				 try {
		              if (connection.isClosed()) {		            
		            	  connection = getConnection();
		              }
		         } catch (SQLException e) {	       
		            connection = getConnection();
		         }
			}else if((0 == maxConn)|| checkedOut < maxConn){
				connection = newConnection();
			}
			if(null != connection){
				checkedOut++;
			}
			return connection;
		}
		/**
		 * 〈释放单个连接〉
		 */
		public void freeConnection(Connection connection) {
			freeConnections.addElement(connection);
			checkedOut--;
			notifyAll();
		}
		/**
		 * 〈创建连接〉
		 */
		public Connection newConnection() {
			Connection connection = null;
			try {
				if(null == userName){
					DriverManager.getConnection(url);
				}else {
					connection = DriverManager.getConnection(url, userName, password);
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return connection;
		}
		/**
		 * 〈释放所有连接〉
		 */
		public void freeConnections() {
			Enumeration<Connection> connections = freeConnections.elements();
			Connection connection = null;
			while(connections.hasMoreElements()){
				connection = connections.nextElement();
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			freeConnections.removeAllElements();
		}
	}
}
分享到:
评论
4 楼 citybuster_one 2010-09-27  
yangguo 写道
你把驱动存起来有什么用。

先把驱动存起来,等到用完之后再删除驱动!
3 楼 yangguo 2010-09-16  
你把驱动存起来有什么用。
2 楼 citybuster_one 2010-09-14  

    呵呵!很好!多谢啦!对于代码的格式化,以后我会注意的。多谢指教!
1 楼 zachary.guo 2010-09-14  
java api 提供了 javax.sql.DataSource 接口,有 getConnection() 方法,你可以是实现这个接口,并实现 getConnection() 方法。

apache 的 dbcp 连接池,就是实现了此接口:public class org.apache.commons.dbcp.BasicDataSource implements javax.sql.DataSource

对于调用者,你其实不知道 getConnection() 是每次申请一个新的连接还是用的已存在的连接。这依赖于你对 DataSource 接口的实现。

同时,spring 也提供了很多 DataSource 的实现。

另外提一个建议,你写的代码实例,最好用 BBCode 的 code 来括起来,同时将代码格式化,带有缩进,这样呢,大家看起来就不晕船哈~~~

相关推荐

Global site tag (gtag.js) - Google Analytics