数据库连接池

博客介绍了Java连接池相关内容,包括自定义连接池,其核心是单例模式和动态代理;还介绍了DBCP连接池,它是Apache开源实现,Tomcat采用该连接池,有硬编码和配置两种实现方式;以及常用的C3P0连接池,Spring默认支持,有硬编码和XML两种实现方式。

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

1. 自定义连接池

需求:预先创建一组连接,用的时候每次取出一个; 用完后,放回。

核心:单例模式、动态代理(可以监测接口中方法的执行)

import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;

public class MyPOOL {

	private int init = 3;// 初始连接数
	private int max = 6;// 最大连接数
	private int curr = 0;// 当前连接数
	private LinkedList<Connection> connPool = new LinkedList<Connection>();// 存放连接的集合
	private String driver;
	private String url;
	private String username;
	private String password;
	private static MyPOOL pool = new MyPOOL();

	public static MyPOOL getInstance() {// 单例模式
		return pool;
	}

	private MyPOOL() {// 初始化连接
		try {
			Properties pro = new Properties();
			InputStream stream = MyPOOL.class.getClassLoader().getResourceAsStream("db.properties");
			pro.load(stream);
			driver = pro.getProperty("driver");
			url = pro.getProperty("url");
			username = pro.getProperty("username");
			password = pro.getProperty("password");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		for (int i = 0; i < init; i++) {
			connPool.addLast(createConnection());// 连接加入连接池
			curr++;// 记录当前连接数
		}
	}

	private Connection createConnection() {
		try {// 创建连接
			Class.forName(driver);
			final Connection con = DriverManager.getConnection(url, username, password);
			// 对con创建其代理对象
			Connection proxyCon = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), // 类加载器
					new Class[] { Connection.class }, // 目标对象实现的接口
					new InvocationHandler() {
						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							Object result = null;
							String methodName = method.getName();
							if ("close".equals(methodName)) {
								connPool.addLast(con);
							} else {
								result = method.invoke(con, args);
							}
							return result;
						}
					});
			return proxyCon;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public Connection getConnection() {// 获取连接
		if (connPool.size() > 0) {// 判断连接池中是否有连接,如果有就直接从连接池中取
			return connPool.removeFirst();
		} else if (curr < max) {// 没有并且未达到最大连接数,创建
			curr++;// 记录当前使用的连接数
			return createConnection();
		}
		throw new RuntimeException("当前连接已经达到最大连接数目!");// 达到则抛异常
	}

	public void release(Connection con) {// 释放连接
		if (connPool.size() < init) {// 当连接池的数目小于当前连接数,就放入池中
			connPool.addLast(con);
		} else {
			try {// 否则关闭
				con.close();
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public static void main(String[] args) {
		MyPOOL p = MyPOOL.getInstance();
		Connection connection = p.getConnection();
		p.release(connection);
	}

}

2. DBCP连接池(核心类:BasicDataSource)

DBCP 是Apache软件基金组织下的开源连接池实现。使用前应导入两个 jar 包(commons-dbcp、commons-pool)。Tomcat 的连接池正是采用DBCP来实现的。

2.1 硬编码方式实现连接池

BasicDataSource source = new BasicDataSource();
//连接池参数配置
source.setUrl("jdbc:oracle:thin:@localhost:1521:orcl"); // 数据库连接字符串
source.setDriverClassName("oracle.jdbc.driver.OracleDriver"); // 数据库驱动
source.setUsername("sys as sysdba"); // 数据库连接用户
source.setPassword("oracle"); // 数据库连接密码
source.setInitialSize(3); // 初始化连接
source.setMaxActive(6); // 最大连接
source.setMaxIdle(3000); // 最大空闲时间
Connection con = source.getConnection();// 获取连接
con.close();// 关闭连接

2.2 配置方式实现连接池

db.properties:

url=jdbc:oracle:thin:@localhost:1521:orcl
driverClassName=oracle.jdbc.driver.OracleDriver
username=sys as sysdba
password=oracle
initialSize=3
maxActive=6
maxIdle=3000
Properties prop = new Properties();// 加载prop配置文件
InputStream inStream = DBCP.class.getClassLoader().getResourceAsStream("db.properties");// 获取文件流
prop.load(inStream);// 加载属性配置文件
DataSource dataSouce = BasicDataSourceFactory.createDataSource(prop);// 根据prop配置,直接创建数据源对象
Connection con = dataSouce.getConnection();// 获取连接
con.close();// 关闭

3. C3P0连接池(核心类:ComboPooledDataSource)

最常用的连接池技术,Spring框架,默认支持C3P0连接池技术。

3.1 硬编码方式实现连接池

ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接参数
dataSource.setDriverClass("oracle.jdbc.driver.OracleDriver");
dataSource.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:orcl");
dataSource.setUser("sys as sysdba");
dataSource.setPassword("oracle");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
Connection con = dataSource.getConnection();//获取连接
con.close();// 关闭

3.2 XML方式实现连接池

c3p0-config.xml:

<c3p0-config>
	<default-config><!-- 默认配置 -->
	    <ptoperty name="driverClass">oracle.jdbc.driver.OracleDriver</ptoperty>
		<ptoperty name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl</ptoperty>
		<ptoperty name="user">sys as sysdba</ptoperty>
		<ptoperty name="password">oracle</ptoperty>
		<ptoperty name="initialPoolSize">3</ptoperty>
		<ptoperty name="maxPoolSize">6</ptoperty>
		<ptoperty name="maxIdleTime">1000</ptoperty>
	</default-config>
	<name-config name="july">
		<ptoperty name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl</ptoperty>
		<ptoperty name="driverClass">oracle.jdbc.driver.OracleDriver</ptoperty>
		<ptoperty name="user">sys as sysdba</ptoperty>
		<ptoperty name="password">oracle</ptoperty>
		<ptoperty name="initialPoolSize">3</ptoperty>
		<ptoperty name="maxPoolSize">6</ptoperty>
		<ptoperty name="maxIdleTime">1000</ptoperty>
	</name-config>
</c3p0-config>
// 创建c3p0连接池核心工具类
// 自动加载src下c3p0的配置文件c3p0-config.xml
ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置(default-config)
//ComboPooledDataSource dataSource = new ComboPooledDataSource("july");// 使用指定的的配置(name-config)
Connection con = dataSource.getConnection();// 获取连接
con.close();// 关闭

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值