`
kevin_wanwei
  • 浏览: 117609 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

WEB应用中常用的数据库连接池

阅读更多

数据库连接池是WEB应用中必不可少的东西,这是我个人最近参照别人代码写的自己的数据库连接池。

package com.bpcrm.kevin.util.DB_utill.connection_pool;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Vector;
/**
 * 连接池对象
 * @author kevin.wangwei
 * 2009-11-17
 */
public class ConnectionPool {
	/**驱动名称*/
	private String jdbcDriver;
	/**驱动url*/
	private String url;
	/**用户名称*/
	private String userName;
	/**用户密码*/
	private String password;
	/**初始化连接数*/
	private int initConnections=10;
	/**连接池自动增长连接数、默认为:5*/
	private int increamentConnections=5;
	/**连接池最大连接数*/
	private int maxConnections=50;
	/**存放连接对象的数组*/
	private Vector connections=null;
	/**测试用表*/
	private String testTable;
	/**
	 * 默认构造函数
	 * 将默认构造函数设为私有
	 * 防止在无用户名和密码的情况下创建连接池对象 
	 */
	private ConnectionPool(){};
	/**
	 * 自定义构造函数
	 * @param jdbcDriver 驱动名
	 * @param url 数据库URL
	 * @param userName 用户名
	 * @param password 密码
	 */
	public ConnectionPool(String jdbcDriver,String url,String userName,String password){
		this.jdbcDriver=jdbcDriver;
		this.url=url;
		this.userName=userName;
		this.password=password;
	}
	/**
	 * 设置测试表名称
	 * @param testTable 测试表名称
	 */
	public void setTestTable(String testTable) {
		this.testTable = testTable;
	}
	/**
	 * 获得连接池自动增长大小
	 * @return 自动增长大小
	 */
	public int getIncreamentConnections() {
		return increamentConnections;
	}
	/**
	 * 设置连接池自动增长大小
	 * @param increamentConnections 自动增长大小
	 */
	public void setIncreamentConnections(int increamentConnections) {
		this.increamentConnections = increamentConnections;
	}
	/**
	 * 获得连接池最大连接数
	 * @return 最大连接数
	 */
	public int getMaxConnections() {
		return maxConnections;
	}
	/**
	 * 设置连接池最大连接数
	 * @param maxConnections 最大连接数
	 */
	public void setMaxConnections(int maxConnections) {
		this.maxConnections = maxConnections;
	}
	/**
	 * 获得连接池初始化连接数
	 * @return 初始化连接数
	 */
	public int getInitConnections() {
		return initConnections;
	}
	/**
	 * 设置连接池初始化连接数
	 * @param initConnections 初始化连接数
	 */
	public void setInitConnections(int initConnections) {
		this.initConnections = initConnections;
	}
	/**
	 * 使程序等待给定的毫秒数
	 * @param mseconds 毫秒数
	 */
	private void wait(int mseconds ){
		try {
			Thread.sleep(mseconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 刷新连接池对象
	 * @throws Exception 抛出异常
	 */
	public synchronized void refreshConnections()throws Exception{
		if(connections==null){
			System.out.println("连接池不存在,无法刷新连接!");
			return;
		}
		PooledConnection connection=null;
		Enumeration enumer=connections.elements();
		while(enumer.hasMoreElements()){
			connection=(PooledConnection)enumer.nextElement();
			if(connection.isBusy()){
				this.wait(5000);
			}
			closeConnection(connection.getConn());//调用closeConnection(Connection conn)关闭数据库连接;
			connection.setConn(newConnection());
			connection.setBusy(false);
		}
	}
	/**
	 * 关闭连接池对象
	 * @throws Exception 抛出异常
	 */
	public synchronized void closeConnectionPool()throws Exception{
		if(connections==null){
			System.out.println("连接池已经关闭");
			return;
		}
		PooledConnection connection=null;
		Enumeration enumer=connections.elements();
		while(enumer.hasMoreElements()){
			connection =(PooledConnection)enumer.nextElement();
			if(connection.isBusy()){
			   wait(5000);
			}
			closeConnection(connection.getConn());//调用closeConnection(Connection conn)关闭数据库连接;
			
		}
		connections.clear();
		connections=null;
	}
	/**
	 * 关闭数据库连接
	 * @param con 数据库连接
	 */
	private void closeConnection(Connection con){
		try {
			con.close();
		} catch (SQLException e) {
			System.err.print(e.getMessage());
		}
	}
	/**
	 * 创建一个新的数据库连接对象
	 * @return 数据库连接
	 * @throws Exception 抛出异常
	 */
	private Connection newConnection()throws Exception{
		Connection con=DriverManager.getConnection(url,userName,password);
		if(connections.size()==0){
			DatabaseMetaData metadata=con.getMetaData();
			int driverMaxConnection=metadata.getMaxConnections();//如果数据库最大连接数为0,表示该数据库最大连接数没有限制
			if(driverMaxConnection>0&&this.maxConnections>driverMaxConnection){
				this.maxConnections=driverMaxConnection;
			}
		}
		return con;
	}
	/**
	 * 根据指定的连接数创建连接池的连接的个数
	 * @param numConnections 连接数
	 * @throws Exception 抛出异常
	 */
	@SuppressWarnings("unchecked")
	private void createConnections(int numConnections)throws Exception{
		for(int i=0;i<numConnections;i++){
			if(this.maxConnections>0&&this.connections.size()>=this.maxConnections){
				break;
			}
			try {
				connections.addElement(new PooledConnection(newConnection()));
			} catch (Exception e) {
				System.err.println("创建数据库连接失败");
				throw new Exception();
			}
			System.out.println("创建数据库连接个数为:"+i);
		}
	}
	/**
	 * 创建连接池对象
	 * @throws Exception
	 */
	public synchronized void createPool()throws Exception{
		if(connections!=null){
			return;//如果连接数已存在则不用创建
		}
		Driver driver=(Driver)(Class.forName(this.jdbcDriver)).newInstance();
		DriverManager.registerDriver(driver);
		connections =new Vector();
		createConnections(this.initConnections);//根据初始化连接数的数目,创建连接池的连接数目
		System.out.println("数据库连接池创建成功!");
	}
	/**
	 * 将指定数据库连接设为空闲状态
	 * @param conn 数据库连接
	 * @throws Exception 抛出异常
	 */
	public void returnConnection(Connection conn)throws Exception{
		if(connections==null){
			System.out.println("连接池不存在,无法获得连接对象");
			return;
		}
		PooledConnection poolConnection=null;
		Enumeration eum=connections.elements();
		while(eum.hasMoreElements()){
			poolConnection=(PooledConnection)eum.nextElement();
			if(conn==poolConnection.getConn()){
				poolConnection.setBusy(false);
				break;
			}
		}
	}
	/**
	 * 测试从数据库连接池中获得的数据库连接对是否可用
	 * @param conn 数据库连接
	 * @return boolean 是否可用
	 */
	private boolean testConnection(Connection conn){
		try {
			if(testTable.equals(" ")){
				conn.setAutoCommit(true);
			}else{
				Statement sta=conn.createStatement();
				sta.execute("select count(*) from "+testTable);
			}
		} catch (SQLException e) {
			closeConnection(conn);
			return false;
		}
		return true;
	}
	/**
	 * 查找空闲的连接(也就是可用连接)
	 * @return 数据库连接
	 */
	private Connection findFreeConnection(){
		Connection conn=null;
		PooledConnection poolConn=null;
		Enumeration enu=connections.elements();
		while(enu.hasMoreElements()){
			poolConn=(PooledConnection)enu.nextElement();
			if(!poolConn.isBusy()){
				conn=poolConn.getConn();
				poolConn.setBusy(true);
				if(!testConnection(conn)){
					try {
						conn=newConnection();
					} catch (Exception e) {
						System.err.println(e.getMessage());
						return null;
					}
					poolConn.setConn(conn);
				}
				break;
			}
		}
		return conn;
	}
	/**
	 * 获得可用连接
	 * @return 可用数据库连接
	 * @throws Exception 抛出异常
	 */
	private Connection getFreeConnection()throws Exception{
		Connection conn=findFreeConnection();
		if(conn==null){//如果没有找到则创建连接数获得连接对象
		createConnections(this.increamentConnections);
		conn=findFreeConnection();
		if(conn==null){
			return null;
		}
			
		}
		return conn;
	}
	/**
	 * 此方法供外部调用来或得连接对象,支持多线程访问
	 * @return 可用的连接对象
	 * @throws Exception 抛出异常
	 */
	public synchronized Connection getConnection()throws Exception{
		if(connections==null){
			return null;
		}
		Connection conn=getFreeConnection();
		while(conn==null){
			wait(250);
			conn=getFreeConnection();
		}
		return conn;
	}
}

 

package com.bpcrm.kevin.util.DB_utill.connection_pool;

import java.sql.Connection;
/**
 * 将数据库链接包装为一个对象
 * @author kevin.wangwei
 *	2009-11-17
 */
public class PooledConnection {
	/**连接属性*/
	private Connection conn=null;
	/**该连接是否空闲*/
	private boolean busy=false;
	/**
	 * 设置一个连接
	 * @param con 连接对象
	 */
	public PooledConnection(Connection con){
		this.conn=con;
	}
	/**
	 * 获得该连接对象的空闲属性
	 * @return 该连接是否空闲
	 */
	public boolean isBusy() {
		return busy;
	}
	/**
	 * 设置该连接的空闲属性
	 * @param busy 空闲值
	 */
	public void setBusy(boolean busy) {
		this.busy = busy;
	}
	/**
	 * 获得该连接对象的数据库连接
	 * @return 数据库连接
	 */
	public Connection getConn() {
		return conn;
	}
	/**
	 * 设置该连接对象的数据库连接
	 * @param conn 数据库连接
	 */
	public void setConn(Connection conn) {
		this.conn = conn;
	}
}

 

分享到:
评论

相关推荐

    web中常用数据库连接池

    数据库连接池的基本工作原理是:当应用程序需要访问数据库时,首先从连接池中获取一个已经建立好的连接,使用完毕后,不是立即关闭连接,而是将其归还给连接池,以便其他请求再次使用。这样避免了频繁地打开和关闭...

    Java jdbc数据库连接池总结

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

    JSP数据库连接池技术与应用

    总结,JSP数据库连接池技术的应用对于优化Java Web应用的数据库操作性能、提高系统资源利用率具有重要意义。开发者应熟练掌握数据库连接池的原理和使用,以便在实际项目中实现更高效的数据库访问。同时,选择合适的...

    配置数据库连接池

    数据库连接池的基本思想是预先创建并维护一定数量的数据库连接,当应用需要与数据库通信时,可以快速地从连接池中获取一个已建立的连接,而不是每次都新建一个。用完后,连接会归还到池中,供其他请求使用,而不是...

    C# 数据库连接池

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

    JSP数据库连接池连接实例

    在IT行业中,数据库连接池是优化应用程序性能的关键技术之一,特别是在使用Java服务器页面(JSP)进行Web开发时。数据库连接池允许程序高效地管理与数据库的连接,减少了创建和销毁连接的开销,提高了系统资源利用率...

    数据库连接池使用范例

    在Java Web应用中,常用的数据库连接池工具有C3P0、HikariCP、Druid等。以HikariCP为例,它是目前性能较好的连接池之一,以其高效和低延迟著称。配置HikariCP通常涉及以下步骤: 1. 添加依赖:在Maven或Gradle的...

    数据库连接池在web开发中的应用

    数据库连接池在Web开发中扮演着至关重要的角色,它能够有效地管理和优化数据库连接,提高系统的性能和稳定性。本文将深入探讨Tomcat自带的DBCP(Database Connection Pool)库的使用,以及它如何与Web应用程序集成。...

    Java数据库连接池的原理与应用.pdf

    综上所述,数据库连接池是Java Web应用程序中重要的技术组件,它的运用有助于提高数据库操作的效率,并且能够优化整个应用程序的性能表现。掌握连接池的原理与应用,对于Java开发者来说是必不可少的一项技能。

    java_jdbc数据库连接池总结

    Java JDBC 数据库连接池是 Java 应用程序访问数据库的基本原理之一。Java 语言通过 JDBC 技术访问数据库,JDBC 是一种“开放”的方案,为数据库应用开发人员和数据库前台工具开发人员提供了一种标准的应用程序设计...

    自定义的数据库连接池

    数据库连接池是数据库管理中的重要概念,它在Java Web应用中尤其常见,主要用于优化数据库的连接管理和资源利用。自定义数据库连接池是为了更好地适应特定应用的需求,提高数据存取的效率,减少系统开销,避免频繁...

    论文研究-绝对延迟保证在Web应用服务器数据库连接池中的实现.pdf

    通过系统辨识建立了数据库连接池的近似线性时不变模型LTI, 并设计了绝对延迟保证控制器, 为Tomcat Web应用服务器实现了数据库连接池中闭环系统所有部件。测试结果表明, 即使在并发请求数量剧烈变化时, 控制器的设计...

    数据库连接池管理策略

    数据库连接池管理策略是优化数据库应用性能的关键环节。在软件开发中,特别是涉及到与数据库交互的应用,连接池的使用能够显著提升系统效率。本文将详细解释数据库连接池的工作原理、优缺点以及如何进行管理和配置。...

    jsp连接数据库连接池代码示例

    在Java Web开发中,JSP(JavaServer Pages)常用于创建动态网页,而与数据库的交互是其中不可或缺的一部分。...理解并正确使用数据库连接池是提高Web应用程序性能的关键步骤,也是每个Java开发者必备的技能。

    数据库连接池选型

    数据库连接池是现代应用程序开发中的重要组成部分,它有效地管理和优化了数据库资源的使用,提高了系统的性能和稳定性。本文将深入探讨“数据库连接池选型”的关键知识点,主要以阿里Druid连接池为例,同时也会涉及...

    Java中数据库连接池原理机制的详细讲解.pdf

    ### Java中数据库连接池原理机制详解 #### 一、引言 在现代软件开发中,尤其是在基于Java的应用程序中,数据库连接池技术是一项至关重要的技术。它能够显著提高应用程序访问数据库的效率,减少资源消耗,并简化...

    winform数据库连接池源码

    数据库连接池的基本原理是:当一个应用请求一个新的数据库连接时,连接池不会立即创建一个新的连接,而是从已有的连接池中返回一个已存在的、可重用的连接。如果池中没有空闲连接,它会根据预设的规则创建新的连接并...

Global site tag (gtag.js) - Google Analytics