mysql數據庫鏈接池 手動編寫

源碼來源於http://www.toutiao.com/a6350448676050174209/,留存以供之後參考學習java

先上一張項目託普圖mysql

而後分別列出各個文件的源碼:sql

MyPool.java(就是個接口)數據庫

package com.audi;

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

MyPoolImpl.java(接口的實現類)ide

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;
	}
}

最後是測試類this

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")+"\t"+resultSet.getString("NAME")+"\t"+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
相關文章
相關標籤/搜索