目录
什么是数据库连接池?
数据库连接池负责分配、管理和释放数据库连接(不用手动连接啦),它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。也是池化技术的体现。
为什么要数据库连接池?
数据库连接和释放这两个过程中十分浪费资源,使用数据库连接池可以减少重复连接和释放的次数,减少资源占用,提高效率。
池化技术
池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。
类似在食堂吃饭和去餐厅吃饭。去餐厅吃饭每道菜都是现点现做,比较浪费时间;去食堂吃饭饭菜都是准备好了,只需现点,不用现做。
最小连接数(常用连接数)
最小连接数是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
最大连接数
是连接池能申请的最大连接数。
最小连接数(常用连接数)和最大连接数的区别
- 最小连接数是预先准备好的连接数,最大连接数是总共能连接的数量。
- 连接数<最小连接数:直接使用,不用建立连接
- 最小连接数<连接数<最大连接数:大于最小连接数的部分要去与数据库建立连接
- 最大连接数<连接数:大于最大连接数部分要排队等待(设置超时时间),等待超时会连接失败
最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
举例
比如说去食堂吃饭,食堂准备了100个人的就餐位置(最小连接数);但是今天来了160个人,于是食堂员工从其他地方借来了可以够50人用的桌椅,加上原来的100个,食堂总共有够150人用的位置(最大连接数);由于食堂就这么大,已经不能再添加桌椅了,于是剩下10个人只好等了。为了不造成拥挤,食堂只让等10分钟(超时时间)。过了一会儿,食堂只剩80人吃饭了,但是考虑到等会可能还有人来,借来的桌椅并没有直接还回去(等待重复使用)。午餐时间过去一个小时之后(空闲超时),已经不会有人再来吃午餐了,于是食堂员工把借来的够50人用的桌椅还回去了(释放)。
DBCP连接池
需要的jar包
commons-dbcp2-2.9.0
commons-pool2-2.11.1
配置文件
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=123456
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk
#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true
#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=
#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
工具类
public class JdbcUtils_DBCP {
private static DataSource dataSource = null;
static {
try {
InputStream resourceAsStream = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
//创建数据源 工厂模式
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();//从数据源获取连接而
}
//释放连接
public static void release(Connection conn, Statement st, ResultSet rs){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
C3P0连接池
需要的jar包
c3p0-0.9.5.5
mchange-commons-java-0.2.20
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--
c3p0的缺省(默认)配置
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是c3p0的缺省(默认)配置
-->
<default-config>
<property name="user">root</property>
<property name="password">123456</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&characterEncoding=utf8&useSSL=false</property>
<property name="initialPoolSize">2</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">2</property>
</default-config>
<!--
c3p0的命名配置
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource(“MySQL”);”这样写就表示使用的是c3p0的name为MySQL的配置
同理可以配置多个数据库,如oracle等
-->
<named-config name="MySQL">
<property name="user">root</property>
<property name="password">root</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3308/database?characterEncoding=UTF-8&useOldAliasMetadataBehavior=true</property>
<property name="initialPoolSize">2</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">2</property>
</named-config>
</c3p0-config>
工具类
public class JdbcUtils_C3P0 {
private static DataSource dataSource = null;
static {
try {
//创建数据源 工厂模式
//不写参数使用默认数据源
dataSource = new ComboPooledDataSource("MySQL");
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();//从数据源获取连接而
}
//释放连接
public static void release(Connection conn, Statement st, ResultSet rs){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}