数据库连接池之DBCP数据源

数据库连接池之DBCP数据源

精选文章moguli202025-03-04 11:27:4210A+A-

两种开源的数据库连接池

JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:

  • DBCP 数据库连接池
  • C3P0 数据库连接池

DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池

DBCP数据源

DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool. 如需使用该连接池实现,应在系统中增加如下两个 jar 文件:

  • Commons-dbcp.jar:连接池的实现
  • Commons-pool.jar:连接池实现的依赖库

Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

注意:

  • 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
  • 当数据库访问结束后,程序还是像以前一样关闭数据库连接:close(); 但conn.close()并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。

方式一:

示例代码:

步骤:

1、加入两个jar

DBCP数据库连接池的的jar:Commons-dbcp.jar

连接池实现的依赖库:Commons-pool.jar,如果不加这个,运行报如下异常

Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/pool/KeyedObjectPoolFactory
???????? at com.jdbc.datasource.TestDBCP.main(TestDBCP.java:14)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.pool.KeyedObjectPoolFactory
???????? at java.net.URLClassLoader.findClass(Unknown Source)
???????? at java.lang.ClassLoader.loadClass(Unknown Source)
???????? at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
???????? at java.lang.ClassLoader.loadClass(Unknown Source)
???????? … 1 more

2、编写代码

package com.jdbc.datasource;
?
import java.sql.Connection;
import java.sql.SQLException;
?
import org.apache.commons.dbcp.BasicDataSource;
?
public class TestDBCP {
?
???????? public static void main(String[] args) throws SQLException {
????????????????? //1.创建DBCP数据源(即连接池)
????????????????? BasicDataSource ds = new BasicDataSource();
?
????????????????? //2.设置数据源的必须属性
????????????????? ds.setDriverClassName(“com.mysql.jdbc.Driver”);
????????????????? ds.setUrl(“jdbc:mysql://localhost:3306/test”);
????????????????? ds.setUsername(“root”);
????????????????? ds.setPassword(“root”);
?
????????????????? //3.设置数据源的可选属性
????????????????? //(1)指定数据库连接池中初始化连接数的个数
????????????????? ds.setInitialSize(10);
?
????????????????? //(2)指定最大的连接数: 同一时刻可以同时向数据库申请的连接数
????????????????? ds.setMaxActive(50);
?
????????????????? //(3)在数据库连接池中保存的最少的空闲连接的数量
????????????????? ds.setMinIdle(2);
?
????????????????? //(4)等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常.
????????????????? ds.setMaxWait(1000*5);
?
????????????????? //4.从数据源中获取数据库连接
????????????????? Connection conn = ds.getConnection();
????????????????? System.out.println(conn);
???????? }
}

测试超过连接数

package com.jdbc.datasource;
?
import java.sql.Connection;
import java.sql.SQLException;
?
import org.apache.commons.dbcp.BasicDataSource;
?
public class TestDBCP2 {
?
???????? public static void main(String[] args) throws SQLException {
????????????????? //1.创建DBCP数据源(即连接池)
????????????????? BasicDataSource ds = new BasicDataSource();
?
????????????????? //2.设置数据源的必须属性
????????????????? ds.setDriverClassName(“com.mysql.jdbc.Driver”);
????????????????? ds.setUrl(“jdbc:mysql://localhost:3306/test”);
????????????????? ds.setUsername(“root”);
????????????????? ds.setPassword(“root”);
?
????????????????? //3.设置数据源的可选属性
????????????????? //(1)指定数据库连接池中初始化连接数的个数
????????????????? ds.setInitialSize(3);
?
????????????????? //(2)指定最大的连接数: 同一时刻可以同时向数据库申请的连接数
????????????????? ds.setMaxActive(5);
?
????????????????? //(3)指定最小活跃的连接数: 在数据库连接池中保存的最少的空闲连接的数量
????????????????? ds.setMinIdle(2);
?
????????????????? //(4)等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常.
????????????????? ds.setMaxWait(1000*5);
?
????????????????? //4.从数据源中获取数据库连接
????????????????? for(int i=0;i<6;i++){
????????????????????????? Connection conn = ds.getConnection();
????????????????????????? System.out.println(“获取第”+(i+1)+”个”+conn);
????????????????????????? //这里没有关闭,即没有放回连接池
????????????????? }
???????? }
}

测试如果连接重复使用

package com.jdbc.datasource;
?
import java.sql.Connection;
import java.sql.SQLException;
?
import org.apache.commons.dbcp.BasicDataSource;
?
public class TestDBCP3 {
?
???????? public static void main(String[] args) throws SQLException {
????????????????? //1.创建DBCP数据源(即连接池)
????????????????? BasicDataSource ds = new BasicDataSource();
?
????????????????? //2.设置数据源的必须属性
????????????????? ds.setDriverClassName(“com.mysql.jdbc.Driver”);
????????????????? ds.setUrl(“jdbc:mysql://localhost:3306/test”);
????????????????? ds.setUsername(“root”);
????????????????? ds.setPassword(“root”);
?
????????????????? //3.设置数据源的可选属性
????????????????? //(1)指定数据库连接池中初始化连接数的个数
????????????????? ds.setInitialSize(3);
?
????????????????? //(2)指定最大的连接数: 同一时刻可以同时向数据库申请的连接数
????????????????? ds.setMaxActive(5);
?
????????????????? //(3)指定最小活跃的连接数: 在数据库连接池中保存的最少的空闲连接的数量
????????????????? ds.setMinIdle(2);
?
????????????????? //(4)等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常.
????????????????? ds.setMaxWait(1000*5);
?
????????????????? //4.从数据源中获取数据库连接
????????????????? for(int i=0;i<10;i++){
????????????????????????? new Thread(){
?????????????????????????????????? public void run(){
??????????????????????????????????????????? try {
???????????????????????????????????????????????????? Connection conn = ds.getConnection();
???????????????????????????????????????????????????? System.out.println(“获取1个”+conn);
?
???????????????????????????????????????????????????? Thread.sleep(3000);
?
???????????????????????????????????????????????????? //隔3秒换回去
???????????????????????????????????????????????????? conn.close();
??????????????????????????????????????????? } catch (Exception e) {
???????????????????????????????????????????????????? e.printStackTrace();
??????????????????????????????????????????? }
?????????????????????????????????? }
????????????????????????? }.start();
?
????????????????? }
???????? }
}

方式二:

优化代码:

直接使用BasicDataSource,耦合,而且在代码中需要很多setXxx()设置属性值

使用dbcp.properties属性配置文件和BasicDataSourceFactory更灵活

步骤:

