一、数据库连接池


(1)JDBC数据库连接池的必要性

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

  • 在主程序(如servlet、beans)中建立数据库连接。
  • 进行sql操作
  • 断开数据库连接。

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

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


(2)数据库连接池(connection pool)

  • 基本思想是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
  • 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。


(3)数据库连接池的工作原理 



(4)数据库连接池技术的优点

  • 资源重用:由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
  • 更快的系统反应速度:数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间
  • 新的资源分配手段:对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
  • 统一的连接管理,避免数据库连接泄露:在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露


(5)开源的数据库连接池

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

  • DBCP 数据库连接池
  • C3P0 数据库连接池

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



 二、DBCP 数据库连接池

(1)基本用法

/**
     * 使用 DBCP数据库连接池
     * 1.加入jar包:
     *   commons-dbcp2-2.1.1.jar
     *   commons-pool2-2.4.2.jar
     * 2.创建数据库连接
     * 3.为数据源实例指定必需的属性
     * 4.从数据源中获取数据库连接
     * @throws SQLException
     */
    @Test
    public void test17() throws SQLException {
        BasicDataSource dataSource = null;
        //1.创建DBPC数据源实例
        dataSource = new BasicDataSource();

        //2.为数据源实例指定必需的属性
        dataSource.setUsername("root");
        dataSource.setPassword("12345");
        dataSource.setUrl("jdbc:mysql://localhost:3306/jdbctest");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        //3.指定数据库的一些可选属性
        //3.1 指定数据库连接池初始化连接数的个数
        dataSource.setInitialSize(10);
        //3.2 指定最大连接数,同一时间可以同时向数据库申请的连接数
        dataSource.setMaxTotal(50);
        //3.3 其他...

        //3.从数据源中获取数据库连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection.getClass());
    }

(2)更好的使用方法

/**
     * 1. 加载 dbcp的 properties配置文件:配置文件中的键需要来自BasicDataSource的属性
     * 2. 调用 BasicDataSourceFactory的 createDataSource方法才创建数据库连接
     * 3. 从 DataSource实例中获取数据库连接。
     *
     * @throws Exception
     */
    @Test
    public void test18() throws Exception {
        Properties properties = new Properties();
        InputStream in = JdbcTest.class.getClassLoader().getResourceAsStream("dbcp.properties");
        properties.load(in);

        DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);

        //BasicDataSource basicDataSource = (BasicDataSource) dataSource;
    }



三、C3P0 数据库连接池

(1)基本用法

(2)更好的用法

/**
	 * 1. 创建 c3p0-config.xml 文件, 
	 * 参考帮助文档中 Appendix B: Configuation Files 的内容
	 * 2. 创建 ComboPooledDataSource 实例;
	 * DataSource dataSource = 
	 *			new ComboPooledDataSource("helloc3p0");  
	 * 3. 从 DataSource 实例中获取数据库连接. 
	 */
	@Test
	public void testC3poWithConfigFile() throws Exception{
		DataSource dataSource = 
				new ComboPooledDataSource("helloc3p0");  
		
		System.out.println(dataSource.getConnection()); 
		
		ComboPooledDataSource comboPooledDataSource = 
				(ComboPooledDataSource) dataSource;
		System.out.println(comboPooledDataSource.getMaxStatements()); 
	}

附c3p0-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<named-config name="helloc3p0">
		
		<!-- 指定连接数据源的基本属性 -->
		<property name="user">root</property>
		<property name="password">1230</property>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///atguigu</property>
		
		<!-- 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 -->
		<property name="acquireIncrement">5</property>
		<!-- 初始化数据库连接池时连接的数量 -->
		<property name="initialPoolSize">5</property>
		<!-- 数据库连接池中的最小的数据库连接数 -->
		<property name="minPoolSize">5</property>
		<!-- 数据库连接池中的最大的数据库连接数 -->
		<property name="maxPoolSize">10</property>

		<!-- C3P0 数据库连接池可以维护的 Statement 的个数 -->
		<property name="maxStatements">20</property>
		<!-- 每个连接同时可以使用的 Statement 对象的个数 -->
		<property name="maxStatementsPerConnection">5</property>
	
	</named-config>
		
</c3p0-config>

 

 

JDBC学习笔记:

1. 获取数据库连接    

2. 通过Statement执行更新、查询操作    

3. 使用PrepareStatement    

4. 使用ResultSetMetaData 对象处理结果集元数据    

5. 使用DatabaseMetaData获取数据库信息    

6. BLOB    

7. 处理事务与隔离级别    

8. 批量处理    

9. 数据库连接池    ----当前----

10. 调用函数与存储过程