准备
pom.xml
<!-- dbcp连接池-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
demo
public class DbcpUtil {
private static DataSource dataSource = null;
//静态代码块初始化数据库连接池
static {
//通过配置文件dbcp.properties 加载dbcp相关配置文件
PropertiesUtil.load("dbcp.properties");
try {
//一个数据源 一个应用范围内加载一次
dataSource = BasicDataSourceFactory.createDataSource(PropertiesUtil.getProperties());
} catch (Exception e) {
e.printStackTrace();
}
}
//直接从连接池获取连接
public static Connection getConnection() {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void main(String[] args) {
//获取连接
Connection connection = DbcpUtil.getConnection();
String sql1 = " select * from t_user tu where name = '张三'";
Statement statement = null;
try {
statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql1);
//第四步:获取结果
while (resultSet.next()) {
String name = resultSet.getString("name");
Integer age = resultSet.getInt("age");
System.out.println("name:" + name + " age:" + age); //打印输出结果集
}
} catch (SQLException e) {
e.printStackTrace();
}
}
到这里我们就能简单的跑一个dbcp数据库连接池的demo了
源码级原理
核心类
BasicDataSourceFactory类
BasicDataSource的工厂类,创建BasicDataSource对象,此类能查看所有数据库连接池的配置
BasicDataSource类
1、主要通过public Connection getConnection() throws SQLException
方法对外提供数据库连接
2、步骤1中的getConnection()是通过内部持有的DataSource 对象提供的。后面会提到是PoolingDataSource的实例。
3、通过protected synchronized DataSource createDataSource()
经过一系列处理 得到PoolingDataSource的实例
PoolingDataSource类
PoolingDataSource类持有连接池ObjectPool对象,并且通过连接池对外提供getConnection()方法。
GenericObjectPool类
上面PoolingDataSource的连接池对象,提供核心方法
//获取连接
Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException;
//返回连接
void returnObject(Object obj) throws Exception;
//校验连接
void invalidateObject(Object obj) throws Exception;
//添加连接
void addObject() throws Exception, IllegalStateException, UnsupportedOperationException;
PoolableConnectionFactory类
上面GenericObjectPool类的工厂类 核心方法
//为数据库连接池提供一个连接对象
Object makeObject() throws Exception;
//为数据库连接池销毁一个连接对象
void destroyObject(Object obj) throws Exception;
//数据库连接池校验连接是否可用
boolean validateObject(Object obj);
//激活连接能够为连接池所用
void activateObject(Object obj) throws Exception;
//从连接池返回空闲状态
void passivateObject(Object obj) throws Exception;
核心流程
初始化过程
- 入口 加载配置 创建BasicDataSource 数据源
BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(PropertiesUtil.getProperties());
这里是通过BasicDataSourceFactory工厂创建的,经过这一步的BasicDataSource实例并没有与数据库有交互,只是简单处理了一下配置项。
注意:如果需要查看dbcp支持哪些配置,这个BasicDataSourceFactory能看到每个配置项。
- BasicDataSource数据源赋予能力(主要是注入的datasource的能力)
展开看整个流程 忽略上面的对象不为空直接返回
2.1、加载驱动并且返回 DriverConnectionFactory 对象,该对象具有物理创建数据库连接Connection的能力 2.2、创建一个连接池 默认是GenericObjectPool类的实例 set各种properpties
2.3、创建一个PoolableConnectionFactory 并且把它注入上面连接池,为上面连接池提供make,destory数据库连接的能力
2.4、创建真实的数据源PoolingDataSource 的对象,并且PoolingDataSource持有GenericObjectPool数据库连接池对象。GenericObjectPool对象对外核心的从连接池获取,释放连接的能力。
获取连接过程
经过了上面整个初始化,现在dbcp连接池具有了对外提供数据库连接的能力。
BasicDataSource.getConnection()
-->PoolingDataSource.getConnection()
---->GenericObjectPool.borrowObject()
borrowObject流程图