  1. 加载 dbcp 的 properties 配置文件: 配置文件中的键需要来自 BasicDataSource的属性.
  2. 调用 BasicDataSourceFactory 的 createDataSource 方法创建 DataSource实例
  3. 从 DataSource 实例中获取数据库连接.
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
initialSize=3
maxActive=5
minIdle=2
maxWait=5000
package com.jdbc.datasource;
?
import java.sql.Connection;
import java.util.Properties;
?
import javax.sql.DataSource;
?
import org.apache.commons.dbcp.BasicDataSourceFactory;
?
public class TestDBCP3 {
?
???????? public static void main(String[] args) throws Exception {
????????????????? //1.获取配置文件信息
??????????????????//注意:配置文件中的key来自BasicDataSourceFactory的属性(set方法后面单词首字母改小写即可)
????????????????? Properties pro = new Properties();
????????????????? pro.load(ClassLoader.getSystemResourceAsStream(“dbcp.properties”));
?
????????????????? //2.创建DBCP数据源(即连接池)
????????????????? DataSource ds = BasicDataSourceFactory.createDataSource(pro);
?
????????????????? //3.从数据源中获取数据库连接
????????????????? Connection conn = ds.getConnection();
????????????????? System.out.println(“获取1个”+conn);
???????? }
}

JDBCUtils修改DBCP版:

package?com.atguigu.utils;
?
import?java.sql.Connection;
import?java.util.Properties;
?
import?javax.sql.DataSource;
?
import?org.apache.commons.dbcp.BasicDataSourceFactory;
?
public?class?DBCPUtils {
????private?static?Properties?pro?=?new?Properties();
????private?static?DataSource?ds?;
?
????static{
?????????try?{
???????????? //加载,读取jdbc.properties配置的信息
?????????????pro.load(ClassLoader.getSystemClassLoader().getResourceAsStream(“dbcp.properties”));
?
???????????? //创建池子
?????????????ds?= BasicDataSourceFactory.createDataSource(pro);
???????? }??catch?(Exception e) {
???????????? e.printStackTrace();
???????? }
??? }
?
????public?static?Connection getConnection()throws?Exception{
?????????return?ds.getConnection();
??? }
?
}

想要了解更多关于Java技术内容欢迎关注尚硅谷教育!

点击这里复制本文地址 以上内容由莫古技术网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

莫古技术网 © All Rights Reserved.  滇ICP备2024046894号-2