`
mabusyao
  • 浏览: 252663 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

数据库连接池

阅读更多
感谢网络提供资源的朋友,自己做了个版本,正在测试,看看是否有问题。

2009-09-08 更新成单例模式
/*
 * $DatabaseInfo.java 2009-01-20 By Bill Yao $
 */

package shopping.servlet.db;

import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

/**
 * DatabaseInfo class provided the basic information for DB connection.
 * 
 * @author yaoh
 *
 */
public abstract class DatabaseInfo {
	
	private static ResourceBundle bundle = PropertyResourceBundle.getBundle("shopping");

    protected static final String url = bundle.getString("DB_URL");

    protected static final String username = bundle.getString("DB_USERNAME");

    protected static final String password = bundle.getString("DB_PASSWORD");

    protected static final String driverClass = bundle.getString("DB_DRIVER");
    
    protected static final int INIT_CONNECTION = Integer.valueOf(bundle.getString("INIT_CONNECTION"));
    
    protected static final int ADD_CONNECTION = Integer.valueOf(bundle.getString("ADD_CONNECTION"));

    protected static final int MAX_CONNECTION = Integer.valueOf(bundle.getString("MAX_CONNECTION"));
}



package shopping.servlet.db;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Vector;

import org.apache.log4j.Logger;

/**
 * ConnectionPool provide database connections by pool.
 * 
 * @author yaoh
 *
 */
public final class ConnectionPool extends DatabaseInfo{
    static Logger logger = Logger.getLogger(ConnectionPool.class);
    
    // The connection pool.
    private Vector<PooledConnection> connections = null;
    
    // Table used to test connection.
    private String testTable = "TEST";
    
    //Singleton pattern.
    private static final ConnectionPool pool = new ConnectionPool();
    
    /**
     * Constructor
     */
	private ConnectionPool() {
		try {
			createPool();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static ConnectionPool getInstance() {
		return pool;
	}
	
	/**
	 * Create the connection pool.
	 * 
	 */
	private synchronized void createPool() throws SQLException, ClassNotFoundException {
		if (connections != null) return;

		Class.forName(driverClass);

		connections = new Vector<PooledConnection>();
		createConnections(INIT_CONNECTION);
		logger.info("Create connection pool successfully.");
	}

	/**
	 * Create number of connections, add into connection pool.
	 * @param num, number of connections.
	 */
	private void createConnections(int num) throws SQLException {
		for (int x = 0; x < num; x++) {
			if (MAX_CONNECTION > 0 && connections.size() >= MAX_CONNECTION) break;

			//add a new PooledConnection object to connections vector
			try {
				connections.addElement(new PooledConnection(newConnection()));
			} catch (SQLException e) {
				logger.error(" Create database connection failed. " + e.getMessage());
				throw new SQLException();
			}
			logger.info(" Create database connection successfully. ");
		}
	}
	
	/**
	 * Create and return a new database connection.
	 *
	 * @return a new database connection.
	 */
	private Connection newConnection() throws SQLException {

		Connection conn = DriverManager.getConnection(url, username, password);

		if (connections.size() == 0) {
			DatabaseMetaData metaData = conn.getMetaData();
			int driverMaxConnections = metaData.getMaxConnections();
			if (driverMaxConnections > 0 && MAX_CONNECTION > driverMaxConnections) {
				//TODO; update the max connection.
			}
		}
		return conn;
	}
	
	/**
	 * Return a avaliable connection.
	 * Wait a while and retrive again if not free connection and the connection
	 * number is max.
	 * 
	 * @return a avaliable connection.
	 */
	public synchronized Connection getConnection() throws SQLException {
		if (connections == null) return null; 

		Connection conn = getFreeConnection();
		
		while (conn == null) {
			wait(250);
			conn = getFreeConnection();
		}
		return conn;
	}

	/**
	 * Retrive an avaliable connection, create some if no avaliable.
	 * If all unavaliable after creation, return null
	 * @return a free connection.
	 */
	private Connection getFreeConnection() throws SQLException {
		Connection conn = findFreeConnection();
		if (conn == null) {
			createConnections(ADD_CONNECTION);
			conn = findFreeConnection();
			if (conn == null) return null;
		}
		
		return conn;
	}
	
	/**
	 * Find a free connection,
	 * if no free connection, return null.
	 *
	 * @return a free connection
	 */
	private Connection findFreeConnection() throws SQLException {
		Connection conn = null;
		PooledConnection pConn = null;

		Enumeration<PooledConnection> enumerate = connections.elements();
		while (enumerate.hasMoreElements()) {
			pConn = enumerate.nextElement();
			
			if (!pConn.isBusy()) {
				conn = pConn.getConnection();
				pConn.setBusy(true);
				if (!testConnection(conn)) {
					try {
						conn = newConnection();
					} catch (SQLException e) {
						logger.error("Create database connection failed." + e.getMessage());
						return null;
					}
					pConn.setConnection(conn);
				}
				break;
			}
		}

		return conn;
	}

	/**
	 * Testing if a connection works, if not, close it and return false.
	 * else return true.
	 *
	 * @param conn connection need to test.
	 * @return true if connection works.
	 */
	private boolean testConnection(Connection conn) {
		try {
			if (testTable.equals("")) {
				conn.setAutoCommit(true);

			} else {
				Statement stmt = conn.createStatement();
				stmt.execute("select count(*) from " + testTable);
				
				stmt.close();
			}
		} catch (SQLException e) {
			closeConnection(conn);
			return false;
		}

		return true;

	}
	
	/**
	 * Return a connection to pool, set it free。
	 *
	 * @param free connection.
	 */
	public void returnConnection(Connection conn) {
		if (connections == null) {
			logger.warn("Connection pool does not exist, could not return connection.");
			return;
		}

		PooledConnection pConn = null;

		Enumeration<PooledConnection> enumerate = connections.elements();
		while (enumerate.hasMoreElements()) {
			pConn = (PooledConnection) enumerate.nextElement();
			if (conn == pConn.getConnection()) {
				pConn.setBusy(false);
				conn = null;
				break;
			}
		}
	}
	
	/**
	 * Refresh all connections in the pool.
	 *
	 */
	public synchronized void refreshConnections() throws SQLException {
		if (connections == null) {
			logger.warn("Connection pool does not exist, could not refresh connection.");
			return;
		}

		PooledConnection pConn = null;

		Enumeration<PooledConnection> enumerate = connections.elements();
		while (enumerate.hasMoreElements()) {
			pConn = (PooledConnection) enumerate.nextElement();
			if (pConn.isBusy()) {
				wait(5000);
			}
			
			closeConnection(pConn.getConnection());
			pConn.setConnection(newConnection());
			pConn.setBusy(false);
		}
	}
	
	/**
	 * Close all connection and clear pool.
	 */

	public synchronized void closeConnectionPool() throws SQLException {
		if (connections == null) {
			logger.warn("Connection pool does not exist, cound not close.");
			return;
		}

		PooledConnection pConn = null;

		Enumeration<PooledConnection> enumerate = connections.elements();
		while (enumerate.hasMoreElements()) {
			pConn = (PooledConnection) enumerate.nextElement();
			if (pConn.isBusy()) {
				wait(5000);
			}
			closeConnection(pConn.getConnection());
			connections.removeElement(pConn);
		}
		connections = null;
	}

	/**
	 * Close a connection.
	 *
	 * @param the connection need to be closed.
	 */

	private void closeConnection(Connection conn) {
		try {
			conn.close();
		} catch (SQLException e) {
			logger.error("Close connection failed:" + e.getMessage());
		}
	}

	/**
	 * Let proccess wait.
	 *
	 * @param ms time.
	 */
	private void wait(int mSeconds) {
		try {
			Thread.sleep(mSeconds);
		} catch (InterruptedException e) {
		}
	}

	/**
	 * Inner class for saving database connection.
	 * Field connection
	 * Filed busy
	 */
	class PooledConnection {

		Connection connection = null;// database connection.

		boolean busy = false; // if this connection is in using, default is used.

		public PooledConnection(Connection connection) {
			this.connection = connection;
		}

		// Return the connection.
		public Connection getConnection() {
			return connection;
		}

		// Set the connection.
		public void setConnection(Connection connection) {
			this.connection = connection;
		}

		// Return if connection is busy.
		public boolean isBusy() {
			return busy;
		}

		// Set the connection is busy.
		public void setBusy(boolean busy) {
			this.busy = busy;
		}
	}
}
分享到:
评论

相关推荐

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

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

    数据库连接池技术详解

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

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

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

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

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

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

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

    c# mysql数据库连接池实现

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

    Java jdbc数据库连接池总结

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

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

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

    MySql数据库连接池C#代码(有注释含测试代码)

    MySQL数据库连接池是提高应用程序性能的一种重要技术,它允许开发者管理多个数据库连接并高效地复用这些连接,而不是每次需要时都创建新的连接。在C#编程中,我们可以使用自定义的连接池或者第三方库如ADO.NET的...

    数据库连接池java代码实现

    数据库连接池在Java中的实现是提高应用程序性能的关键技术之一,它通过复用已存在的数据库连接,避免了频繁创建和销毁连接导致的系统资源浪费。本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释...

    几种数据库连接池详细配置

    在IT领域,数据库连接池是优化数据库访问性能的关键技术之一,尤其在高并发的应用场景下,合理配置数据库连接池能够显著提升系统响应速度并降低资源消耗。本文将深入解析几种常用的数据库连接池——Apache DBCP、C3P...

    C# 数据库连接池

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

    数据库连接池c3p0jar包

    数据库连接池是Java开发中非常重要的一个组件,它在处理多线程环境下对数据库资源的高效利用和管理中起着关键作用。C3P0是一个开源的Java连接池实现,它提供了一种灵活且功能强大的数据库连接管理方式。在本文中,...

    数据库连接池jar包.zip

    数据库连接池是现代Java应用程序中不可或缺的组件,它在提高数据库操作效率和资源管理方面扮演着重要角色。Druid是一个高效、强大且功能丰富的数据库连接池实现,由阿里巴巴开源并维护。标题提到的"数据库连接池jar...

    delphi数据库连接池

    Delphi数据库连接池是一种高效的数据库资源管理技术,它允许应用程序在多用户环境下共享数据库连接,以提高性能并减少系统资源的消耗。连接池的核心思想是重用已建立的数据库连接,而不是每次需要时都创建新的连接,...

    数据库连接池配置文件

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

    配置数据库连接池

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

    JAVA 使用数据库连接池连接Oracle数据库全代码

    ### JAVA 使用数据库连接池连接Oracle数据库全代码解析 #### 一、概述 本文将详细介绍如何在Java项目中使用Apache DBCP(Database Connection Pool)来连接Oracle数据库,并提供完整的示例代码。通过这种方式,我们...

Global site tag (gtag.js) - Google Analytics