数据库连接池的原理

一.早期我们怎么进行数据库操作

1.原理:一般来说,Java应用程序访问数据库的过程是:

   ①装载数据库驱动程序;

   ②通过jdbc建立数据库连接;

   ③访问数据库,执行sql语句;

   ④断开数据库连接。

 

 

2.分析

 

       程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

 

3.解决:

对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

 

我们自己尝试开发一个连接池,来为上面的查询业务提供数据库连接服务:

       ①   编写class 实现DataSource 接口

       ②   class构造器一次性创建10个连接,将连接保存LinkedList

       ③   实现getConnection  LinkedList返回一个连接

       ④   提供将连接放回连接池中方法

 

       1、连接池代码

  1. public class MyDataSource implements DataSource {  
  2.           //链表 --- 实现栈结构  
  3.           privateLinkedList<Connection> dataSources = new LinkedList<Connection>();  
  4.   
  5.           //初始化连接数量  
  6.           publicMyDataSource() {  
  7.                  //一次性创建10个连接  
  8.                  for(int i = 0; i < 10; i++) {  
  9.                         try {  
  10.                            //1、装载sqlserver驱动对象  
  11.                            DriverManager.registerDriver(new SQLServerDriver());  
  12.                            //2、通过JDBC建立数据库连接  
  13.                            Connection con =DriverManager.getConnection(  
  14.                               "jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");  
  15.                            //3、将连接加入连接池中  
  16.                            dataSources.add(con);  
  17.                         } catch (Exception e) {  
  18.                            e.printStackTrace();  
  19.                         }  
  20.                  }  
  21.           }  
  22.   
  23.           @Override  
  24.           publicConnection getConnection() throws SQLException {  
  25.                  //取出连接池中一个连接  
  26.                  finalConnection conn = dataSources.removeFirst(); // 删除第一个连接返回  
  27.                  returnconn;  
  28.           }  
  29.   
  30.           //将连接放回连接池  
  31.           publicvoid releaseConnection(Connection conn) {  
  32.                  dataSources.add(conn);  
  33.                  }  
  34.    } 

 

2、使用连接池重构我们的用户查询函数       

  1. //查询所有用户  
  2. Public void FindAllUsers(){  
  3.        //1、使用连接池建立数据库连接  
  4.        MyDataSource dataSource = new MyDataSource();  
  5.        Connection conn =dataSource.getConnection();          
  6.        //2、创建状态  
  7.        Statement state =con.createStatement();             
  8.        //3、查询数据库并返回结果  
  9.        ResultSet result =state.executeQuery("select * from users");             
  10.        //4、输出查询结果  
  11.        while(result.next()){  
  12.               System.out.println(result.getString("email"));  
  13.        }              
  14.        //5、断开数据库连接  
  15.        result.close();  
  16.        state.close();  
  17.        //6、归还数据库连接给连接池  
  18.        dataSource.releaseConnection(conn);  
  19.  }  

 

       这就是数据库连接池的原理,它大大提供了数据库连接的利用率,减小了内存吞吐的开销。

 

 

3.实际开发中有成熟的开源连接池供我们使用

 

       理解了连接池的原理就可以了,没有必要什么都从头写一遍,那样会花费很多时间,并且性能及稳定性也不一定满足要求。事实上,已经存在很多流行的性能优良的第三方数据库连接池jar包供我们使用。如:

 

       1.Apache commons-dbcp 连接池

 

        下载:http://commons.apache.org/proper/commons-dbcp/

 

 

 

       2.c3p0 数据库连接池

 

        下载:http://sourceforge.net/projects/c3p0/

 

 

 

4.实际开发推荐

介绍:https://github.com/alibaba/druid/wiki/

Druid是阿里巴巴开源平台上的一个项目,基于Apache License 2.0协议开源,代码托管在GitHub。整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计SQL信息、SQL性能收集、SQL注入检查、SQL翻译等,程序员可以通过定制来实现自己需要的功能。

 

 

转载:http://blog.csdn.net/shuaihj/article/details/14223015

 

posted @ 2017-03-17 13:18  Quillagua  阅读(537)  评论(0编辑  收藏  举报