JDBC 的两种开源的数据库连接池

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

1、DBCP 数据库连接池

2、C3P0 数据库连接池

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

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

1)Commons-dbcp.jar:连接池的实现

2)Commons-pool.jar:连接池实现的依赖库

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

注意:

数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。

当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.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();
}

}

2、C3P0 数据源
C3P0 是一个开源的 JDBC 连接池,它实现了数据源和 JNDI 绑定,支持 JDBC3 规范和 JDBC2 的标准扩展。目前使用它的开源项目有 Hibernate,Spring 等。

c3p0 与 dbcp 区别

dbcp 没有自动回收空闲连接的功能

c3p0 有自动回收空闲连接功能

方式一:

步骤:

1、加入 jar

如果是 c3p0-0.9.1.2 版本,加入一个 jar 即可 c3p0-0.9.1.2.jar

如果是 c3p0-0.9.2 之后的版本,需要加入两个 jar:c3p0-0.9.X.jar 和 mchange-commons-java-XX.jar

2、编写代码

package com.jdbc.datasource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TestC3P0 {
public static void main(String[] args)throws Exception {
//1、创建c3p0数据源对象
ComboPooledDataSource ds = new ComboPooledDataSource();
//2、设置必须属性
ds.setDriverClass( "com.mysql.jdbc.Driver" );
ds.setJdbcUrl( "jdbc:mysql://localhost:3306/test" );
ds.setUser("root");
ds.setPassword("root");

//3、获取连接
System.out.println(ds.getConnection());
}
}
方式二:

步骤:

  1. 在 src 目录创建 c3p0-config.xml 文件, 参考帮助文档中 Appendix B: Configuation Files 的内容
  2. 创建 ComboPooledDataSource 实例;

DataSource dataSource = new ComboPooledDataSource("helloc3p0");

  1. 从 DataSource 实例中获取数据库连接.


[I1]


root
root
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/test


5

5

5

10

package com.jdbc.datasource;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TestC3P02 {
public static void main(String[] args)throws Exception {
DataSource dataSource = new ComboPooledDataSource("helloc3p0");
System.out.println(dataSource.getConnection());
}
}
JDBCUtils 修改成 c3p0 版

package com.atguigu.utils;

import java.sql.Connection;
import java.sql.SQLException;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Utils {
//创建数据源,用的是c3p0-config.xml文件中
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

//获取数据源对象
public static ComboPooledDataSource getDataSource() {
return dataSource;
}

//获取连接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
}

如果只有一个配置,那么可以使用,代替

这样在 new ComboPooledDataSource()就可以使用无参构造了。

关键词:java培训

你可能感兴趣的:(jdbc)