数据库连接的建立和关闭是极耗费系统资源的操作,频繁的打开、关闭连接,将造成系统性能下降。数据库连接池的解决方案是:当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接组成一个连接池。每次应用程序请求数据库连接时,无需重新打开连接,而是从连接池中取出已有的连接使用,使用完不再关闭数据库连接,而是直接将连接归还给连接池。
jdbc的数据库连接池使用java.sql.DataSource来表示,DataSource通常被称为数据源或连接池。
1、DBCP连接池
DBCP是Apache软件基金组织下的开源连接池实现该连接池依赖该组织下的另一个开源系统common-pool,Tomcat的连接池,正是采用该连接池实现的。
<!-- DBCP依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.1</version>
</dependency>
2、C3P0连接池
C3P0数据源性能更胜一筹,Hibernate推荐使用该连接池。该连接池,不仅可以自动清理不再使用的connection,还可以statement和ResultSet
<!-- c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.3</version>
</dependency>
3、druid连接池
druid是阿里开源平台上一个数据库连接池实现,它结合了DBCP、C3P0等连接池的优点,同时加入了日志监控,可以很好的监控连接池连接和SQL的执行情况,可以说是针对监控而生的数据库连接池。
使用druid好处:
① 监控数据库访问性能
② 高效、功能强大、扩展性好
③ 数据库密码加密,直接把数据库密码写在配置文件中是很危险的行为。
④ sql执行日志,druid提供了不同的logFilter,可以支持common-logging,log4j和jdklog,可以按需选择logFilter,监控应用的数据库访问情况。
首先引入依赖
<!--druid依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.14</version>
</dependency>
springboot中加入配置文件即可
@Configuration
public class DataSourceConfiguration {
@Value("${ftcs.jdbc.driver}")
private String driverClassName;
@Value("${ftcs.jdbc.url}")
private String jdbcUrl;
@Value("${ftcs.jdbc.username}")
private String dbUserName;
@Value("${ftcs.jdbc.password}")
private String dbPwd;
@Value("${ftcs.jdbc.maxActive}")
private Integer maxActive;
@Value("${ftcs.jdbc.initialSize}")
private Integer initialSize;
@Value("${ftcs.jdbc.minIdle}")
private Integer minIdle;
@Bean(initMethod = "init", destroyMethod = "close")
public DruidDataSource dataSource() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(jdbcUrl);
druidDataSource.setUsername(dbUserName);
druidDataSource.setPassword(dbPwd);
druidDataSource.setFilters("stat");
druidDataSource.setMaxActive(maxActive);
druidDataSource.setInitialSize(initialSize);
druidDataSource.setMinIdle(minIdle);
druidDataSource.setMaxWait(60000);
druidDataSource.setTimeBetweenEvictionRunsMillis(3000);
druidDataSource.setMinEvictableIdleTimeMillis(300000);
druidDataSource.setValidationQuery("SELECT 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
return druidDataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws SQLException {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
sqlSessionFactoryBean.setDataSource(dataSource());
return sqlSessionFactoryBean;
}
@Bean
public SqlSessionTemplate sqlSessionTemplate() throws Exception {
return new SqlSessionTemplate(sqlSessionFactory().getObject());
}
}
上面说了,把密码写入配置文件是很危险的,下面介绍如何对密码加密
找到本地druid.jar目录,执行如下命令,若pwd=root得到私钥、公钥及加密后的密码如下图,可以看到每次对同一个密码加密生成的密文都是不一样的,使用原理:私钥+明文密码=加密密码;加密密码+公钥=明文密码
java -cp druid-1.1.14.jar com.alibaba.druid.filter.config.ConfigTools root
以下是druid的配置信息,密码加密方式重点关注最后两行,尤其最后一行config.decrypt=true一定要设置
<!-- 基于Druid数据库链接池的数据源配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性driverClassName、 url、user、password -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<!-- 通常来说,只需要修改initialSize、minIdle、maxActive -->
<property name="initialSize" value="2" />
<property name="minIdle" value="2" />
<property name="maxActive" value="30" />
<property name="testWhileIdle" value="false" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="5000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="30000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 解密密码必须要配置的项 -->
<property name="filters" value="config" />
<property name="connectionProperties" value="druid.stat.slowSqlMillis=5000;config.decrypt=true;config.decrypt.key=${jdbc.publickey}"/>
</bean>
配置文件jdbc.properties中的内容为
jdbc.password=gB12rOYlciO/4+6kqGdnJ+Jwn2Y0CXhvRvc2uhtnNu2fcKi+EwiedSVCeQSnSCI8fCCd6mztRI/XUuyP5W/C1A==
jdbc.publickey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnTXma8ZAJvv23pINMg5ZW2Te13BbQNmlQYk+jc52QN3Gpi3HWdyHTWnOiFQBrvx3SPhMoE/MyryfaH2LRMZgcCAwEAAQ==