JDBC数据库链接池

JDBC数据库链接池

1、JDBC数据库链接池的必要性

  在使用开发基于数据库的web程序时,传统的模式基本是按如下步骤:java

  ①在主程序(如servlet、beans)中创建数据库链接。
  ②进行sql操做
  ③断开数据库链接。mysql

  这种模式开发,存在的问题:web

  ①普通的JDBC数据库链接使用 DriverManager 来获取,每次向数据库创建连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。须要数据库链接的时候,就向数据库要求一个,执行完成后再断开链接。这样的方式将会消耗大量的资源和时间。数据库的链接资源并无获得很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库链接操做将占用不少的系统资源,严重的甚至会形成服务器的崩溃。
  ②对于每一次数据库链接,使用完后都得断开。不然,若是程序出现异常而未能关闭,将会致使数据库系统中的内存泄漏,最终将致使重启数据库。
  ③这种开发不能控制被建立的链接对象数,系统资源会被毫无顾及的分配出去,如链接过多,也可能致使内存泄漏,服务器崩溃。sql

2、数据库链接池(connection pool)

  数据库链接池简单介绍

  为解决传统开发中的数据库链接问题,能够采用数据库链接池技术。数据库

  数据库链接池的基本思想就是为数据库链接创建一个“缓冲池”。预先在缓冲池中放入必定数量的链接,当须要创建数据库链接时,只需从“缓冲池”中取出一个,使用完毕以后再放回去。服务器

  数据库链接池负责分配、管理和释放数据库链接,它容许应用程序重复使用一个现有的数据库链接,而不是从新创建一个。ide

  数据库链接池在初始化时将建立必定数量的数据库链接放到链接池中,这些数据库链接的数量是由最小数据库链接数来设定的。不管这些数据库链接是否被使用,链接池都将一直保证至少拥有这么多的链接数量。链接池的最大数据库链接数量限定了这个链接池能占有的最大链接数,当应用程序向链接池请求的链接数超过最大链接数量时,这些请求将被加入到等待队列中。学习

  数据库链接池工做原理

  数据库链接池技术的优势

  资源重用:

  ①因为数据库链接得以重用,避免了频繁建立,释放链接引发的大量性能开销。在减小系统消耗的基础上,另外一方面也增长了系统运行环境的平稳性。大数据

  更快的系统反应速度:
  数据库链接池在初始化过程当中,每每已经建立了若干数据库链接置于链接池中备用。此时链接的初始化工做均已完成。对于业务请求处理而言,直接利用现有可用链接,避免了数据库链接初始化和释放过程的时间开销,从而减小了系统的响应时间ui

  新的资源分配手段:
  对于多应用共享同一数据库的系统而言,可在应用层经过数据库链接池的配置,实现某一应用最大可用数据库链接数的限制,避免某一应用独占全部的数据库资源

  统一的链接管理,避免数据库链接泄露:
  在较为完善的数据库链接池实现中,可根据预先的占用超时设定,强制回收被占用链接,从而避免了常规数据库链接操做中可能出现的资源泄露

3、两种开源的数据库链接池

  JDBC 的数据库链接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口一般由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:
  ①DBCP 数据库链接池
  ②C3P0 数据库链接池

  DataSource 一般被称为数据源,它包含链接池和连接池管理两个部分,习惯上也常常把 DataSource称为链接池

  数据源和数据库链接不一样,数据源无需建立多个,它是产生数据库链接的工厂,所以整个应用只须要一个数据源便可。

  当数据库访问结束后,程序仍是像之前同样关闭数据库链接:conn.close(); 但上面的代码并无关闭数据库的物理链接,它仅仅把数据库链接释放,归还给了数据库链接池。

  DBCP 数据源

  DBCP 是 Apache 软件基金组织下的开源链接池实现,该链接池依赖该组织下的另外一个开源系统:Common-pool.如需使用该链接池实现,应在系统中增长以下两个 jar文件:
  ①Commons-dbcp.jar:链接池的实现
  ②Commons-pool.jar:链接池实现的依赖库

  Tomcat 的链接池正是采用该链接池来实现的。该数据库链接池既能够与应用服务器整合使用,也可由应用程序独立使用。

  使用范例:

 1     /**
 2  * 使用 DBCP 数据库链接池  3  * 1. 加入 jar 包(2 个jar 包). 依赖于 Commons Pool  4  * 2. 建立数据库链接池  5  * 3. 为数据源实例指定必须的属性  6  * 4. 从数据源中获取数据库链接  7  *  8  * @throws SQLException  9      */
