Druid 连接池 配置 (java无框架)

为什么必须使用数据库连接池:

1.普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接时都要将Connection加载到内存中,再验证用户名和密码。需要数据库连接的时候,就向数据库要求一个,执行完后就断开连接,这样的方式会消耗大量的资源和时间,数据库的连接资源并没有得到很好的重复利用。若是同时有几百人甚至几千人在线,频繁地进行数据库连接操作,这将会占用很多的系统资源,严重的甚至会造成服务器的奔溃。

2.使用DriverManager方式获取JDBC数据库连接,每一次数据库连接,操作完会后都要断开,否则,如果程序出现异常而未能关闭,将会导致数据库系统内存泄漏,最终将导致重启数据库。

3.同时,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾忌地分配出去,若果连接过多,也可能导致内存泄漏,服务器奔溃。

使用数据库连接池,可以避免以上几种问题。数据库连接池允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接漏洞;连接池的数据库连接数受最大连接数和最小连接数控制,因此不会出现连接过多内存泄漏的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

/**
*
* @date 2017年6月28日 下午10:31:49
*/
public class DBPoolHelper {

/** 默认配置文件名 */
public static String confile = "druid.properties";
/** 配置文件 */
public static Properties p = null;
/** 唯一dateSource,保证全局只有一个数据库连接池 */
public static DataSource dataSource = null;

static {
p = new Properties();
InputStream inputStream = null;
try {
// java应用 读取配置文件
inputStream = DBPoolHelper.class.getClassLoader().getResourceAsStream(confile);
p.load(inputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
// ignore
}
} // end finally

try {
//通过工厂类获取DataSource对象
dataSource = DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
logger.error("获取连接异常 ", e);
}

} // end static



/**
* 获取连接
*
* @return
*/
public static Connection getConnection() throws SQLException {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new SQLException("获取连接时异常", e);
}

}


/**
* 关闭连接
*
* @param con
* @date : 2017-10-16 10:08:10
*/
public static void close(Connection con) throws SQLException {
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {
throw new SQLException("关闭连接时异常", e);
}finally {
try {
if (con != null) {
con.close();
}

} catch (SQLException e) {
throw new SQLException("关闭连接时异常", e);
}
}
} // end method


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/crawler?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
username=admin
password=admin


# 配置参数,让ConfigFilter解密密码
#connectionProperties=config.decrypt=true;config.decrypt.key=xxxx

# 监控统计拦截的filters
filters=stat

# 初始化时建立物理连接的个数,初始化发生在显示调用init方法,或者第一次getConnection时
initialSize=1
# 最大连接池数量
maxActive=10
# 最小连接池数量
minIdle:1
# 获取连接等待超时的时间,单位毫秒
maxWait=60000

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
# 有两个含义:1) Destroy线程会检测连接的间隔时间 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
timeBetweenEvictionRunsMillis=60000
# 一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis=300000

# 用来检测连接是否有效
validationQuery=SELECT 1
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
testWhileIdle=true
# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnBorrow=false
# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnReturn=false

# 是否缓存preparedStatement,也就是PSCache
poolPreparedStatements=true

maxPoolPreparedStatementPerConnectionSize=200

References

[1] druid简单教程
[2] 淘宝druid数据库连接池使用示例
[3] Druid连接池配置(java无框架)
[4] 使用数据库连接池获取JDBC数据库