数据库连接池

2016/9/4 posted in  Java  

建立数据库连接是一个非常耗时耗资源的行为,在大量并发的情况下,会降低服务器性能。同时,如果连接数超过最大的数据库允许连接值,数据库会直接抛出异常,非常不友好。为了解决上述的问题,我们引入了数据连接池的概念。
数据库连接池类似于线程池,通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去,避免频繁的新建和关闭连接对象

DBCP

DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。同时DBCP也是tomcat所使用的连接池组价。

DBCP的简单使用DEMO

package site.zhanjingbo.HelloDB;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbcp2.BasicDataSource;

public class HelloDBCP {

    static final String DRIVER_NAME = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost:3307/cloud_study?characterEncoding=utf8";
    static final String DB_USER = "root";
    static final String DB_PASSWORD = "";

    public static BasicDataSource ds = null;

    public static void init() {
        ds = new BasicDataSource();
        ds.setDriverClassName(DRIVER_NAME);
        ds.setUsername(DB_USER);
        ds.setUrl(DB_URL);
        ds.setPassword(DB_PASSWORD);
    }

    public static void search() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            conn = ds.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("select username from user");
            while (rs.next()) {
                System.out.println("Hello " + rs.getString("username"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
            }
        }
    }

    public static void main(String[] args) {
        init();
        search();
    }
}

通过上述的demo可见,使用DBCP对数据进行访问实际操作与JDBC并无不同。唯一的区别就是Connection对象的获取是通过BasicDataSource对象来获得而不是DriverManage对象。
注:释放Connection对象同样是调用Connection的close()方法,不过这里的close()方法是被DBCP重写过的,是将连接对象重新放回连接池,而不是释放销毁。

DBCP高级API

为了更好的设置和使用DBCP连接池,使数据库连接池效率更高,DBCP还提供了多个API接口供我们使用。

接口 作用 建议
.setInitialSize() 设置初始化连接数 设置为项目预期访问量
.setMaxTotal() 最大连接数
ds.setMaxWaitMillis() 线程最大等待时间
.setMaxIdle() 最大空闲连接数 与MinIdle相同
.setMinIdle() 最小空闲连接数 与MaxIdle相同

DBCP定期检查

为了保证连接池中的连接都是有效的,我们需要定期的对连接池中的连接进行检查,对失效的连接及时进行关闭。相关API如下:

API 作用 建议
.setTestWhileIdle(true) 是否开启定期检查
.setMinEvictableIdle 最小空闲时间,超过该值被销毁 小于服务器连接失效时间(一般为8小时)
.setTimeBetweenEvictionRunsMillis 检查时间间隔