开源的连接池技术DBCP和C3P0
概述:
Sun公司约定: 如果是连接池技术,需要实现一个接口!
javax.sql.DataSource;
1.1 DBCP连接池:
l DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个 jar 文件:
- Commons-dbcp.jar:连接池的实现
- Commons-pool.jar:连接池实现的依赖库
l Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
l 核心类:BasicDataSource
l 使用步骤
- 引入jar文件
l commons-dbcp-1.4.jar
l commons-pool-1.5.6.jar
示例代码
首先创建数据库的配置信息db.properties
url=jdbc:sqlserver://localhost:1433;DataBaseName=Test username=sa password=123456 driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver initialSize=3 maxActive=6 maxIdle=3000
开始编写测试类
package com.gqx.DBCP; import static org.junit.Assert.*; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.junit.Test; import com.jdbc.util.JDBCUtil; public class DBCPTest { @Test public void test() { //硬编码 //DBCP连接池核心类 BasicDataSource dataSource =new BasicDataSource(); //连接池参数配置,初始化连接,最大连接数/连接字符串,驱动,账号密密码 dataSource.setUrl("jdbc:sqlserver://localhost:1433;DataBaseName=Test"); dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); dataSource.setUsername("sa"); dataSource.setPassword("123456"); dataSource.setInitialSize(3); //初始化链接数目 dataSource.setMaxActive(6); //最大连接数目 dataSource.setMaxIdle(3000); //设置最大空闲时间 //获取连接 Connection connection=null; PreparedStatement statement=null; try { connection=dataSource.getConnection(); String sql="insert into usershop values(?,?,?) "; statement=connection.prepareStatement(sql); statement.setInt(1, 2); statement.setInt(2, 2); statement.setInt(3, 4); statement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(connection, statement); } } //根据配置文件获取连接 @Test public void test2() throws Exception{ //加载properties加载配置文件 Properties prop=new Properties(); /** * 类路径 * . 代表java命令运行的目录 * 在java项目下,. java命令的运行目录从项目的根目录开始 * 在web项目下, . java命令的而运行目录从tomcat/bin目录开始 * 所以不能使用点. */ InputStream in = DBCPTest.class.getResourceAsStream("db.properties"); prop.load(in); //根据properties配置直接创建数据对象 DataSource dataSource=BasicDataSourceFactory.createDataSource(prop); //获取连接 Connection connection=null; PreparedStatement statement=null; try { connection=dataSource.getConnection(); String sql="insert into usershop values(?,?,?) "; statement=connection.prepareStatement(sql); statement.setInt(1, 6); statement.setInt(2, 3); statement.setInt(3, 4); statement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(connection, statement); } } }
1.1 C3P0连接池:
C3P0连接池:
最常用的连接池技术!Spring框架,默认支持C3P0连接池技术!
C3P0连接池,核心类:
CombopooledDataSource ds;
使用:
- 下载,引入jar文件: c3p0-0.9.1.2.jar
- 使用连接池,创建连接
代码示例
注意要按照c3p0的标准写一个xml文件(在c3p0的jar包的源代码文件中有实例),如我的xml配置文件,名称为“c3p0-config.xml”,这是规定,在使用其核心类的时候,它会自动加载src下名为c3p0-config.xml的文件
<c3p0-config> <default-config> <property name="jdbcUrl">jdbc:sqlserver://localhost:1433;DataBaseName=教学库</property> <property name="driverClass">com.microsoft.sqlserver.jdbc.SQLServerDriver</property> <property name="user">sa</property> <property name="password">123456</property> <property name="maxIdleTime">3000</property> <property name="maxPoolSize">6</property> <property name="initialPoolSize">3</property> </default-config> <named-config name="mysqlConfig"> <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_demo </property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">root</property> <property name="initialPoolSize">3</property> <property name="maxPoolSize">6</property> <property name="maxIdleTime">1000</property> </named-config> </c3p0-config>
再是测试类了
package com.gqx.C3P0; import static org.junit.Assert.*; import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import org.junit.Test; import com.jdbc.util.JDBCUtil; import com.mchange.v2.c3p0.ComboPooledDataSource; public class C3P0Demo { //硬编码方式使用c3p0 @Test public void test() throws Exception { //创建连接池核心工具类 ComboPooledDataSource dataSource=new ComboPooledDataSource(); //设置连接处参数 dataSource.setJdbcUrl("jdbc:sqlserver://localhost:1433;DataBaseName=Test"); dataSource.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver"); dataSource.setUser("sa"); dataSource.setPassword("123456"); dataSource.setInitialPoolSize(3); dataSource.setMaxPoolSize(6); dataSource.setMaxIdleTime(3000); //从连接池对象中获取连接 Connection connection=null; PreparedStatement statement=null; try { connection=dataSource.getConnection(); String sql="insert into usershop values(?,?,?) "; statement=connection.prepareStatement(sql); statement.setInt(1, 6); statement.setInt(2, 4); statement.setInt(3, 4); statement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(connection, statement); } } //根据配置文件获取连接 @Test public void test2() throws Exception{ //创建连接池核心工具类 //自动加载src下叫做c3p0-config.xml的配置文件中的default-config /** * ComboPooledDataSource(config name)当要换数据库的时候(不适用默认数据库) * 可以以字符串的形式输入在c3p0-config.xml中<named-config name="mysqlConfig">指定的参数 */ ComboPooledDataSource dataSource=new ComboPooledDataSource(); //从连接池对象中获取连接 Connection connection=null; PreparedStatement statement=null; try { connection=dataSource.getConnection(); String sql="insert into usershop values(?,?,?) "; statement=connection.prepareStatement(sql); statement.setInt(1, 2); statement.setInt(2, 3); statement.setInt(3, 4); statement.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(connection, statement); } } }
由此,我可以把原来的JDBCUtil包重新改写一下,换成常用的c3p0技术,如下
package com.jdbc.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.activation.DataSource; import org.omg.CORBA.portable.InputStream; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JDBCUtil { //初始化连接池 private static ComboPooledDataSource dataSource; /* * 静态代码块只加载一次 */ static{ dataSource=new ComboPooledDataSource(); } /** * 获取JDBC连接对象的方法 */ public static Connection getConnection(){ try { return dataSource.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block throw new RuntimeException(e); } } /* * 关闭操作 */ public static void close(Connection con,Statement stmt){ if (stmt!=null) { try { stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } if (con!=null) { try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } } /** * 这是方法的重载 * @param con * @param stmt * @param resultSet */ public static void close(Connection con,Statement stmt,ResultSet resultSet){ if (resultSet!=null) { try { resultSet.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (stmt!=null) { try { stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } if (con!=null) { try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } } }
还有就是网上说:dbcp没有自动的去回收空闲连接的功能,而c3p0有自动回收空闲连接功能。
一般c3p0使用的比较多
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。