`
citybuster_one
  • 浏览: 20677 次
  • 性别: 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 来括起来,同时将代码格式化,带有缩进,这样呢,大家看起来就不晕船哈~~~

相关推荐

    基于C++11和Linux环境的自写数据库连接池源码+项目说明.zip

    【项目介绍】基于C++11和Linux环境的自写数据库连接池源码+项目说明.zip关键技术要点- MySQL数据库编程- 设计模式中的单例模式- STL中的queue队列容器- C++11多线程编程- C++11线程互斥、线程同步通信和unique_lock-...

    自己写的数据库连接池(java)

    在给定的标题“自己写的数据库连接池(java)”中,我们可以推测这是一个用户自定义的数据库连接池实现,可能是为了学习或实践目的。描述提到的“XML版读取属性文件”和“普通的”,暗示了两种不同的配置方式,一种是...

    基于C++11和Linux环境的自写数据库连接池项目源码+文档说明.zip

    基于C++11和Linux环境的自写数据库连接池项目源码+文档说明.zip 【说明】 【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 ...

    java手写数据库连接池

    数据库连接池是Java应用程序中非常重要的一个组件,它在提高应用性能、节省系统资源方面起着关键作用。本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及...

    数据库连接池技术详解

    对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。 在较为完备的数据库连接池实现中,可根据...

    C#高效数据库连接池源码

    数据库连接池是数据库管理中的重要概念,特别是在高并发和大数据量的应用场景下,它能显著提升性能并降低系统资源消耗。在C#编程环境中,我们可以使用自定义的数据库连接池来实现这一功能。本篇文章将深入探讨“C#...

    C# 数据库连接池 C# 数据库连接池

    数据库连接池是数据库管理中的一个重要概念,它在C#编程中扮演着优化数据库操作的关键角色。C#数据库连接池是一种管理数据库连接的技术,通过复用已存在的连接而不是每次请求时都创建新的连接,从而提高数据库操作的...

    java写的数据库连接池

    数据库连接池是Java开发中非常重要的一个概念,它在处理大量并发访问数据库的应用场景中扮演着关键角色。本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池...

    自己写的数据库连接池

    数据库连接池是应用程序管理数据库连接的一种机制,它在多个并发请求之间共享数据库连接,从而减少了创建和销毁数据库连接的开销。在这个项目中,你使用Java实现了一个自定义的数据库连接池,应用了代理模式来优化...

    03-数据库连接池驱动_数据库连接池;驱动_

    数据库连接池是现代应用程序开发中的重要组成部分,尤其是在处理大量数据交互的应用中,它极大地提高了数据库操作的效率和系统的稳定性。本资源"03-数据库连接池驱动"包含了三种常用的数据库连接池驱动:C3P0、Druid...

    c# mysql数据库连接池实现

    本文将深入探讨如何在C#中使用MySQL数据库连接池。 首先,我们需要了解什么是数据库连接池。数据库连接池是一种资源管理技术,它预先创建并维护一定数量的数据库连接,当应用需要时,可以从池中获取连接,使用完毕...

    Java jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...

    常用jdbc数据库连接jar包,数据库连接池jar包

    本资源集合了常用的JDBC数据库连接jar包,以及一些知名的数据库连接池实现,如dbcp和c3p0,这对于开发人员来说是非常宝贵的资源。 首先,让我们了解一下JDBC。JDBC提供了一套标准的API,包括接口和类,使得开发者...

    Qt 多线程连接数据库——数据库连接池

    * 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...

    数据库连接池配置文件

    context.xml, 数据库连接池配置文

    C# 数据库连接池

    数据库连接池是数据库管理系统中的一个重要概念,主要用于优化数据库的连接操作。在C#编程中,数据库连接池可以高效地管理数据库连接,避免频繁创建和销毁连接导致的性能开销。本文将详细介绍C#中数据库连接池的工作...

    配置数据库连接池

    数据库连接池是现代应用程序中管理数据库连接的一种高效方式,它能显著提高系统性能,减少资源消耗。在给定的标题“配置数据库连接池”中,我们可以深入探讨数据库连接池的概念、工作原理,以及如何配置Oracle9i和...

Global site tag (gtag.js) - Google Analytics