两种开源的数据库连接池
JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:
- DBCP 数据库连接池
- C3P0 数据库连接池
DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池
1 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更灵活
步骤:
- 加载 dbcp 的 properties 配置文件: 配置文件中的键需要来自 BasicDataSource的属性.
- 调用 BasicDataSourceFactory 的 createDataSource 方法创建 DataSource实例
- 从 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()); } } |
方式二:
步骤:
- 在src目录创建 c3p0-config.xml 文件, 参考帮助文档中 Appendix B: Configuation Files 的内容
- 创建 ComboPooledDataSource 实例;
DataSource dataSource = new ComboPooledDataSource(“helloc3p0”);
- 从 DataSource 实例中获取数据库连接.
<?xml version=”1.0″ encoding=”UTF-8″?> <c3p0-config>
<named-config name=”helloc3p0“>
<!– 指定连接数据源的基本属性 –> <property name=”user”>root</property> <property name=”password”>root</property> <property name=”driverClass”>com.mysql.jdbc.Driver</property> <property name=”jdbcUrl”>jdbc:mysql://localhost:3306/test</property>
<!– 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 –> <property name=”acquireIncrement”>5</property> <!– 初始化数据库连接池时连接的数量 –> <property name=”initialPoolSize”>5</property> <!– 数据库连接池中的最小的数据库连接数 –> <property name=”minPoolSize”>5</property> <!– 数据库连接池中的最大的数据库连接数 –> <property name=”maxPoolSize”>10</property> </named-config>
</c3p0-config> |
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文件中<default-config> private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
//获取数据源对象 public static ComboPooledDataSource getDataSource() { return dataSource; }
//获取连接 public static Connection getConnection() throws SQLException{ return dataSource.getConnection(); } }
|
上一篇: Java培训课程之JDBC修改成DbUtils版
下一篇: python好学吗