为下周实习做准备,实现一个简单的数据库连接池
连接池主要的功能有:
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