package com.hanchao.test;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.DataSources;


/***********************
 * @author:han    
 * @version:1.0        
 * @created:2015-10-11    
 ***********************
 */
public class TestPool {
	
	public static void main(String[] args) {
		
/*		Scanner input = new Scanner(System.in);
		System.out.println("请输入账号:");
		String name = input.next();
		System.out.println("请输入密码:");
		String pwd = input.next();
		System.out.println("请输入金额:");
		float money = input.nextFloat();*/
		
		final String DRIVER = "com.mysql.jdbc.Driver";
		//final String URL = "jdbc:mysql://127.0.0.1:3306/mydb";
		//final String URL = "jdbc:mysql://localhost:3306/mydb";
		final String URL = "jdbc:mysql:///mydb";
		final String NAME = "root";
		final String PASSWORD = "root";
		
		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;
		
		try {
			//1.加载数据库驱动
			Class.forName(DRIVER);
			//连接mysql数据库
			DataSource unpooled = DataSources.unpooledDataSource(URL,NAME,PASSWORD);
			//构建一个连接池
			DataSource pooled = DataSources.pooledDataSource(unpooled);

			//2.获取数据库连接(first Time)
		    conn = pooled.getConnection();
			System.out.println("1 con Class Type is :" + conn.getClass().getName());
			//取得内部的实际数据库连接
			Object o1 = getInner(conn);
			System.out.println("1 Inner con Class Type is :" + o1.getClass().getName());
			
			//3.获取Statement对象
			stat = conn.createStatement();
			//4.执行SQL
			rs = stat.executeQuery(" select * from t_user where id = 13");
		    while (rs.next()) {
				System.out.println(" username:" + rs.getString("username"));
			}
		    
		    //5.关闭连接
		    rs.close();
		    stat.close();
		    conn.close();
		    
		    //6.等待连接返回池中
		    try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		    
		    //第二次获取数据库连接
		    conn = pooled.getConnection();
			System.out.println("2 con Class Type is :" + conn.getClass().getName());
			Object o2 = getInner(conn);
			System.out.println("2 Inner con Class Type is :" + o2.getClass().getName());
			
			//获取Statement对象
			stat = conn.createStatement();
			
			//3.获取Statement对象
			stat = conn.createStatement();
			//4.执行SQL
			rs = stat.executeQuery(" select * from t_user where id = 13");
		    while (rs.next()) {
				System.out.println(" username:" + rs.getString("username"));
			}
/*
			//3.获取Statement对象
//			String sql = "delete from t_user where id = 13";
//			String sql = "insert into t_user(username,address) values('tom1','USA1')";
		    StringBuilder sql = new StringBuilder();
		    sql.append("INSERT INTO t_account(username,`password`,money,`enable`)  ");
		    sql.append("VALUES ");
		    sql.append("('"+name+"','"+pwd+"','"+money+"','1')");
		    
		    System.out.println("SQL:" + sql.toString());
			
			//执行SQL
//			int rows = stat.executeUpdate(sql);
			int rows = stat.executeUpdate(sql.toString());
			if (rows > 0) {
				System.out.println("execute OK!!");
			} else {
				System.out.println("execute error !!");
			}
			
		*/	
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (stat != null) {
					stat.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static Object getInner(Object conn) {
		Object object = null;
		Field f ;
		
		try {
			f = conn.getClass().getDeclaredField("inner");
			f.setAccessible(true);
			object = f.get(conn);
			f.setAccessible(false);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return object;
	}

}

结果:

wKioL1fIQGzh6CUyAABTT7-zXU0450.png-wh_50

wKiom1fIQHODclVYAA2YKJV4SbM573.jpg-wh_50

首先,从数据库连接池获得一个连接。发现连接类型并不是mysql的数据库连接,而是,com.mchange.v2.c3p0.impl.NewProxyConnection。通过类名,可以推测,从数据库连接池中获取的只是一个代理。

当我们关闭.NewProxyConnection连接时,并没有真正关闭连接,而只是将数据库连接放入连接池保存,使得数据库连接在连接池中得到复用。而从连接池返回的NewProxyConnection对象,只是对真实数据库连接的包装。