什么是连接池?
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。
这种把连接“汇集”起来的技术基于这样的一个事实:对于大多数应用程序,当它们正在处理通常需要数毫秒完成的事务时,仅需要能够访问JDBC连接的 1 个线程。当不处理事务时,这个连接就会闲置。相反,连接池允许闲置的连接被其它需要的线程使用。
事实上,当一个线程需要用 JDBC 对一个 GBase 或其它数据库操作时,它从池中请求一个连接。当这个线程使用完了这个连接,将它返回到连接池中,这样这就可以被其它想使用它的线程使用。
当连接从池中“借出”,它被请求它的线程专有地使用。从编程的角度来看,这和用户的线程每当需要一个 JDBC 连接的时候调用DriverManager.getConnection()是一样的,采用连接池技术,可通过使用新的或已有的连接结束线程。
说白了,其实连接池就是一个集合,用于存放数据库连接对象。我们一次性创建很多个与数据库建立好连接的connection对象存放在内存中,形成了一个连接对象的集合,这就是连接池。
连接池意在解决的问题是什么?
1、减少连接创建时间
我们都知道,在网络通讯中,建立通讯连接是非常消耗资源的。如果每次访问数据库就创建一个新的Connection对象,这非常好资源。特别是当我们的服务器并发用户数量达到较大规模时,例如服务器资源甚至可能被消耗殆尽。这造成了服务器性能的一个瓶颈。使用连接池就可以解决这个性能问题。
2、简化的编程模式
当使用连接池时,每一个单独的线程能够像创建了一个自己的 JDBC连接一样操作,允许用户直接使用JDBC编程技术。
3、受控的资源使用
如果用户不使用连接池,而是每当线程需要时创建一个新的连接,那么用户的应用程序的资源使用会产生非常大的浪费并且可能会导致高负载下的异常发生。
连接池又是如何去解决这个问题的呢?
当我们需要访问数据库时,我们不需要再去创建连接对象并建立连接,而是直接去连接池里取已经建立好数据库连接的Connection对象。当使用完后,我们并不将connection对象销毁,而是将其放回连接池中。这样,我们就避免了不断创建Connection对象并建立连接的不必要的资源消耗,同时,其执行速度也会加快不少(因为少了与数据库建立通讯连接的过程)。
连接池中通过一定的算法,动态地控制池中连接对象的数量,当数量不够时,创建更多的对象;当对象过于富裕时,销毁部分对象。通过动态的控制来保证服务器的高性能。
怎样去理解连接池?
连接池的最基本的思想其实就是利用了集合来存放已经建立好连接的Connection对象这些连接池中Connection对象均有连接池管理,我们无需理会。
但是,我们自己写一个类库,使用集合来存放已经建立好连接的Connection对象。我们的类库就是连接池了吗?
答案是NO。
连接池的规范:
1、需要实现javax.sql.DataSource接口。
2、让Connection的close方法,它不在是销毁Connection对象,而是将Connection对象重新装入到连接池。
只有符合以上两个规范的才算得上是一个连接池。对于第1点,很简单。对于第2点,可以使用动态代理来实现。但是实现连接池不是我们要考虑的问题。理解原理和学会使用现有的连接池才是我们的重点。
常见的开源连接池有C3P0、DBCP。下面我们来演示一下如何去使用这些连接池吧。具体的连接池操作,我将会在以后的文章中讲解。企业中较为常用的是C3P0连接池。
DBCP连接池
dbcp是apache下的一个开源连接池。
1、下载jar包,导入以下两个jar包
commons-dbcp-1.4.jar
commons-pool-1.5.6.jar
2、测试代码如下:
public void dbcp() throws SQLException {
// 创建了一个连接池.
BasicDataSource ds = new BasicDataSource();
// 配置连接池
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("000000");
ds.setUrl("jdbc:mysql:///mydb");
// 1.从连接池获取连接(若没有对象,连接池会自动给我们创建。我们无需关心,只需通过它获取就行了)
Connection con = ds.getConnection();
// 2.操作
String sql = "select * from user";
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
// 3.释放资源
rs.close();
st.close();
con.close(); //实际是将Connection对象放回连接池
}
C3P0连接池
1、下载jar包并导入
c3p0-0.9.1.2.jar
2、测试代码如下:
public void fun1() throws PropertyVetoException, SQLException {
// 创建连接池
ComboPooledDataSource cpds = new ComboPooledDataSource();
//配置连接池
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql:///mydb");
cpds.setUser("root");
cpds.setPassword("000000");
// 1.从连接池获取连接(若没有对象,连接池会自动给我们创建。我们无需关心,只需通过它获取就行了)
Connection con = cpds.getConnection();
// 2.操作
String sql = "select * from account";
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
// 3.释放资源
rs.close();
st.close();
con.close(); //实际是将Connection对象放回连接池
}
本文为原创,如需转载,请注明出处!