现在的位置: 首页 > 综合 > 正文

J2SE简单的数据库连接池

2018年01月22日 ⁄ 综合 ⁄ 共 4444字 ⁄ 字号 评论关闭

为下周实习做准备,实现一个简单的数据库连接池

 

连接池主要的功能有:

1、提供一个方法,从连接池获得一个连接

2、提供一个把一个连接放回连接池的方法

 

编写连接池调用接口

连接池除提供基本功能外,还应该支持设置连接属性,已经调试功能等。下面编写连接池接口类

package connectionPool;

import java.sql.SQLException;

import com.mysql.jdbc.Connection;

/**
 * 数据库连接池接口类
 * @author Administrator
 *
 */
public interface ConnectionPool {
	
	/**
	 * 设置数据库连接信息
	 * @param url 连接地址
	 * @param username 用户名
	 * @param password 密码
	 */
	public void setConnect(String url, String username, String password);

	/** 
	 * 获得一个数据库连接 
	 * @throws SQLException  
	 */
	public Connection get() throws SQLException;
	
	/** 
	 * 关闭一个数据库连接 
	 * @throws SQLException
	 */
	public void close(Connection conn) throws SQLException;
	
	/**
	 * 打印调试信息
	 */
	public void printDebug();
	
}
 
连接池处于数据的持久化层,为了更好的扩展性,编写一个创建连接池的工厂类
package connectionPool;

/**
 * 创建连接池的工厂类
 * @author Administrator
 *
 */
public class ConnectionPoolFactory {

	/**
	 * 取得连接池类的一个实例
	 * @param name 连接池类的名字(必须处于connectionPool包下)
	 * @return 连接池类的一个实例
	 */
	public static ConnectionPool getConnectionPool(String name) {
		try {
			return (ConnectionPool) Class.forName("connectionPool." + name).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
}

 

编写一个简单的连接池

下面以MySQL为例,编写一个连接池
package connectionPool;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Driver;

/**
 * MySQL数据库连接池
 * @author 石莹
 * @since 1.0
 *
 */
public class MySQLConnection implements ConnectionPool {
	
	private static final int FREE_AND_USED_RATIO = 1;

	private static String m_url = "";
	private static String m_user = "";
	private static String m_password = "";
	
	private static LinkedList freeConn = new LinkedList();
	private static LinkedList usedConn = new LinkedList();

	static {
		//当类加载时,自动加载并初始化JDBC驱动
		initDriver();
	}

	/** 加载JDBC驱动 */
	private static void initDriver() {
		Driver driver = null;
		try {
			driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();
			installDriver(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** 注册安装JDBC驱动 */
	private static void installDriver(Driver driver) {
		try {
			DriverManager.registerDriver(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public synchronized Connection get() throws SQLException {
		Connection conn = null;
		if (freeConn.isEmpty()) {
			conn = (Connection) DriverManager.getConnection(m_url, m_user, m_password);
		} else {
			//取出一个连接并且检查是否关闭,防止用户误操作调用了conn.close();
			while (true) {
				conn = freeConn.removeFirst();
				if (!conn.isClosed()) {
					break;
				} else {
					if (!freeConn.isEmpty()) {
						continue;
					} else {
						conn = (Connection) DriverManager.getConnection(m_url, m_user, m_password);
						break;
					}
				}
			}
		}
		usedConn.add(conn);
		return conn;
	}

	@Override
	public synchronized void close(Connection conn) throws SQLException {
		usedConn.remove(conn);
		if (freeConn.size() > usedConn.size() * FREE_AND_USED_RATIO) {
			conn.close();
		} else {
			freeConn.add(conn);
		}
	}

	/**
	 * 创建一个新的连接
	 * @return 创建的连接
	 * @throws SQLException
	 */
	protected Connection getNewConnection() throws SQLException {
		Connection conn = (Connection) DriverManager.getConnection(m_url, m_user, m_password);
		return conn;
	}

	public String getUrl() {
		return m_url;
	}

	public void setUrl(String mUrl) {
		m_url = mUrl;
	}

	public String getUserName() {
		return m_user;
	}

	public void setUserName(String mUser) {
		m_user = mUser;
	}

	public String getPassword() {
		return m_password;
	}

	public void setPassword(String mPassword) {
		m_password = mPassword;
	}

	@Override
	public void setConnect(String url, String username, String password) {
		this.setUrl(url);
		this.setUserName(username);
		this.setPassword(password);
	}
	
	@Override
	public void printDebug() {
		System.out.println("Free conn num : " + freeConn.size() + "/tUsed conn num : " + usedConn.size());
	}
}

 

测试程序

import java.sql.SQLException;

import com.mysql.jdbc.Connection;

import connectionPool.ConnectionPool;
import connectionPool.ConnectionPoolFactory;



public class test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		ConnectionPool cp = ConnectionPoolFactory.getConnectionPool("MySQLConnection");
		
		cp.setConnect("jdbc:mysql://localhost:3306/test?characterEncoding=gbk", "root", "");
		
		try {
			System.out.println("测试创建新连接是否正常");
			cp.printDebug();
			Connection conn = cp.get();
			cp.printDebug();
			
			System.out.println("测试用户误操作调用close后,下次获得连接是否正常");
			conn.close();
			cp.close(conn);
			cp.printDebug();
			conn = cp.get();
			System.out.println("conn is Closed : " + conn.isClosed());
			
			System.out.println("测试释放连接是否正常");
			Connection c1 = cp.get();
			Connection c2 = cp.get();
			cp.printDebug();
			cp.close(conn);
			cp.close(c1);
			cp.close(c2);
			cp.printDebug();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
命令行下打印测试结果

测试创建新连接是否正常
Free conn num : 0    Used conn num : 0
Free conn num : 0    Used conn num : 1
测试用户误操作调用close后,工作是否正常
Free conn num : 1    Used conn num : 0
conn is Closed : false
测试释放连接是否正常
Free conn num : 0    Used conn num : 3
Free conn num : 2    Used conn num : 0

抱歉!评论已关闭.