-
-
C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。
1 @Test 2 public void testGetConnection() throws Exception { 3 // 获取数据库连接池的实例化对象 4 ComboPooledDataSource cpds = new ComboPooledDataSource() ; 5 6 // 设置连接需要的基本信息 7 cpds.setDriverClass("com.mysql.cj.jdbc.Driver"); 8 cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"); 9 cpds.setUser("root"); 10 cpds.setPassword("password"); 11 // 设置与管理数据库连接池相关的属性 12 // 设置连接池中初始连接的数量 13 cpds.setInitialPoolSize(10); 14 15 // 获取数据库连接 16 Connection conn = cpds.getConnection() ; 17 System.out.println(conn); 18 }
实现的方式二:配置文件的方式
配置文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <c3p0-config> 3 <named-config name="myc3p0"> 4 <!-- 提供用于获取连接的基本信息 --> 5 <property name="driverClass">com.mysql.cj.jdbc.Driver</property> 6 <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8</property> 7 <!-- 主机号与端口号为本机3306时,可以省略:即jdbc:mysql:///test?serverTimezone=GMT%2B8 --> 8 <property name="user">root</property> 9 <property name="password">password</property> 10 11 <!-- 管理数据库连接池的基本信息 --> 12 <!-- 当数据库连接池的连接不够时,c3p0 一次性向数据库服务器申请的连接数 --> 13 <property name="acquireIncrement">5</property> 14 <!-- c3p0数据库连接池中初始化时的连接数 --> 15 <property name="initialPoolSize">10</property> 16 17 <!-- c3p0数据库连接池中维护的最少连接数 --> 18 <property name="minPoolSize">10</property> 19 <!-- c3p0数据库连接池中维护的最多连接数 --> 20 <property name="maxPoolSize">100</property> 21 22 <!-- c3p0数据库连接池中最多维护的Statement的个数 --> 23 <property name="maxStatements">50</property> 24 <!-- 每个连接中最多可以使用的Statement的个数 --> 25 <property name="maxStatementsPerConnection">2</property> 26 </named-config> 27 </c3p0-config>
说明:
1. 配置文件的名称要求必须为 “c3p0-config.xml” ;
2. 第 3 行的 <named-config name="myc3p0"> 主要用于设置该配置文件的名称 ;
3. 提供用于获取连接的基本信息的 “name” 可以参考方式一中的方法名,注意不能出现错误。
1 @Test 2 public void testGetConnection2() throws Exception { 3 // 实例化数据库连接池的对象并传入配置文件 4 ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0"); 5 // 获取数据库连接 6 Connection conn = cpds.getConnection() ; 7 System.out.println("myc3p0:" + conn); 8 }
DBCP数据连接池技术:
方式一:
1 @Test 2 public void testGetConnection() throws Exception { 3 // 获取DBCP数据库连接池的实例化对象 4 BasicDataSource bds = new BasicDataSource() ; 5 6 // 设置连接需要的基本信息 7 bds.setDriverClassName("com.mysql.cj.jdbc.Driver"); 8 bds.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"); 9 bds.setUsername("root"); 10 bds.setPassword("password"); 11 // 设置其他与数据库连接池管理的相关信属性 12 bds.setInitialSize(10); 13 14 // 获取数据库连接 15 Connection conn = bds.getConnection() ; 16 System.out.println(conn); 17 }
dbcp连接池常用基本配置属性:
属性 | 默认值 | 说明 |
---|---|---|
initialSize | 0 | 连接池启动时创建的初始化连接数量 |
maxActive | 8 | 连接池中可同时连接的最大的连接数 |
maxIdle | 8 | 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制 |
minIdle | 0 | 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接。该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大。 |
maxWait | 无限制 | 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待 |
poolPreparedStatements | false | 开启池的Statement是否prepared |
maxOpenPreparedStatements | 无限制 | 开启池的prepared 后的同时最大连接数 |
minEvictableIdleTimeMillis | 连接池中连接,在时间段内一直空闲, 被逐出连接池的时间 | |
removeAbandonedTimeout | 300 | 超过时间限制,回收没有用(废弃)的连接 |
removeAbandoned | false | 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收 |
方式二:使用配置文件:
配置文件如下:
1 driverClassName=com.mysql.cj.jdbc.Driver 2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8 3 username=root 4 password=password
1 @Test 2 public void testGetConnection2() throws Exception{ 3 // 方式一:使用类的加载器 4 // InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); 5 // 方式二:普通的文件流(当前工程下) 6 FileInputStream is = new FileInputStream(new File("src/dbcp.properties")) ; 7 Properties pros = new Properties() ; 8 pros.load(is) ; 9 DataSource ds = BasicDataSourceFactory.createDataSource(pros) ; 10 11 Connection conn = ds.getConnection() ; 12 System.out.println(conn); 13 }
Druid数据库连接池技术:
配置文件的方式:
1 driverClassName=com.mysql.cj.jdbc.Driver 2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8 3 username=root 4 password=password
1 @Test 2 public void testGetConnection() throws Exception { 3 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ; 4 Properties pros = new Properties() ; 5 pros.load(is); 6 DataSource ds = DruidDataSourceFactory.createDataSource(pros) ; 7 Connection conn = ds.getConnection() ; 8 System.out.println(conn); 9 }
详细配置参数
缺省 | 说明 | |
---|---|---|
name | 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this) | |
url | 连接数据库的url,不同数据库不一样。例如:mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 连接数据库的用户名 | |
password | 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。 | |
driverClassName | 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下) | |
initialSize | 0 | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 |
maxActive | 8 | 最大连接池数量 |
maxIdle | 8 | 已经不再使用,配置了也没效果 |
minIdle | 最小连接池数量 | |
maxWait | 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 | |
poolPreparedStatements | false | 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 |
maxOpenPreparedStatements | -1 | 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 |
validationQuery | 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。 | |
testOnBorrow | true | 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 |
testOnReturn | false | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 |
testWhileIdle | false | 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 |
timeBetweenEvictionRunsMillis | 有两个含义: 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据,详细看testWhileIdle属性的说明 | |
numTestsPerEvictionRun | 不再使用,一个DruidDataSource只支持一个EvictionRun | |
minEvictableIdleTimeMillis | ||
connectionInitSqls | 物理连接初始化的时候执行的sql | |
exceptionSorter | 根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接 | |
filters | 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall | |
proxyFilters |
总结:利用以上三种数据库连接池技术实现数据库的工具类"JDBCUtil“
1 package edu.cn.ahpu4.util; 2 3 import java.io.InputStream; 4 import java.sql.Connection; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.Properties; 9 import javax.sql.DataSource; 10 import org.apache.commons.dbcp.BasicDataSourceFactory; 11 import com.alibaba.druid.pool.DruidDataSourceFactory; 12 import com.mchange.v2.c3p0.ComboPooledDataSource; 13 14 /** 15 * 16 * @Description 操作数据库的工具类 17 * @author XiaoFeng Email:1431230065@qq.com 18 * @version 19 * @date 2020年8月20日下午4:02:59 20 * 21 */ 22 public class JDBCUtil { 23 24 /*** 25 * 26 * @Description 使用C3P0技术获取数据库连接 27 * @author XiaoFeng 28 * @date 2020年8月20日下午4:12:17 29 * @return 数据库连接 30 * @throws SQLException 31 */ 32 // 实例化数据库连接池的对象并传入配置文件 33 private static ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0"); 34 public static Connection getConnection1() throws SQLException { 35 // 获取并返回数据库连接 36 return cpds.getConnection() ; 37 } 38 39 /*** 40 * 41 * @Description 使用DBCP技术获取数据库连接 42 * @author XiaoFeng 43 * @date 2020年8月26日上午11:16:47 44 * @return 45 * @throws Exception 46 */ 47 private static DataSource ds2 ; 48 static { 49 try { 50 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); 51 Properties pros = new Properties() ; 52 pros.load(is) ; 53 // 创建一个DBCP数据库连接池 54 ds2 = BasicDataSourceFactory.createDataSource(pros) ; 55 } catch (Exception e) { 56 e.printStackTrace(); 57 } 58 } 59 public static Connection testGetConnection2() throws Exception{ 60 Connection conn = ds2.getConnection() ; 61 return conn ; 62 } 63 64 /*** 65 * 66 * @Description 使用druid技术获取数据库连接 67 * @author XiaoFeng 68 * @date 2020年8月26日上午11:38:41 69 * @return 70 * @throws Exception 71 */ 72 private static DataSource ds3 ; 73 static { 74 try { 75 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ; 76 Properties pros = new Properties() ; 77 pros.load(is); 78 ds3 = DruidDataSourceFactory.createDataSource(pros) ; 79 } catch (Exception e) { 80 e.printStackTrace(); 81 } 82 } 83 public static Connection testGetConnection3() throws SQLException{ 84 Connection conn = ds3.getConnection() ; 85 return conn ; 86 } 87 88 /*** 89 * 90 * @Description 关闭资源 91 * @author XiaoFeng 92 * @date 2020年8月20日下午4:15:35 93 * @param conn connection资源 94 * @param ps PreparedStatement资源 95 */ 96 public static void closeResource(Connection conn,Statement ps) { 97 if (ps != null) { 98 try { 99 ps.close(); 100 } catch (SQLException e) { 101 e.printStackTrace(); 102 } 103 } 104 if (conn != null) { 105 try { 106 conn.close(); 107 } catch (SQLException e) { 108 e.printStackTrace(); 109 } 110 } 111 } 112 113 /*** 114 * 115 * @Description 关闭资源 116 * @author XiaoFeng 117 * @date 2020年8月20日下午5:39:25 118 * @param conn 119 * @param ps 120 * @param rs ResultSet资源 121 */ 122 public static void closeResource(Connection conn,Statement ps,ResultSet rs) { 123 if (ps != null) { 124 try { 125 ps.close(); 126 } catch (SQLException e) { 127 e.printStackTrace(); 128 } 129 } 130 if (conn != null) { 131 try { 132 conn.close(); 133 } catch (SQLException e) { 134 e.printStackTrace(); 135 } 136 } 137 if(rs != null) { 138 try { 139 rs.close(); 140 } catch (SQLException e) { 141 e.printStackTrace(); 142 } 143 } 144 } 145 }