JDBC_02_连接池
连接池简述
连接池的接口是数据源接口javax.sql.DataSource,实现类由第三方厂商来实现,编程人员只需实现这个接口就可以编写自己的连接池。通过getConnection()获取连接对象
为什么要使用连接池
经测试,用户在每次访问数据库创建连接对象时很耗时,为提高创建连接对象的速度和提高连接对象的使用率,可以使用连接池。
连接池使用原理
连接对象在系统启动时创建一定数量的连接放在连接池中,使用时直接从连接池获取连接对象,使用完毕后,再将连接对象放回连接池供下一个用户使用。
常用两种连接池
c3p0连接池
-
开源的JDBC连接池,有自动回收空闲连接功能。
-
步骤
- 导入jar包c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.12.jar, 如果要连接mysql,还要数据库驱动程序:mysql-connector-java-5.1.37-bin.jar
- 配置xml
- 在src目录下创建配置文件c3p0-config.xml,配置对应参数
- 设置数据库的连接参数:用户名、密码、URL、驱动名
- 设置连接池配置参数:初始连接数、最大连接数、最长等待时间
- Java代码
- 创建数据源的实现类ComboPooledDataSource,使用默认配置或命名配置
- 从连接池中得到连接对象
-
配置文件的要求
常用参数 描述 initialPoolSize 初始连接数,一开始创建多少个连接对象 maxPoolSize 连接池中最大连接数 checkoutTimeout 最长等待时间,等多久没有获取到连接对象,抛出异常 maxIdleTime 最长空闲回收时间,并不是到了这个时间马上回收,看连接池使用情况
使用c3p0的配置文件来配置连接池,配置文件有如下几个要求:
- 文件名:必须叫c3p0-config.xml
- 路径:这个文件必须要放在src目录下,即类路径下
分成两种配置
- 默认配置:在不指定配置名的情况下,默认使用的配置
- 命名配置:可以使用多个配置,通过名字来选择使用哪个配置
- 多个配置的好处:
- 可以使用不同的连接池参数
- 可以指定不同的数据库名,如:db1, db2
- 可以指定不同厂商的数据库,如:Oracle,MySQL
-
API
构造方法 描述 ComboPooledDataSource() 默认的构造方法,使用默认的配置来创建连接池 ComboPooledDataSource(命名配置) 指定使用哪个命名配置来创建连接池 -
配置文件内容:
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
<!-- 默认配置 -->
<default-config>
<!-- 指定数据库驱动 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 指定数据库url -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db1</property>
<!-- 数据库用户名 -->
<property name="user">root</property>
<!-- 对应密码 -->
<property name="password">root</property>
<!-- 初始连接对象数 -->
<property name="initialPoolSize">5</property>
<!-- 最大连接对象数 -->
<property name="maxPoolSize">10</property>
<!-- 最长等待时间 -->
<property name="checkoutTimeout">1000</property>
</default-config>
<!-- 命名配置 -->
<named-config name="otherc3p0">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db2</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
-
Java代码
package com.databasepool; import com.mchange.v2.c3p0.ComboPooledDataSource; import java.sql.*; public class C3p0Demo { public static void main(String[] args) throws SQLException { //1.创建连接池,使用默认配置。ComboPooledDataSource实现了DataSource接口 // ComboPooledDataSource ds = new ComboPooledDataSource(); //2.创建连接池,使用命名配置。ComboPooledDataSource实现了DataSource接口 ComboPooledDataSource ds = new ComboPooledDataSource("otherc3p0"); //命名配置设置的最大连接数为20,模拟有21个用户出现的情况, for (int i = 0; i < 21; i++) { try { Connection connection = ds.getConnection(); System.out.println("第"+(i+1)+"个:"+connection); //模拟用户关闭连接对象后,能否从连接池再次获取连接对象的情况 //if(i==1){connection.close();} } catch (SQLException e) { e.printStackTrace(); } } } }
CRUID连接池
-
Druid是阿里巴巴开发的号称为监控而生的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。如:一年一度的双十一活动,每年春运的抢火车票。
Druid的下载地址:https://github.com/alibaba/druid
DRUID连接池使用的jar包:druid-1.0.9.jar
-
步骤
-
在src目录下创建一个properties文件,设置参数
-
Java代码
- 加载properties文件的内容到Properties对象中
- 使用工厂类,创建DRUID连接池,使用配置文件中的参数
- 从DRUID连接池中取出连接
-
-
在src下新建一个druid.properties的配置文件
#连接数据库的url url=jdbc:mysql://localhost:3306/test #数据库的登录用户和密码 username=root password=root #驱动 driverClassName=com.mysql.jdbc.Driver #初始化连接对象数 initialSize=5 #最大连接对象数 maxActive=10 #最长连接等待时间 maxWait=2000
-
java代码
package com.databasepool; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.util.Properties; public class Demo2Druid { public static void main(String[] args) throws Exception { //1.从类路径下加载配置文件,获取一个输入流。 InputStream inputStream = Demo2Druid.class.getResourceAsStream("/druid.properties"); //2.使用Properties对象的方法将配置文件中属性加载到Properties对象中 Properties properties = new Properties(); //加载了配置文件中所有的属性 properties.load(inputStream); //3.通过druid的工厂类创建连接池 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); //获取10个连接对象 for (int i = 1; i <= 11; i++) { Connection connection = dataSource.getConnection(); System.out.println("第" + i + "个连接对象:" + connection); //第3个连接关闭 if (i==3) { connection.close(); } } } }