2.4 数据库连接池

2.4.1 什么是连接池

在开发中,<mark>所谓的池就是一个容器</mark>,来存储程序的中的数据.

而<mark>数据库连接池就是用来存储数据库连接的池子</mark>,

  • 在整个程序中<mark>共享连接</mark>,
  • <mark>减少</mark>连接<mark>开关的次数</mark>,
  • 实现连接的<mark>复用</mark>,
  • 从而<mark>提高</mark>程序执行的<mark>效率</mark>.

提示:连接池还有另外一个名字,即DataSource,翻译为数据源,<mark>因此连接池也叫做数据源</mark>。

2.4.2 为什么要使用数据库连接池

         对于数据库来说,<mark>频繁的开关连接会非常的耗费资源</mark>,也会<mark>导致程序执行效率低下</mark>。

         我们可以在程序中<mark>创建一个池子</mark>,在程序启动时就初始化一批连接放在连接池中,当用户<mark>需要连接时,就直接从池子中拿一个连接使用</mark>,<mark>当用完连接后,也不要将连接关闭</mark>,而是将连接还回池中,下一个用户需要连接时也是如此。
         <mark>这样可以减少链接开关的次数,从而提供程序执行的效率</mark>.

1、传统方式操作数据库


… … 在传统方式中,每次需要连接就创建一个连接进行使用,用完连接后,直接将连接关闭。
… … 而每次创建连接和关闭连接是非常消耗时间和资源的过程。
因此效率较低,并且连接也没有得到复用。
.
… … 可以在程序一启动时,就往池中放一批连接,当用户需要连接时,不用自己创建,而是从连接池中直接获取。
.
… … 这样一来,用来用去都是池中的这一批连接,减少了连接创建和关闭的次数。
实现了连接的复用,从而提高了程序执行的效率。

2、使用连接池操作数据库

2.4.3 如何使用C3P0连接池

使用C3P0连接池开发步骤:

1、导入开发包

2、创建数据库连接池

//创建一个连接池对象(池子:会包含很多连接)
//每个池,都必须继承 sun公司的 接口 - DataSource
// c3p0

ComboPooledDataSource cpds = new ComboPooledDataSource();

3、设置数据库连接的基本信息

连接池:dbc3p 、<mark>c3p0(下面讲) 、druid(阿里)</mark>

方式一:(不推荐)

cpds.setDriverClass("com.mysql.jdbc.Driver"); cpds.setJdbcUrl("jdbc:mysql:///jt_db?characterEncoding=utf-8"); cpds.setUser("root"); cpds.setPassword("root");

  • 因为每次修改配置,需要重新启动程序。
  • 因此,用到了<mark>配置文件</mark>
测试代码 - 修改之前写的查询代码
package com.edut.cn.tarena.jdbc;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import com.edut.cn.tarena.util.JdbcUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class Test_C3P0 {
	@Test
	public void testFindAll() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		//创建一个连接池对象(池子:会包含很多连接) 
		//每个池,都必须继承 sun公司的 接口 - DataSource
		// c3p0
		ComboPooledDataSource pool = 
				new ComboPooledDataSource();
		
		try {
			//设置连接数据库的基本信息
			pool.setDriverClass("com.mysql.jdbc.Driver");
			pool.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jt_db?characterEncoding=utf-8");
			pool.setUser("root");
			pool.setPassword("root");
			//如果能连接,会默认获取一批连接放在池中。
			//修改,通过pool获得连接
			conn = pool.getConnection();
			//到下面 close 代码
			
			String sql = "select * from account;";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery(sql);
			while (rs.next()) {
				int id = rs.getInt("id");
				String name = rs.getString("name");
				double money = rs.getDouble("money");
				System.out.println(id + " : " + name + " : " + money);
			}

		
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			/* * --------- * 之前 * --------- * 我们自己创建连接对象, * 这个连接对象是没有经过任何修改的, * 原生的连接对象。 * conn.close(); * 是将连接关闭。 * * ----- * 现在 * ----- * 如果是通过连接池获取了一个连接池对象, * 整个连接池对象在返回时就已经被修改。 * 其中的close方法被改成了将连接还回到连接池中, */
			JdbcUtil.close(conn, ps, rs);
		}
	}
}


红色的信息,不是异常。

方式二:(推荐)

在类目录下(开发时可以放在src或者类似的源码目录下), 添加一个c3p0-config.<mark>xml</mark>文件, 配置内容如下:

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

<!-- C3P0连接池配置 数据库连接是一个耗费大量资源且相当慢的操作, 所以为了提高性能和连接速度,诞生了连接池这样的概念。 在多用户并发操作过程中,连接池尤为重要。 它是将那些已连接的数据库连接存放在一个容器里(连接池), 这样以后别人要连接数据库的时候, 将不会重新建立数据库连接, 会直接从连接池里取出可用的连接, 用户使用完毕后,连接又重新还回到连接池中。 注意:连接池里的连接将会一直保存在内存里, 即使你没用也是一样。所以这个时候你得权衡一下连接池的连接数量了。 -->
	
<c3p0-config> <!-- 根标签 -->
	<default-config> <!-- 默认配置 -->
		<!-- property 标签里面写属性, -->
		<!-- 数据库的标签名 -->
		<property name="driverClass">
			com.mysql.jdbc.Driver
		</property>
		
		<!-- 数据库的url -->
		<property name="jdbcUrl">
			jdbc:mysql://127.0.0.1:3306/jt_db?characterEncoding=utf-8
		</property>
		
		<!--用户名。Default: null -->
		<property name="user">root</property>
		
		<!--密码。Default: null -->
		<property name="password">root</property>
		
	</default-config>
</c3p0-config>
方式三:(推荐)

在<mark>类目录下(开发时可以放在src或者类似的源码目录下),</mark> 添加一个c3p0.<mark>properties</mark>文件, 配置内容如下:

c3p0.properties内容:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///jt_db?characterEncoding=utf-8
c3p0.user=root
c3p0.password=root