使用抽象工厂模式简单模拟数据库连接池

使用抽象工厂模式模拟JDBC连接池

工厂方法模式
简单工厂模式
抽象工厂模式

1.连接池

连接池:连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。

在这里我使用抽象工厂模式简单模拟数据库连接池

2.准备

首先搞清楚抽象工厂中的四个角色

我们需要的是一个可用直接拿到数据库连接的池,因此具体对象就是数据库的连接池,抽象对象就是数据库连接对象Connection对象,

抽象工厂里面定义数据库连接池的通用行为,创建一个连接池,拿到一个连接,回收一个连接。

具体工厂继承抽象工厂同时细化连接池的行为,比如获取当前可用连接等等。

抽象工厂:连接池的通用行为

具体工厂:继承抽象工厂,并提供该连接池的具体行为

抽象对象:Connection

具体对象:数据库的连接池

搞清楚这些就可以开始动手了

3.实现

抽象工厂:

public	abstract class Pool {

	public Driver driver = null;//驱动对象
	
	public String propertiesName = "jdbc.properties";//配置文件名称
	
	public int normalConnect = 10;//保持连接数
	
	public String driverName = null;//驱动字符串
	
	public String username;//用户名
	
	public String password;//密码
	
	public String url;//地址
	
	
	{//静态代码块初始化成员变量
		InputStream is = Pool.class.getResourceAsStream(propertiesName);
		Properties p = new Properties();
		//加载配置文件
		try {
			p.load(is);
			this.driverName = p.getProperty("driverName");
			this.username = p.getProperty("username");
			this.password = p.getProperty("password");
			this.url = p.getProperty("url");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 注册JDBC驱动
	 */
	@SuppressWarnings("deprecation")
	public void loadDriver() {
		try {
			Driver driver = (Driver) Class.forName(driverName).newInstance();
			this.driver = driver;
			System.out.println("驱动注册成功"+driverName);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("驱动注册失败检查驱动字符串是否正确");
		}
	}
	
	
	/**
	 * 从连接池中拿到一个连接
	 * @return
	 */
	public abstract Connection getConnection();
	
	
	/**
	 * 把一个连接返回连接池
	 * @param con 连接对象
	 */
	public abstract void freeConnection(Connection con);
	
	
	/**
	 * 关闭所有的连接,撤销驱动注册
	 */
	public abstract void release();
	
}

具体工厂:

public class DBconnectionPool extends Pool {

	// 空闲连接
	private int num = 0;
	// 存储连接的容器
	private Vector<Connection> freeConnections = new Vector<Connection>();

	/**
	 * 初始化
	 */
	public DBconnectionPool() {
		super.loadDriver();// 加载驱动
		for (int i = 0; i < normalConnect; i++) {// 创建连接
			freeConnections.add(newConnection());
			num++;
		}
	}

	/**
	 * 从连接池中拿到一个连接
	 * 
	 * @return
	 */
	@Override
	public Connection getConnection() {
		if (freeConnections.size() > 0) {// 连接池中有空闲连接
			Connection con = freeConnections.get(0);
			freeConnections.removeElementAt(0);
			num--;
			System.out.println("客户端拿取了一个连接"+con);
			return con;
		}
		System.out.println("连接池无可用连接");
		return null;
	}

	/**
	 * 把一个连接返回连接池
	 * 
	 * @param con 连接对象
	 */
	@Override
	public void freeConnection(Connection con) {
		freeConnections.add(con);
		num++;
		System.out.println("客户端放回了一个连接");
	}

	/**
	 * 关闭连接,并注销驱动
	 */
	@Override
	public void release() {
		freeConnections.removeAllElements();//移除所有连接
		num=0;
		try {
			DriverManager.deregisterDriver(driver);//注销驱动
		} catch (SQLException e) {
			e.printStackTrace();
			System.out.println("驱动注销失败");
		}
		System.out.println("连接池已经关闭");
	}

	/**
	 * 创建一个连接
	 * 
	 * @return
	 * @throws SQLException
	 */
	public Connection newConnection() {
		try {
			Connection con = DriverManager.getConnection(url, username, password);
			System.out.println("连接池创建了一个连接");
			return con;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("连接创建失败");
			return null;
		}
	}

	/**
	 * 返回可用连接
	 * 
	 * @return
	 */
	public int getNum() {
		return num;
	}

}

客户端调用

public class Client {

	public static void main(String[] args) throws SQLException {
		//创建连接池
		DBconnectionPool pool = new	DBconnectionPool();
		System.out.println(pool.getNum());//10
		//拿到一个连接
		Connection con1 = pool.getConnection();
		pool.getConnection();//再次获取
		
		System.out.println(pool.getNum());//8
		
		pool.freeConnection(con1);//放回一个连接
		con1.close();
		System.out.println(pool.getNum());//9
		pool.release();//注销连接池
		pool.getConnection();//这个时候已经连接池中已经没有可用的连接了
	}
	
}

在这里插入图片描述
配置文件
在这里插入图片描述

tip:连接数据库需要一个jar包(mysql-connector-java.jar)

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值