10  @Test 11     public void testDBCP() throws SQLException { 12     final BasicDataSource dataSource = new BasicDataSource(); 13 
14     // 2. 为数据源实例指定必须的属性
15     dataSource.setUsername("root"); 16     dataSource.setPassword(""); 17     dataSource.setUrl("jdbc:mysql:///jdbc?useSSL=false"); 18     dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 19 
20     // 3. 指定数据源的一些可选的属性. 21     // 1). 指定数据库链接池中初始化链接数的个数
22     dataSource.setInitialSize(5); 23 
24     // 2). 指定最大的链接数: 同一时刻能够同时向数据库申请的链接数
25     dataSource.setMaxActive(5); 26 
27     // 3). 指定小链接数: 在数据库链接池中保存的最少的空闲链接的数量
28     dataSource.setMinIdle(2); 29 
30     // 4).等待数据库链接池分配链接的最长时间. 单位为毫秒. 超出该时间将抛出异常.
31     dataSource.setMaxWait(1000 * 5); 32 
33     // 4. 从数据源中获取数据库链接
34     Connection connection = dataSource.getConnection(); 35  System.out.println(connection.getClass()); 36 
37     connection = dataSource.getConnection(); 38  System.out.println(connection.getClass()); 39 
40     connection = dataSource.getConnection(); 41  System.out.println(connection.getClass()); 42 
43     connection = dataSource.getConnection(); 44  System.out.println(connection.getClass()); 45 
46     Connection connection2 = dataSource.getConnection(); 47     System.out.println(">" + connection2.getClass()); 48 
49     new Thread() { 50         public void run() { 51  Connection conn; 52         try { 53             conn = dataSource.getConnection(); 54  System.out.println(conn.getClass()); 55         } catch (SQLException e) { 56  e.printStackTrace(); 57  } 58  }; 59  }.start(); 60 
61     try { 62         Thread.sleep(3000); 63     } catch (InterruptedException e) { 64  e.printStackTrace(); 65  } 66 
67  connection2.close(); 68     }
View Code

    使用配置文件的方式:

 1     /**
 2  * 1. 加载 dbcp 的 properties 配置文件: 配置文件中的键须要来自 BasicDataSource 的属性.  3  * 2. 调用BasicDataSourceFactory 的 createDataSource 方法建立 DataSource 实例  4  * 3. 从DataSource 实例中获取数据库链接.  5      */
 6  @Test  7     public void testDBCPWithDataSourceFactory() throws Exception {  8 
 9     Properties properties = new Properties(); 10     InputStream inStream = JDBCTest.class.getClassLoader().getResourceAsStream("dbcp.properties"); 11  properties.load(inStream); 12 
13     DataSource dataSource = BasicDataSourceFactory.createDataSource(properties); 14 
15  System.out.println(dataSource.getConnection()); 16 
17     // BasicDataSource basicDataSource = 18     // (BasicDataSource) dataSource; 19     //
20     // System.out.println(basicDataSource.getMaxWait());
21     }
View Code

  注意:这里使用配置文件的方式应遵循Java EE的setter和getter规范,不能随便命名:

  dbcp.properties配置文件(属性的意义和第一种方式对应):

  username=root
  password=password
  driverClassName=com.mysql.jdbc.Driver

  #这里MySQL高版本驱动须要设置useSSL=false或true,不然控制台会有警告
  url=jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false

  initialSize=10
  maxActive=50
  minIdle=5
  maxWait=5000

  C3P0数据源

  通常方式建立数据库链接池:

 1     /**
 2  * 使用set方法为属性赋值  3      */
 4  @Test  5     public void testC3P0() throws Exception {  6     ComboPooledDataSource cpds = new ComboPooledDataSource();  7     cpds.setDriverClass("com.mysql.jdbc.Driver"); // loads the jdbc driver
 8     cpds.setJdbcUrl("jdbc:mysql:///jdbc?useSSL=false");  9     cpds.setUser("root"); 10     cpds.setPassword(""); 11 
12  System.out.println(cpds.getConnection()); 13     }

  使用xml配置文件:

  ①Java代码:

 1     /**
 2  * 1. 建立 c3p0-config.xml 文件, 参考帮助文档中 Appendix B: Configuation Files 的内容  3  * 2. 建立 ComboPooledDataSource 实例;  4  * DataSource dataSource = new ComboPooledDataSource("helloc3p0");  5  * 3. 从 DataSource 实例中获取数据库链接.  6      */
 7  @Test  8     public void testC3poWithConfigFile() throws Exception {  9     DataSource dataSource = new ComboPooledDataSource("helloc3p0"); 10 
11  System.out.println(dataSource.getConnection()); 12 
13     ComboPooledDataSource comboPooledDataSource = (ComboPooledDataSource) dataSource; 14  System.out.println(comboPooledDataSource.getMaxStatements()); 15     }
View Code

  ②C3P0-config.xml配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <c3p0-config>
 3 
 4     <named-config name="helloc3p0">
 5         
 6         <!-- 指定链接数据源的基本属性 -->
 7         <property name="user">root</property>
 8         <property name="password"></property>
 9         <property name="driverClass">com.mysql.jdbc.Driver</property>
10         <property name="jdbcUrl">jdbc:mysql:///jdbc?useSSL=false</property>
11         
12         <!-- 若数据库中链接数不足时, 一次向数据库服务器申请多少个链接 -->
13         <property name="acquireIncrement">5</property>
14         <!-- 初始化数据库链接池时链接的数量 -->
15         <property name="initialPoolSize">5</property>
16         <!-- 数据库链接池中的最小的数据库链接数 -->
17         <property name="minPoolSize">5</property>
18         <!-- 数据库链接池中的最大的数据库链接数 -->
19         <property name="maxPoolSize">10</property>
20 
21         <!-- C3P0 数据库链接池能够维护的 Statement 的个数 -->
22         <property name="maxStatements">20</property>
23         <!-- 每一个链接同时可使用的 Statement 对象的个数 -->
24         <property name="maxStatementsPerConnection">5</property>
25     
26     </named-config>
27         
28 </c3p0-config>
View Code

 

若是,您对个人这篇博文有什么疑问,欢迎评论区留言,你们互相讨论学习。
若是,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
若是,您但愿更容易地发现个人新博客,不妨点击一下左下角的【关注我】。
若是,您对个人博文感兴趣,能够关注个人后续博客,我是【AlbertRui】。

转载请注明出处和连接地址,欢迎转载,谢谢!

相关文章
相关标签/搜索