mysql数据库连接池 手动编写

源码来源于http://www.toutiao.com/a6350448676050174209/,留存以供以后参考学习

先上一张项目托普图

然后分别列出各个文件的源码:

MyPool.java(就是个接口)

package com.audi;

public interface MyPool
{
	PoolConnection getConnection();
	void createConnections(int count);
}

MyPoolImpl.java(接口的实现类)

package com.audi;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;

import com.mysql.jdbc.Driver;

public class MyPoolImpl implements MyPool
{
	private static String jdbcDriver = "";
	private static String jdbcUrl = "";
	private static String userName = "";
	private static String password = "";
	private static int initCount;
	private static int stepSize;
	private static int poolMaxSize;

	private static Vector<PoolConnection> poolConnections = new Vector<PoolConnection>();

	public MyPoolImpl()
	{
		// TODO Auto-generated constructor stub
		init();
	}

	private void init()
	{
		// TODO Auto-generated method stub
//		读取配置文件
		InputStream in = MyPoolImpl.class.getClassLoader()
				.getResourceAsStream("mysqlConnection.properties");
//		InputStream inputStream = new in
		Properties pro = new Properties();
		try
		{
//			装载配置文件输入流
			pro.load(in);
		} catch (Exception e)
		{
			// TODO: handle exception
		}
//		从配置文件中读取出配置参数
		jdbcDriver = pro.getProperty("jdbcDriver");
		jdbcUrl = pro.getProperty("jdbcUrl");
		userName = pro.getProperty("userName");
		password = pro.getProperty("password");
		initCount = Integer.valueOf(pro.getProperty("initCount"));
		stepSize = Integer.valueOf(pro.getProperty("stepSize"));
		poolMaxSize = Integer.valueOf(pro.getProperty("poolMaxSize"));

		try
		{
//			获取驱动对象并注册
			Driver driver = (Driver) Class.forName(jdbcDriver).newInstance();
			DriverManager.registerDriver(driver);
		} catch (Exception e)
		{
			// TODO: handle exception
			e.printStackTrace();
		}
//		创建一定数量的初始链接
		createConnections(initCount);
	}

	@Override
	public PoolConnection getConnection()
	{
		// TODO Auto-generated method stub
		if (poolConnections.size() <= 0)
		{
			System.out.println("链接池为空,获取数据库链接失败!!!");
			throw new RuntimeException("链接池为空,获取数据库链接失败!!!");
		}
		PoolConnection connection = getRealConnection();
		
//		如果没有成功的获取链接就创建一定数量的链接  并从中获取一个有效链接
		while(connection == null)
		{
			createConnections(stepSize);
			connection = getRealConnection();
			try
			{
//				这里睡眠的原因时考虑到第一次获取链接失败,可能有多个线程在等待链接资源,所以当前线程先等待一下,避开高峰
				Thread.sleep(300);
			} catch (Exception e)
			{
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		return connection;
	}

//	注意有synchronized关键字
	private synchronized PoolConnection getRealConnection()
	{
		// TODO Auto-generated method stub
		for (PoolConnection conn : poolConnections)
		{
//			如果当前链接空闲则返回该链接对象
			if (!conn.isBusy())
			{
				Connection connection = conn.getConn();
				try
				{
//					判断获得的链接是否是有效的,如果无效就创建一个新的链接  isValid方法其实就是在定时时间到的时候执行一下sql语句
					if (!connection.isValid(2000))
					{
						Connection validConn = DriverManager.getConnection(jdbcUrl, userName, password);
						conn.setConn(validConn);
					}
				} catch (Exception e)
				{
					// TODO: handle exception
				}
			}
			conn.setBusy(true);
			return conn;
		}
		return null;
	}

//	创建链接
	@Override
	public void createConnections(int count)
	{
		// TODO Auto-generated method stub
		if (poolMaxSize > 0 && poolConnections.size() + count > poolMaxSize)
		{
			System.out.println("创建链接对象失败,因为数据库链接数量已达上限!!");
			throw new RuntimeException("创建链接对象失败,因为数据库链接数量已达上限!!");
		}

//		否则就开始创建链接
		for (int i = 0; i < count; i++)
		{
			try
			{
				Connection conn = DriverManager.getConnection(jdbcUrl, userName, password);
//				封装链接对象  并存入vecter
				PoolConnection poolConnection = new PoolConnection(conn, false);
				poolConnections.add(poolConnection);
			} catch (SQLException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}

 PoolConnection.java(里面会进行一些连接参数的配置)

package com.audi;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class PoolConnection
{
	private Connection conn;
	private boolean isBusy = false;
	
	public Connection getConn()
	{
		return conn;
	}

	public void setConn(Connection conn)
	{
		this.conn = conn;
	}

	public boolean isBusy()
	{
		return isBusy;
	}

	public void setBusy(boolean isBusy)
	{
		this.isBusy = isBusy;
	}

	public PoolConnection(Connection conn,boolean isBusy)
	{
		this.conn = conn;
		this.isBusy = isBusy; 
	}
	
	public ResultSet querySql(String sql)
	{
		ResultSet resultSet = null;
		Statement statement = null;
		try
		{
			statement = conn.createStatement();
			resultSet = statement.executeQuery(sql);
		} catch (Exception e)
		{
			// TODO: handle exception
		}
		return resultSet;
	}

	public void close()
	{
		this.isBusy = false;
	}
}

PoolManager.java(使用内部类的方式获取连接池对象)

package com.audi;

public class PoolManager
{
	private static class CreatePool
	{
		private static MyPoolImpl myPoolImpl= new MyPoolImpl(); 
	}
	
	public static MyPoolImpl getInStance()
	{
		return CreatePool.myPoolImpl;
	}
}

最后是测试类

package com.audi;

import java.sql.ResultSet;

public class TestPool
{
	private static MyPoolImpl poolImpl =PoolManager.getInStance();
	
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		/*long time= System.currentTimeMillis();
		for (int i = 0; i < 2000; i++)
		{
			System.out.println("第"+i+"次执行");
			selecData();
		}
		System.out.println("運行時間"+(System.currentTimeMillis()-time));*/
//		System.out.println(new Date());
		//selecData();
//		创建2000个数据库链接线程
		long time= System.currentTimeMillis();
		for (int i = 0; i < 2000; i++)
		{
			System.out.println("第"+i+"次执行");
			new Thread(new Runnable()
			{
				public void run()
				{
					selecData();
				}
			});
		}
		System.out.println("運行時間"+(System.currentTimeMillis()-time));
	}

	public synchronized static void selecData()
	{
		PoolConnection connection = poolImpl.getConnection();
		ResultSet resultSet = connection.querySql("select * from Student");
		try
		{
			while (resultSet.next())
			{
				System.out.println(resultSet.getString("ID")+"	"+resultSet.getString("NAME")+"	"+resultSet.getString("AGE"));
			}
			resultSet.close();
			connection.close();
		} catch (Exception e)
		{
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}

数据库连接参数配置文件

mysqlConnection.properties

jdbcDriver=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/test
userName=root
password=w513723
initCount=10
stepSize=5
poolMaxSize=200
原文地址:https://www.cnblogs.com/audi-car/p/6086842.html