設計模式之工廠模式(數據庫連接)

項目結構

代碼

 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();
		}
	}
}

你們還有什麼好的寫法嗎?

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