一. 连接池的功能对比 :
1:性能方面 hikariCP>druid>tomcat-jdbc>dbcp>c3p0 。
hikariCP的高性能得益于最大限度的避免锁竞争。
2:druid功能最为全面,sql拦截等功能,统计数据较为全面,具有良好的扩展性。
3:综合性能,扩展性等方面,可考虑使用druid或者hikariCP连接池。
4:可开启prepareStatement缓存,对性能会有大概20%的提升。
功能 | dbcp | druid | c3p0 | tomcat-jdbc | HikariCP |
是否支持PSCache | 是 | 是 | 是 | 否 | 否 |
监控 | jmx | jmx/log/http | jmx,log | jmx | jmx |
扩展性 | 弱 | 好 | 弱 | 弱 | 弱 |
sql拦截及解析 | 无 | 支持 | 无 | 无 | 无 |
代码 | 简单 | 中等 | 复杂 | 简单 | 简单 |
更新时间 | 2015.8.6 | 2015.10.10 | 2015.12.09 | 2015.12.3 | |
特点 | 依赖于common-pool | 阿里开源,功能全面 | 历史久远,代码逻辑复杂,且不易维护 | 优化力度大,功能简单,起源于boneCP | |
连接池管理 | LinkedBlockingDeque | 数组 | FairBlockingQueue | threadlocal+CopyOnWriteArrayList |
- 由于boneCP被hikariCP替代,并且已经不再更新,boneCP没有进行调研。
- proxool网上有评测说在并发较高的情况下会出错,proxool便没有进行调研。
- druid的功能比较全面,且扩展性较好,比较方便对jdbc接口进行监控跟踪等。
- c3p0历史悠久,代码及其复杂,不利于维护。并且存在deadlock的潜在风险。
二 . 将druid连接池 更换为 c3p0连接池 :
步骤 :
1. pom.xml 当中的依赖 更换 :
<!-- 注释 原 druid连接池依赖 -->
<!--<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>-->
<!-- c3p0 连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
2. yml 配置文件当中的参数 设置 :
原 druid 的yml配置 :
spring:
# 数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: oracle.jdbc.OracleDriver
url: 自己需要连的oracle连接地址链接
username: root
password: root
druid:
# 数据库类型
db-type: oracle
# 初始化大小
initial-size: 5
# 最小连接数
min-idle: 5
# 最大连接数
max-active: 200
# 等待超时的时间
# max-wait: 6000
# 检测需要关闭的空闲连接的间隔时间(单位:毫秒)
time-between-eviction-runs-millis: 60000
# 连接在连接池中最小生存的时间(单位:毫秒)
min-evictable-idle-time-millis: 100000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: ${spring.datasource.druid.max-active}
# 配置监控统计拦截的filters
filters: stat
# connectProperties属性
connect-properties: {
druid.stat.mergeSql: true,
druid.stat.slowSqlMillis: 5000
}
# connection-init-sqls: ["SET NAMES utf8mb4;"]
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
# 允许访问druid监控的IP 留空表示允许所有
allow: 127.0.0.1
reset-enable: false
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: # 自己需要连的mysql连接地址链接
username: root
password: root
druid:
# 数据库类型
db-type: mysql
# 初始化大小
initial-size: 5
# 最小连接数
min-idle: 5
# 最大连接数
max-active: 200
# 等待超时的时间
# max-wait: 6000
# 检测需要关闭的空闲连接的间隔时间(单位:毫秒)
time-between-eviction-runs-millis: 60000
# 连接在连接池中最小生存的时间(单位:毫秒)
min-evictable-idle-time-millis: 100000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: ${spring.datasource.druid.max-active}
# 配置监控统计拦截的filters
filters: stat
# connectProperties属性
connect-properties: {
druid.stat.mergeSql: true,
druid.stat.slowSqlMillis: 5000
}
# connection-init-sqls: ["SET NAMES utf8mb4;"]
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
# 允许访问druid监控的IP 留空表示允许所有
allow: 127.0.0.1
reset-enable: false
现 c3p0 的yml配置 :
spring:
# 数据源
datasource:
driver-class-name: oracle.jdbc.OracleDriver
url: 自己需要连的oracle连接地址链接
username: root
password: root
c3p0:
minPoolSize: 5
maxPoolSize: 200
maxIdleTime: 100000
maxStatements: 0
acquireIncrement: 0
idleConnectionTestPeriod: 60
testConnectionOnCheckout: true
preferredTestQuery: SELECT 1 FROM DUAL
ds1: oracle.jdbc.OracleDriver
driver-class-name: com.mysql.cj.jdbc.Driver
url: # 自己需要连的mysql连接地址链接
username: root
password: root
c3p0:
minPoolSize: 5
maxPoolSize: 200
maxIdleTime: 100000
maxStatements: 0
acquireIncrement: 0
idleConnectionTestPeriod: 60
testConnectionOnCheckout: true
preferredTestQuery: SELECT 1 FROM DUAL
注意 : driver-class-name 我这里没有改 是因为 我当中的项目需要druid 与 c3p0 兼容使用 , 要是单独使用 c3p0 需要 使用 它对应的属性名称 driver-class 包括 其他账号 、密码的 属性名称 等等.
3. .java 配置类当中的 加载扫描 @Bean 加入 IoC容器 :
/**
* 配置多数据源
*/
@Configuration
//@EnableConfigurationProperties({DataSourceProperties.class})
public class DatasourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.ds1")
public DataSourceProperties ds1SourceProperties() {
return new DataSourceProperties();
}
}
@Bean
@ConfigurationProperties("spring.datasource.c3p0")
public ComboPooledDataSource datasource(){
return dataSourceProperties().initializeDataSourceBuilder()
.type(ComboPooledDataSource.class).build();
}
@Bean
@ConfigurationProperties("spring.ds1.c3p0")
public ComboPooledDataSource ds1(){
return ds1SourceProperties().initializeDataSourceBuilder()
.type(ComboPooledDataSource.class).build();
}
/**
* 如果还有数据源,在这继续添加 DataSource Bean
* */
@Bean
@Primary
@DependsOn({"datasource", "ds1"})
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = MapUtils.newHashMap();
targetDataSources.put("datasource", datasource());
targetDataSources.put("ds1", ds1());
// 还有数据源,在targetDataSources中继续添加
dynamicDataSource.setDefaultTargetDataSource(datasource());
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.afterPropertiesSet();
return dynamicDataSource;
}
@Bean(name = "transactionManager")
@Order
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("datasource") DataSource ds){
return new DataSourceTransactionManager(ds);
}
@Bean(name = "ds1TransactionManager")
@Order
public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1") DataSource ds){
return new DataSourceTransactionManager(ds);
}
}
以上配置示例仅供参考 , 希望对大家有所帮助 , 略有不足之处 , 请多多包涵 !!!