数据库连接池

本文介绍数据库连接池的工作原理及其在Java中的实现方式,包括c3p0、BoneCP、DBCP等主流连接池的特性与配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库连接池负责分配,管理和释放数据库连接。

优点:

减少连接的创建时间,创建新的JDBC连接仍会招致网络和JDBC驱动的开销。

简化的编程模式

受控的资源使用

连接池能够使性能最大化,还能将资源利用控制在一定的水平之下。

将数据库连接作为对象存储在Vector对象中,一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接。

数据库连接池的主要操作:

1.建立数据库连接池对象(服务器启动)

2.按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)

3.对于数据库访问请求,直接从连接池中得到一个连接。数据库连接池对象没有空闲的连接,且连接数没有达到最大,创建一个新的数据库连接。

4.存取数据库

5.关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。)

6.释放数据库连接池对象(服务器停止,维护期间,释放数据库连接池对象,并释放所有连接)

连接池使用

servlet的生命周期是:在开始建立servlet时,调用其初始化(init)方法。之后每个用户请求都调用前面建立的实例的service方法的线程。当服务器决定卸载一个servlet时,它首先调用该servlet的destroy方法。根据servlet的特点在初始化函数中生成连接池管理类中的唯一实例(一个或多个连接池)

在service方法中通过连接池名称使用连接池,执行数据库操作。最后在destory方法中释放占用的系统资源。


几个主流的java连接池:

 c3p0是一个开放源代码的JDBC连接池。

BoneCP是一个开源快速的JDBC连接池。BoneCP很小,只有四十几K(运行时需要log4j和GoogleCollections的支持,这二者加起来就不小了),相比之下C3P0要六百多K。缺点:JDBC驱动的加载是在连接池之外的,这样在一些应用服务器的配置上就不够灵活。

DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池,tomcat的数据源使用的就是DBCP.


Proxool是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。非常简单的移植到现存的代码中。完全可配置。

c3p0连接池使用:c3p0.jar 

jdbc.properties

driverClass=org.gjt.mm.mysql.Driver

jdbcUrl=jdbc:mysql://localhost:3306/my_test?useUnicode=true&characterEncoding=utf-8

user=root

password=123456

#<!--初始化时获取的连接数,取值应该minPoolSize与maxPoolSzie之间。-->

initialPoolSize=3

#<!---连接池中保留的最小连接数-->

minPoolSize=1

#<--连接池中保留的最大连接数-->

maxPoolSize=15

#<!--最大空闲时间,600秒内未使用则连接被丢弃。若为0则永不丢弃。Default:0-->

maxIdleTime=200

#<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default:3-->

aquireIncrement=2

#<--每120秒检查所有连接池中的空闲连接。Default:0-->

idleConnectionTestPeriod=120

maxConnectionAge=400

package com.c3p0;

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public final class C3p0Source {
	private C3p0Source(){
	}
	private static ComboPooledDataSource dataSource;
	static{
		try {
		dataSource = new ComboPooledDataSource();
		Properties properties = new Properties();
		InputStream is = C3p0Source.class.getClassLoader().getResourceAsStream("jdbc.properties");//类加载器 返回一个读取指定资源的输入流
		properties.load(is);//从输入流中读取属性列表
		//dataSource.setProperties(properties);
		dataSource.setUser(properties.getProperty("user"));
		dataSource.setPassword(properties.getProperty("password"));
		dataSource.setJdbcUrl(properties.getProperty("JdbcUrl"));
		dataSource.setDriverClass(properties.getProperty("DriverClass"));
		dataSource.setInitialPoolSize(Integer.parseInt(properties.getProperty("InitialPoolSize")));
		dataSource.setMinPoolSize(Integer.parseInt(properties.getProperty("MinPoolSize")));
		dataSource.setMaxPoolSize(Integer.parseInt(properties.getProperty("MaxPoolSize")));
		dataSource.setMaxIdleTime(Integer.parseInt(properties.getProperty("MaxIdleTime")));
		dataSource.setIdleConnectionTestPeriod(Integer.parseInt(properties.getProperty("IdleConnectionTestPeriod")));
		dataSource.setMaxConnectionAge(Integer.parseInt(properties.getProperty("MaxConnectionAge")));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (PropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection(){
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void realseSource(ResultSet rs,Statement st,Connection conn) throws SQLException{
		try{
			if(rs!=null){
				rs.close();
			}
		} finally{
			try{
				if(st != null){
					st.close();
				}
			}finally{
				if(conn != null){
					conn.close();
				}
			}
		}
		
	}
}

jdbc.properties属性文件可以写成xml格式

早期的c3p0版本对JDBC接口采用动态反射代理。

DBCP连接池使用:commons-dbcp-1.4.jar commons-pool.jar commons-collections-3.2.jar

dbcpconfig.properties

#数据库驱动器全限定名称

driverClassName=org.microsoft.sqlserver.jdbc.SQLServerDriver

#与数据库连接的url

url=jdbc:sqlserver//localhost:1433;DatabaseName=dbTest1

#用户名

username=sa

#密码

password=admin

#连接的初始化个数

initialPoolSize=10

#最大活跃数

maxActive=50

#最大空闲连接数

maxIdle=20

#最小空闲连接数

minIdle=5

#最大等待时间

maxWait=60000

#连接属性

connectionProperties=useUnicode=true;characterEncoding=gbk

#默认是否自动提交

defaultAutoCommit=true

#默认事物隔离级别

defaultTransactionIsolation=Read_COMMITED


package com.c3p0;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

public final class DBCPBean {
	//数据源,static
	private static DataSource DS;
	
	public Connection getConn(){
		try {
			return DS.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	//默认的构造函数
	public DBCPBean(){
	}
	
	//构造函数,初始化了DS,指定数据库
	public DBCPBean(String connectURI){
		initDS(connectURI);
	}
	
	public static void initDS(String connectURI){
		initDS(connectURI,"root","password","com.mysql.jdbc.Driver",5,100,30,10000);
	}
	
	public static void initDS(String connectURI,String username,String pswd,String driverClass,int initialSize,int maxActive,int maxIdle,int maxWait){
		BasicDataSource ds = new BasicDataSource();
		ds.setDriverClassName(driverClass);
		ds.setUserName(username);
		ds.setPassword(pswd);
		ds.setUrl(connectURI);
		ds.setInitialSize(initialSize);
		ds.setMaxWait(maxWait);
		DS = ds;
	}
	
	//获取数据源连接状态
	public static Map<String,Integer> getDataSourceStats() throws SQLException{
		BasicDataSource bds = (BasicDataSource)DS;
		Map<String,Integer> map = new HashMap<String,Integer>(2);
		map.put("active_number", bds.getNumberActive());
		map.put("idle_number", bds.getNumberIdle());
		return map;
	}
	
	//关闭数据源
	protected static void shutdownDataSource() throws SQLException{
		BasicDataSource bds = (BasicDataSource)DS;
		bds.close();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值