C3P0连接池

 我们现实生活中每日三餐。我们并不会吃一餐饭就将碗丢掉,而是吃完饭后将碗放到碗柜中,下一餐接着使用。目的是重复利用碗,我们的数据库连接也可以重复使用,可以减少数据库连接的创建次数。提高数据库连接对象的使用率。


C3P0连接池

概念

连接池是创建和管理数据库连接的缓冲池技术。连接池就是一个容器,连接池中保存了一些数据库连接,这些连接是可以重复使用的。

没有连接池的现状

 之前JDBC访问数据库的步骤: 创建数据库连接 →运行SQL语句关闭连接 每次数据库访问执行这样重复的动作

                         

  • 获取数据库连接需要消耗比较多的资源,而每次操作都要重新获取新的连接对象,执行一次操作就把连接关闭,创建时间也较长。这样数据库连接对象的使用率低。
  • 假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出

连接池解决现状问题的原理

  1. 程序一开始就创建一定数量的连接,放在一个容器中,这个容器称为连接池(相当于碗柜)。
  2. 使用的时候直接从连接池中取一个已经创建好的连接对象。
  3. 关闭的时候不是真正关闭连接,而是将连接对象再次放回到连接池中。

                                             

数据库连接池相关API  Java为数据库连接池提供了公共的接口: javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池。

数据源(连接池)接口:javax.sql.DataSource中的方法

                                       Connection getConnection()
                                       从连接池中取出一个连接。

常见的连接池: C3P0、DBCP、druid等

 C3P0连接池简介

C3P0地址:https://sourceforge.net/projects/c3p0/?source=navbar C3P0是一个开源的连接池。Hibernate框架,默认推荐使用C3P0作为连接池实现。 C3P0的jar包:c3p0-0.9.1.2.jar(里面有两个文件,都需要导入)

             

创建文件夹,三个jar包存入,然后一起build path。

准备工作

要想连接这个c3p0,还需要一个设置配置的XML文件,而且这个文件的路径和名字必须是要写死的。
要放在src文件下,起名为:c3p0-config.xml

                                             

因为这里在c3p0的jar包里写死了这个地址和这个文件名,所以我们要这样来这样起名和存储。

这个XML配置文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- XML文件类似HTML文件,是一种树形结构的文件,上面的这个是文件的根节点 -->

<!-- 这里可以从名字看出,是c3p0的配置 -->
<c3p0-config>
	<default-config>
		<!-- 这是一个注释,XML文件的注释格式就是这样 -->
		<!-- 这下面四个是这个配置文件的必须项,出了错或者里面填写错误一定会失败,连接不到 -->
		<!-- 配置文件的内容,c3p0的jar包里面会读取这个文件这里面的配置,来连接到我们想要连接的数据库 -->
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///dbjdbc</property>
		<property name="user">root</property>
		<property name="password">yht</property>
		
		<!-- 连接池参数 -->
		<!-- 这里是基本参数的设置,如果没有会有默认值,根据项目的运作情况,可以在这里面进行更改 -->
    	        <property name="initialPoolSize">5</property>
    	        <property name="maxPoolSize">10</property>
    	        <property name="checkoutTimeout">2000</property>
    	        <property name="maxIdleTime">1000</property>
	
	</default-config>
	
	<!-- 上面的是默认配置,后面要用的ComboPooledDataSource构造方法中没有参数时会默认获取上面的配置 -->	
	<!-- 这里是可以自定义的名字,不过要在ComboPooledDataSource构造方法中加上自定义的名字,比如下面的yht,就是自定义的名字 -->
	<name-config name="yht">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///dbc3p0</property>
		<property name="user">root</property>
		<property name="password">yht</property>
		
		<!-- 连接池参数 -->
		<!-- 这里是基本参数的设置,如果没有会有默认值,根据项目的运作情况,可以在这里面进行更改 -->
    	        <property name="initialPoolSize">5</property>
    	        <property name="maxPoolSize">10</property>
    	        <property name="checkoutTimeout">2000</property>
    	        <property name="maxIdleTime">1000</property>
	</name-config>
</c3p0-config>

其实不止这些,还有:

                                   

到了这里,我们的第三方jar包已经导入完成,配置文件已经写好,我们来从连接池中获取一个连接:

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.yht.utils.JdbcUtil;

public class Test {
	public static void main(String[] args)  {
		
		/*
		 * DataSource可以看作数据源,它封装了数据库参数,连接数据库,程序中操作DataSource对象即可对数据库进行增删改查操作。
		 * DataSource可以对多种数据库进行连接
		 * 而后面的ComboPooledDataSource就是对c3p0连接池专属的子类。
		 * 通过这里创建对象,会加载c3p0的jar包然后再去读取XML文件中的属性最后连接到数据库,然后才算是真正的创建了一个连接池
		 * 创建的连接池资源,全部都存在下面创建的对象里
		 */
		DataSource ds = new ComboPooledDataSource();


                //这里可以加上在XML文件设置的带名字的配置,就可以访问到对应的数据库
		//DataSource ds = new ComboPooledDataSource("yht");
	
			
		//为了测试是否连接成功,所以就用jdbc来进行一次查询操作
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try{
			
			/*
			* 我们之前是通过Class.forname()加载驱动,然后利用DriverManager来获取连接
			* 现在我们上面通过创建好的连接池来获取资源
			*/
			conn = ds.getConnection();
			String sql = "select * from emp";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while(rs.next()){
				int id = rs.getInt("id");
				String name = rs.getString("name");
				String gender = rs.getString("gender");
				double salary = rs.getDouble("salary");
				Date joinDate = rs.getDate("join_date");
				System.out.println(id+"\t"+name+"\t"+gender+"\t"+salary+"\t"+joinDate);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		try {
			ps.close();
			conn.close();
			rs.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果:

注意:XML里面的必须项标签内的代码一个字母还有大小写都不能错,因为里面不会进行编译报错,所以一定要检查好。

C3p0Utils工具类

我们之前在JDBC里面写过一个工具类,在这里,我们还可以再次写一个工具类来简化代码,而且在以后也会多次用到。

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
	
	private static DataSource ds = new ComboPooledDataSource();
	//获取一个连接池
	public static DataSource getDataSource(){
		return ds;
	}
	//获取连接池中的一个连接
	public static Connection getConnection(){
		Connection conn = null;
		
		try {
			conn = ds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
}

利用工具类后的代码

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.yht.utils.C3P0Utils;

public class Test02 {
	public static void main(String[] args) throws Exception {
		
		Connection conn = C3P0Utils.getConnection();
		String sql = "select * from emp";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			int id = rs.getInt("id");
			String name = rs.getString("name");
			String gender = rs.getString("gender");
			double salary = rs.getDouble("salary");
			Date joinDate = rs.getDate("join_date");
			System.out.println(id+"\t"+name+"\t"+gender+"\t"+salary+"\t"+joinDate);
		}
		try {
			ps.close();
			conn.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值