设计模式之工厂模式(数据库连接)

项目结构

代码

 db.properties

driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://127.0.0.1:1433;databasename=weixinDB_yc
username=HQ
password=HQ
maxConnect=50
normalConnect=5

 

Pool.java

package com.chen.jdbc.sqlhelper;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.Vector;

/**
*@author  chenmin
*@version 创建时间:2020年5月21日 下午3:35:52
*
*/
public abstract class Pool {

	protected String propertiesName = "/config/db.properties";
	
	protected int maxConnect = 100;//最大连接数
	
	protected int normalConnect = 10;//保持连接数
	
	protected String driverName = null;
	
	protected Driver driver = null;
	
	protected String password = null;
	
	protected String url = null;
	
	protected String userName = null;
	
	protected Vector<Connection> freeConnections = new Vector<Connection>();//存放产生的连接对象容器
	
	
	protected int checkedOut = 0;//正在使用的连接数
	
	protected static int num = 0;//空闲连接数
	
	protected static int numActive = 0;//当前可用的连接数
	
	//私有构造函数
	protected Pool(){}
	
	//装载和注册所有jdbc驱动程序
	protected void loadDriver(String dri){
		String driverName = dri;
		
		try {
			driver = (Driver)Class.forName(driverName).newInstance();
			DriverManager.registerDriver(driver);
			System.out.println("成功注册jdbc驱动程序"+driverName);
		} catch (Exception e) {
			System.out.println("无法注册jdbc驱动程序:"+driverName+",错误:"+e);
		}
	}
	
	//创建连接池
	public abstract void createPool();
	
	//获取一个可用的连接,如果没有则创建一个连接,且小于最大连接限制
	public abstract Connection getConnection();
	
	//获取一个连接,有时间限制
	public abstract Connection getConnection(long time);
	
	//将连接对象返回给连接池
	public abstract void freeConnection(Connection conn);
	
	//释放连接
	public abstract void release();
	
	//返回当前空闲的连接数
	public abstract int getNum();
	
	//返回当前工作的连接数
	public abstract int getNumActive();
	
}

DBConnectionPool

package com.chen.jdbc.sqlhelper;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

/**
*@author  chenmin
*@version 创建时间:2020年5月21日 下午4:14:17
*
*/
public class DBConnectionPool extends Pool {
	
	
	
	private static DBConnectionPool pool = null;//连接池实例变量
	
	//构造函数
	private DBConnectionPool() {
		try {
			init();
			for(int i = 0;i < normalConnect;i++){
				Connection conn = newConnection();
				if(conn != null){
					freeConnections.add(conn);//往容器中添加一个连接对象
					num++;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//初始化
	private void init() throws IOException{
		InputStream is = DBConnectionPool.class.getResourceAsStream(propertiesName);
		Properties properties = new Properties();
		properties.load(is);
		this.userName = properties.getProperty("username");
		this.password = properties.getProperty("password");
		this.driverName = properties.getProperty("driver");
		this.url = properties.getProperty("url");
		this.maxConnect = Integer.parseInt(properties.getProperty("maxConnect"));
		this.normalConnect = Integer.parseInt(properties.getProperty("normalConnect"));
	}
	
	//创建一个新连接
	private Connection newConnection(){
		Connection conn = null;
		try {
			if(userName == null){//用户名和密码都是空的
				conn = DriverManager.getConnection(url);
			}else{
				conn = DriverManager.getConnection(url, userName, password);
			}
			System.out.println("连接池创建一个新的连接");
		} catch (Exception e) {
			System.out.println("无法创建这个url的连接"+url);
			return null;
		}
		
		return conn;
	}
	
	public static synchronized DBConnectionPool getInstance(){
		if(pool == null){
			pool = new DBConnectionPool();
		}
		return pool;
	}
	
	@Override
	public void createPool() {
		
	}

	@Override
	public Connection getConnection() {
		Connection connection = null;
		if(freeConnections.size() > 0){//还有空闲的连接
			num--;
			connection = freeConnections.firstElement();
			freeConnections.removeElementAt(0);
			try {
				if(connection.isClosed()){
					System.out.println("从连接池中删除一个无效的连接");
					//再次获取
					connection = getConnection();
				}
			} catch (Exception e) {
				System.out.println("从连接池中删除一个无效的连接");
				connection = getConnection();
			}
		}else if(maxConnect == 0 || checkedOut < maxConnect){
			connection = newConnection();
		}
		
		if(connection != null){
			checkedOut++;
		}
		numActive++;
		return connection;
	}

	@Override
	public Connection getConnection(long time) {
		long startTime = new Date().getTime();
		Connection connection = null;
		
		connection = getConnection();
		
		while(connection == null){
			try {
				wait(time);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if((new Date().getTime() - startTime) >= time){
				return null;//如果超时则返回
			}
			
			connection = getConnection();
		}
		return connection;
	}

	@Override
	public synchronized void freeConnection(Connection conn) {
		freeConnections.addElement(conn);
		num++;
		checkedOut--;
		numActive--;
		notifyAll();//解锁
	}

	@Override
	public int getNum() {
		
		return num;
	}

	@Override
	public int getNumActive() {
		
		return numActive;
	}

	//关闭所有连接
	@Override
	public synchronized void release(){
		try {
			//将当前连接赋值到枚举中
			Enumeration allConnections = freeConnections.elements();
			//使用循环关闭所有链接
			while(allConnections.hasMoreElements()){
				Connection connection = (Connection)allConnections.nextElement();
				try {
					connection.close();
					
					num--;
					
					System.out.println("释放连接!");
				} catch (Exception e) {
					System.out.println("无法关闭连接池中的连接:"+e);
				}
			}
			freeConnections.removeAllElements();
			numActive = 0;
		} catch(Exception e){
			e.printStackTrace();
		}
	}
}

你们还有什么好的写法吗?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章