对于访问数据库来说,建立连接的代价比较昂贵,因此,建立“连接池”来提高访问的性能。从名字上来理解,“连接池”是一个存放“连接”的“池子”,把连接当做对象或者设备,统一放在一个“池子”里面,以前需要直接访问数据库的地方,现在都改为从这个“池子”里面获取连接来使用。因为“池子”中的连接都是已经预先创建好,可以直接分配给应用使用,因此大大减少了创建新连接所耗费的资源。连接返回后,本次访问将连接交还给“连接池”,以供新的访问使用。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池技术的优势:
1.资源重用
由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。
2.更快的系统响应速度
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
3.新的资源分配手段
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术,几年钱也许还是个新鲜话题,对于目前的业务系统而言,如果设计中还没有考虑到连接池的应用,那么…….快在设计文档中加上这部分的内容吧。
某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。
4.统一的连接管理,避免数据库连接泄漏
在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄漏。
Druid
阿里出品,淘宝和支付宝专用数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。
C3p0
一个开放源代码的JDBC连接池,像Spring、Hiberbate等框架都需要用到c3p0连接池,我们在使用c3p0的时候需要导入第三方的jar包,而且还需要添加配置文件~
它的特性:编码的简单易用;连接的复用;连接的管理
原理是:从pool里获取到的connection,是proxy包装的connection,而对connection的释放或者重用,是pool的管理责任:初始化池大小,维护池的大小(expand或shrink),管理unused、expired、checkout、checkin连接。
真正底层的连接是jdbc自己的连接,而c3p0的管理部分,基本上使用的是synchronized关键字,使用timerTask定时器工作。
DBCP
DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序中使用。
数据库连接池的使用
Druid连接池使用步骤
1、Maven项目导入jar包依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.26</version>
<scope>compile</scope>
</dependency>
2、通过配置文件初始化DataSource,
编写一个properties文件,文件名为druid.properties
3、编码使用
//初始BasicDataSource()数据源
DruidDataSource dataSource=new DruidDataSource();
//从连接池中取用一个连接
dataSource.getConnection();
//释放连接回连接池
ResultSet.close();
PreparedStatement.close();
Connection.close();
public static void main(String[] args) throws IOException {
Properties properties=new Properties();
properties.load(JL_Test.class.getClassLoader().getResourceAsStream("druidLG.properties"));
//初始化BasicDataSource()数据源
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName(properties.getProperty("mysql"));
dataSource.setUrl(properties.getProperty("url"));
dataSource.setUsername(properties.getProperty("username"));
dataSource.setPassword(properties.getProperty("password"));
dataSource.setInitialSize(Integer.parseInt(properties.getProperty("initPoolSize")));
dataSource.setMaxWait(Long.parseLong(properties.getProperty("maxIdleTime")));
dataSource.setMaxActive(Integer.parseInt(properties.getProperty("maxPoolSize")));
try {
//从连接池中获取一个连接
Connection connection=dataSource.getConnection();
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("select * from Student");
while (resultSet.next()){
System.out.println(resultSet.getString("Sname")+" "+resultSet.getString("SID"));
}
//关闭资源
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
C3P0连接池使用步骤
1、Maven项目导入jar包依赖
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
2、在src目录下新建一个名叫 c3p0-config.xml 的文件,注意,必须是这个文件名。
3、编码使用
//通过标识名来创建相应连接池
static ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql");
//从连接池中取用一个连接
dataSource.getConnection();
//释放连接回连接池
ResultSet.close();
PreparedStatement.close();
Connection.close();
public static void main(String[] args) {
//通过标识名来创建相应连接池
ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql");
try {
//从连接池获取连接
Connection connection=dataSource.getConnection();
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("select * from Student");
while (resultSet.next()){
System.out.println(resultSet.getString("Sname")+resultSet.getString("SID"));
}
//关闭连接
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
dbcp连接池使用步骤
1、Maven项目导入jar包依赖:commons-dbcp和commons-pool
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.3</version>
</dependency>
2、通过配置文件初始化DataSource,dbcp用的是BasicDataSource()
编写一个properties文件,文件名为dbcp.properties
3、编码使用
//初始BasicDataSource()数据源
static ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql");
//从连接池中取用一个连接
dataSource.getConnection();
//释放连接回连接池
ResultSet.close();
PreparedStatement.close();
Connection.close();
public static void main(String[] args) {
Properties properties=new Properties();
try {
properties.load(JL_Test.class.getClassLoader().getResourceAsStream("dbcpLG.properties"));
//初始BasicDataSource()数据源
BasicDataSource dataSource=new BasicDataSource();
dataSource.setDriverClassName(properties.getProperty("driver"));
dataSource.setUrl(properties.getProperty("url"));
dataSource.setUsername(properties.getProperty("username"));
dataSource.setPassword(properties.getProperty("password"));
dataSource.setInitialSize(Integer.parseInt(properties.getProperty("initPoolSize")));
dataSource.setMaxWait(Long.parseLong(properties.getProperty("maxIdleTime")));
dataSource.setMaxActive(Integer.parseInt(properties.getProperty("maxPoolSize")));
//从连接池获取连接
Connection connection=dataSource.getConnection();
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("select * from Student");
while (resultSet.next()){
System.out.println(resultSet.getString("Sname")+" "+resultSet.getString("SID"));
}
//关闭连接
resultSet.close();
statement.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}