经常使用Java数据库链接池

概述

在这里所谓的数据库链接是指经过网络协议与数据库服务之间创建的TCP链接。一般,与数据库服务进行通讯的网络协议无需由应用程序自己实现,缘由有三:html

  1. 实现复杂度大,须要充分理解和掌握相应的通讯协议。
  2. 代码难以复用,每一个应用程序都须要独立实现一套对应的网络协议(不一样公司之间,同一公司的不一样技术栈之间难以复用实现相同协议的代码)
  3. 性能难以保证,不一样的网络协议实现可能存在巨大的性能差距。

正由于如此,因此现实的实现方式是:
首先,定义网络协议标准,这样只要支持这个标准协议的数据库就可使用相应的客户端与之通讯。
其次,将实现这个标准协议的客户端独立为一个通讯库,这样只须要在应用程序中使用这个通讯组件库就能够方便地实现与数据库进行交互。java

一般,咱们将实现了网络协议的通讯库称之为数据库驱动程序。固然,对于不一样的编程语言,须要对应编写相应的数据库驱动实现。以与关系型数据库通讯为例,在Java中实现的驱动程序为JDBC,Python中的驱动程序为MySQLdb。
因为经过TCP与数据库创建网络链接的代价很是高昂,并且耗时(TCP创建链接须要“三次握手”,断开链接须要“四次握手”)。因此在实践中一般不直接单独使用链接进行数据库操做,而是使用链接池的方式,这主要是处于如下两方面的考虑:mysql

  1. 应用程序自己须要更低的响应时间,若是每次数据库操做都须要通过“创建链接->通讯(增删改查)->断开链接”这个过程,那么势必会致使响应延时的增长。
  2. 避免服务器资源被耗尽,随着业务量的增大,对应的数据库操做必然会随之增长,若是对客户端的链接数不加以控制,可能会致使数据库服务器的CPU和内存资源被大量的网络链接快速耗尽,这样将致使服务不可用。

在Java中使用得比较流行的数据库链接池主要有:DBCP,c3p0,druid。
另外,不论使用什么链接池,低层都是使用JDBC链接,即:在应用程序中都须要加载JDBC驱动程序。git

DBCP

https://commons.apache.org/proper/commons-dbcp/index.html
DBCP是Apache下独立的数据库链接池组件,在Tomcat中使用的链接池组件就是DBCP,支持JDBC3,JDBC4。关于更多JDBC版本信息,详见:https://en.wikipedia.org/wiki/Java_Database_Connectivitygithub

c3p0

http://www.mchange.com/projects/c3p0/
使用c3p0有多种方式,如:既能够直接使用API方式配置c3p0,也能够经过文件的方式进行配置,配置文件有2种形式:properties或xml文件。sql

<dependencies>
    <!-- JDBC驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.42</version>
    </dependency>
    
    <!-- c3p0链接池 -->
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.2</version>
    </dependency>

    <!-- 日志组件 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
</dependencies>

1.使用Java API方式配置c3p0数据库

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "com.mysql.jdbc.Driver" ); //loads the jdbc driver            
cpds.setJdbcUrl("jdbc:mysql://host:port/db");
cpds.setUser("username");                                  
cpds.setPassword("password");                                  
    
cpds.setMinPoolSize(5);                                     
cpds.setMaxPoolSize(20);
cpds.setAcquireIncrement(5);

// 直接从链接池中获取链接
Connection conn = cpds.getConnection();
query(conn);

// 关闭链接池
// cpds.close();

2.使用文件方式配置c3p0
2.1 使用c3p0.properties文件进行配置
须要在classpath路径下添加配置文件:c3p0.properties,内容以下:apache

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://host:port/db
c3p0.user=root
c3p0.password=
c3p0.minPoolSize=5
c3p0.maxPoolSize=20
c3p0.acquireIncrement=5

在应用程序中只须要直接建立ComboPooledDataSource对象便可(c3p0会自动从classpath加载c3p0.properties中的配置信息):编程

ComboPooledDataSource cpds = new ComboPooledDataSource();
Connection conn = cpds.getConnection();
query(conn);
cpds.close();

注意: 使用c3p0.properties做为配置文件时,每一个参数的name前缀必须是“c3p0”,如:“c3p0.driverClass=com.mysql.jdbc.Driver”。api

2.2 使用c3p0-config.xml文件进行配置
使用这种方式会比使用c3p0.properties更加高级,支持配置多个数据源,一样须要在classpath路径下添加文件:c3p0-config.xml。

<c3p0-config>
    <!-- 默认数据源 -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://host:port/db</property>
        <property name="user">username</property>
        <property name="password">password</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
        <property name="acquireIncrement">5</property>
    </default-config>

    <!-- 定义带名称的数据源 -->
    <named-config name="myDataSource">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test_jdbc</property>
        <property name="user">root</property>
        <property name="password"></property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
        <property name="acquireIncrement">5</property>
    </named-config>
</c3p0-config>
// 使用默认数据源
// ComboPooledDataSource cpds = new ComboPooledDataSource();

// 使用指定名称的数据源
ComboPooledDataSource cpds = new ComboPooledDataSource("myDataSource");
Connection conn = cpds.getConnection();
query(conn);
cpds.close();

3.c3p0经常使用配置

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://host:port/db</property>
        <property name="user">username</property>
        <property name="password">password</property>

        <!-- 链接池初始化时建立的链接数,默认值: 3 -->
        <property name="initialPoolSize">3</property>
        <!-- 链接池保持的最小链接数,默认值: 3 -->
        <property name="minPoolSize">3</property>
        <!-- 链接池中拥有的最大链接数,若是得到新链接时会使链接总数超过这个值则不会再获取新链接,而是等待其余链接释放。 -->
        <property name="maxPoolSize">15</property>
        <!-- 链接池在无空闲链接可用时一次性建立的新数据库链接数,默认值: 3 -->
        <property name="acquireIncrement">3</property>
        <!-- 链接的最大空闲时间,若是超过这个时间,某个数据库链接尚未被使用,则会断开掉这个链接。为0,则永远不会断开链接。默认值: 0,单位: 秒 -->
        <property name="maxIdleTime">0</property>
        <!-- 链接测试语句 -->
        <property name="preferredTestQuery">select 1</property>
        <!-- 用来配置测试空闲链接的间隔时间。能够用来解决MySQL 8小时断开链接的问题。由于它保证链接池会每隔必定时间对空闲链接进行一次测试,从而保证有效的空闲链接能每隔必定时间访问一次数据库,将MySQL8小时无会话的状态打破。为0则不测试。默认值:0,单位: 秒 -->
        <property name="idleConnectionTestPeriod">30</property>
        <!-- 链接池在得到新链接失败时重试的次数,若是小于等于0则无限重试直至链接得到成功。默认值: 30 -->
        <property name="acquireRetryAttempts">30</property>
        <!-- 链接池在得到新链接时的间隔时间,默认值: 1000,单位: 毫秒 -->
        <property name="acquireRetryDelay">1000</property>
    </default-config>
</c3p0-config>

druid

https://github.com/alibaba/druid
阿里开源的druid不单纯是一个链接池,还添加了监控功能,目前已是很是受推崇的链接池组件,详细配置参数请参考官网。

固然,还存在一些其余的数据库链接池实现,例如:Tomcat本身就实现了一个链接池组件,根据官方的说法,这个链接池正是为了在Tomcat中替换DBCP,详见:https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

【参考】
http://josh-persistence.iteye.com/blog/2229929 深刻浅出数据库链接池c3p0

相关文章
相关标签/搜索