`

数据库连接池

阅读更多

连接工厂 ConnectionFactory

 

 

package myConnPool;

import java.util.LinkedHashSet;
import java.sql.*;
import java.util.Iterator;

public class ConnectionFactory {
	private static ConnectionFactory connFactory = null;
	private LinkedHashSet connPool = null;// 在使用的连接池
	private LinkedHashSet freeConnPool = null;// 空闲连接池
	private int maxConnCount = 4;//最大连接数
	private int minConnCount = 2;	// 最小连接数
	private int current_conn_count = 0;// 当前连接数
	private boolean isflag = false;// 是否创建工厂的标志
	private ConnectionFactory(){}
	public ConnectionFactory(ConnectionParam param) throws SQLException {
		if (connFactory == null) {
			synchronized (ConnectionFactory.class) {
				if (connFactory == null) {
					connFactory=new ConnectionFactory();
					connFactory.connPool = new LinkedHashSet();
					connFactory.freeConnPool = new LinkedHashSet();
					connFactory.maxConnCount = param.getMaxConn();
					connFactory.minConnCount = param.getMinConn();
					connFactory.isflag = true;
					try {// 初始化,创建minConnCount个连接
						for (int i = 0; i < connFactory.minConnCount; i++) {
							_Connection _conn = _Connection
									.getConnection(connFactory);
							connFactory.freeConnPool.add(_conn);// 加入空闲连接池
							connFactory.current_conn_count++;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	// 标志工厂是否已经创建
	public boolean isCreate() {
		return connFactory.isflag;
	}
	
	/* 从连接池中取一个空闲的连接
	 * 	先遍历空闲连接池,看看是否有空闲连接
	 * 	如果能得到连接,得到连接后,从空闲连接池移除该链接,然后加入到当前连接池
	 * 判断连空闲连接池是否为空
	 *	如果空闲连接池为空,并且当前连接还没达到最大连接数,则创建新的连接,加入空闲连接池
	 *	然后检查当前连接池,把不再使用的连接归还给空闲连接池 
	 * 最后判断到底有没有得到连接
	 * 	如果没有得到连接,则再次遍历空闲连接池
	 */
	public synchronized Connection getFreeConnection() throws SQLException {
		Connection conn = null;
		Iterator iter = connFactory.freeConnPool.iterator();// 获取空闲连接
		while (iter.hasNext()) {
			_Connection _conn = (_Connection) iter.next();
			if (!_conn.isFree()) {// 找到未用连接
				conn = _conn.getFreeConnection();
				_conn.setIsFree(true);
				connFactory.freeConnPool.remove(_conn);// 移出空闲区
				connFactory.connPool.add(_conn);// 加入连接池
				break;
			}
		}
		// 检查空闲池是否为空
		if (connFactory.freeConnPool.isEmpty()) {
			// 再检查是否能够分配
			if (connFactory.current_conn_count < connFactory.maxConnCount) {
				int newcount = 0;
				// 取得要建立的数目
				if (connFactory.maxConnCount - connFactory.current_conn_count >= connFactory.minConnCount) {
					newcount = connFactory.minConnCount;
				} else {
					newcount = connFactory.maxConnCount
							- connFactory.current_conn_count;
				}
				for (int i = 0; i < newcount; i++) {// 创建连接
					_Connection _conn = _Connection.getConnection(connFactory);
					connFactory.freeConnPool.add(_conn);
					connFactory.current_conn_count++;
				}
			} else {// 如果不能新建,检查是否有已经归还的连接
				iter = connFactory.connPool.iterator();
				while (iter.hasNext()) {
					_Connection _conn = (_Connection) iter.next();
					if (!_conn.isFree()) {
						conn = _conn.getFreeConnection();
						_conn.setIsFree(false);
						connFactory.connPool.remove(_conn);
						connFactory.freeConnPool.add(_conn);
						break;
					}
				}
			}
		}
		// 再次检查是否能分配连接
		if (conn == null) {
			iter = connFactory.freeConnPool.iterator();
			while (iter.hasNext()) {
				_Connection _conn = (_Connection) iter.next();
				if (!_conn.isFree()) {
					conn = _conn.getFreeConnection();
					_conn.setIsFree(true);
					connFactory.freeConnPool.remove(_conn);
					connFactory.connPool.add(_conn);
					break;
				}
			}
			if (conn == null)// 如果不能则说明无连接可用
				throw new SQLException("没有可用的数据库连接");
		}
		System.out.println("get connection");
		return conn;
	}
	// 关闭该连接池中的所有数据库连接
	public synchronized void close() throws SQLException {
		this.isflag = false;
		SQLException excp = null;
		// 关闭空闲池
		Iterator iter = connFactory.freeConnPool.iterator();
		while (iter.hasNext()) {
			try {
				((_Connection) iter.next()).close();
				System.out.println("close connection:free");
				connFactory.current_conn_count--;
			} catch (Exception e) {
				if (e instanceof SQLException)
					excp = (SQLException) e;
			}
		}
		// 关闭在使用的连接池
		iter = connFactory.connPool.iterator();
		while (iter.hasNext()) {
			try {
				((_Connection) iter.next()).close();
				System.out.println("close connection:inused");
				connFactory.current_conn_count--;
			} catch (Exception e) {
				if (e instanceof SQLException)
					excp = (SQLException) e;
			}
		}
		if (excp != null)
			throw excp;
	}
}

 

数据连接代理类_Connection

 

package myConnPool;

import java.lang.reflect.*;
import java.sql.*;
//定义数据库连接的代理类
public class _Connection implements InvocationHandler {
	private Connection conn = null;// 定义连接
	private Statement statRef = null;// 定义监控连接创建的语句
	private PreparedStatement prestatRef = null;
	private boolean isFree = false;// 数据库的忙状态
	long lastAccessTime = 0;// 最后一次访问时间
	// 定义要接管的函数的名字
	String CREATESTATE = "createStatement";
	String CLOSE = "close";
	String PREPARESTATEMENT = "prepareStatement";
	private _Connection() {
		try {// 创建连接
			Class.forName(ConnectionParam.getInstance().getDriver())
					.newInstance();
			conn = DriverManager.getConnection(ConnectionParam.getInstance()
					.getUrl(), ConnectionParam.getInstance().getUser(),
					ConnectionParam.getInstance().getPassword());
			DatabaseMetaData dm = null;
			dm = conn.getMetaData();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object obj = null;
		// 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
		if (CLOSE.equals(method.getName())) {
			// 设置不使用标志
			setIsFree(false);
			// 检查是否有后续工作,清除该连接无用资源
			if (statRef != null)
				statRef.close();
			if (prestatRef != null)
				prestatRef.close();
			return null;
		}
		// 判断是使用了createStatement语句
		if (CREATESTATE.equals(method.getName())) {
			obj = method.invoke(conn, args);
			statRef = (Statement) obj;// 记录语句
			return obj;
		}
		// 判断是使用了prepareStatement语句
		if (PREPARESTATEMENT.equals(method.getName())) {
			obj = method.invoke(conn, args);
			prestatRef = (PreparedStatement) obj;
			return obj;
		}
		obj = method.invoke(conn, args);
		// 设置最后一次访问时间,以便及时清除超时的连接
		lastAccessTime = System.currentTimeMillis();
		return obj;
	}
	// 创建连接的工厂,只能让工厂调用
	static public _Connection getConnection(ConnectionFactory factory) {
		if (factory.isCreate()) {// 判断是否正确初始化的工厂
			_Connection _conn = new _Connection();
			return _conn;
		} else
			return null;
	}
	public Connection getFreeConnection() {
		// 返回数据库连接conn的接管类,以便截住close方法
		Connection conn2 = (Connection) Proxy.newProxyInstance(conn.getClass()
				.getClassLoader(), conn.getClass().getInterfaces(), this);
		return conn2;
	}

	// 该方法真正的关闭了数据库的连接

	void close() throws SQLException {
		// 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
		conn.close();
	}

	public void setIsFree(boolean value) {
		isFree = value;
	}

	public boolean isFree() {
		return isFree;
	}
}

 

连接参数类 ConnectionParam

 

package myConnPool;

import java.io.Serializable;

public class ConnectionParam implements Serializable {
	private static ConnectionParam connParam=null;
	private String driver; // 数据库驱动程序
	private String url; // 数据连接的URL
	private String user; // 数据库用户名
	private String password; // 数据库密码
	private int MaxConnectionCount = 4;// 最大连接数
	private int MinConnectionCount = 2;// 最小连接数
	private ConnectionParam(){}
	public static ConnectionParam getInstance(){
		if(connParam==null){
			connParam=new ConnectionParam();
		}
		return connParam;
	}
	public String getDriver() {
		return driver;
	}
	public String getPassword() {
		return password;
	}
	public String getUrl() {
		return url;
	}
	public String getUser() {
		return user;
	}
	public int getMaxConn() {
		return this.MaxConnectionCount;
	}
	public int getMinConn() {
		return this.MinConnectionCount;
	}
	public void setDriver(String driver) {
		this.driver = driver;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public void setUser(String user) {
		this.user = user;
	}
	public void setMaxConn(int value) {
		this.MaxConnectionCount = value;
	}
	public void setMinConn(int value) {
		this.MinConnectionCount = value;
	}
}

 

 

测试类

 

package myConnPool;

import java.sql.*;

public class testmypool {
	
	public static void main(String[] args) {
		
		String user = "root";
		String password = "root";
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost/authorization";
		ConnectionParam param = ConnectionParam.getInstance();
		param.setDriver(driver);
		param.setUrl(url);
		param.setUser(user);
		param.setPassword(password);
		param.setMaxConn(4);
		param.setMinConn(2);
		ConnectionFactory cf = null;
		try {
			cf = new ConnectionFactory(param);
			ConnectionFactory cf1 = new ConnectionFactory(param);
			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 function");
				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 function");
				if (rs.next()) {
					System.out.println("conn1 y");
				} 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();
			}
		}
	}
}

 

分享到:
评论

相关推荐

    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