zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    Eclipse给方法添加注释
    隐式等待和显示等待和固定等待
    用例执行完后切换到指定的页面
    HTTP常见响应状态码
    Java类初始化顺序问题
    博客园!我来了
    MySQL的存储引擎
    String声明为NULL和""的区别
    Mysql入门
    MySQL查询与结构
  • 原文地址:https://www.cnblogs.com/audi-car/p/6086842.html
Copyright © 2011-2022 走看看