?? dbconnectionmanager.java
字號:
*/
public synchronized void release() {
Enumeration allConnections = freeConnections.elements();
while (allConnections.hasMoreElements()) { //freeConnections對象存在
Connection con = (Connection) allConnections.nextElement(); //取出所有的數(shù)組
try {
con.close(); //嘗試關(guān)閉
Debug.writeLog("關(guān)閉連接池" + name + "中的一個連接");
}
catch (SQLException e) {
Debug.writeLog("無法關(guān)閉連接池" + name + "中的連接");
e.printStackTrace(System.out);
}
}
freeConnections.removeAllElements(); //清空
}
}
/**
* *****************************************************************
* 建構(gòu)函數(shù)私有以防止其它對象創(chuàng)建本類實例
* 其它對象能夠調(diào)用其靜態(tài)方法(也稱為類方法)獲得該唯一實例的引用
* DBConnectionManager類的建構(gòu)函數(shù)是私有的,這是為了避免其它對象創(chuàng)建該類的實例。
*/
private DBConnectionManager() {
init();
}
/**
*
* @param props 連接池屬性
*/
private void createPools(Properties props) {
Enumeration propNames = props.propertyNames(); //創(chuàng)建枚舉對象----該對象可以想象為一個元素系列,逐次調(diào)用其nextElement()方法將順序返回各元素
while (propNames.hasMoreElements()) { //如果有枚舉對象存在
String name = (String) propNames.nextElement(); //取出值格式為字符串
Debug.writeLog("createPools(Properties), name is: " + name); //3、logPath 將路徑名寫入日志
/**
* 在其中搜索名字以“.url”結(jié)尾的屬性
* 對于每一個符合條件的屬性,先提取其連接池名字部分,進(jìn)而讀取所有屬于該連接池的屬性
*/
if (name.endsWith(".url")) {
Debug.writeLog("createPools(Properties), name end with url"); //5
String poolName = name.substring(0, name.lastIndexOf(".")); //取出“.”之前的字符串(連接池的名字)
String url = props.getProperty(poolName + ".url"); //4、Connection.url 取得URL
Debug.writeLog("createPools(Properties), url is " + url); //6、jdbc:mysql://127.0.0.1:3306/nt 寫入數(shù)據(jù)庫的url"jdbc:mysql://127.0.0.1:3306/數(shù)據(jù)名"
if (url == null) { //如果URL為空,寫入日志顯示沒有找到指定的URL
Debug.writeLog("沒有為連接池" + poolName + "指定URL");
continue; //跳出本次循環(huán)
}
String user = props.getProperty(poolName + ".user"); //用戶名
String password = props.getProperty(poolName + ".password"); //密碼
String maxconn = props.getProperty(poolName + ".maxconn", "0"); //最大連接數(shù)
int max; //定義一個整形變量
try {
max = Integer.valueOf(maxconn).intValue(); //取得最大連接數(shù)的值
}
catch (NumberFormatException e) {
Debug.writeLog("錯誤的最大連接數(shù)限制: " + maxconn + " .連接池: " +
poolName);
max = 0;
}
//創(chuàng)建連接池對象并把它保存在實例變量pools中
DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max);
//散列表(Hashtable類 )pools實現(xiàn)連接池名字到連接池對象之間的映射,此處以連接池名字為鍵,連接池對象為值。
pools.put(poolName, pool);
Debug.writeLog("成功創(chuàng)建連接池" + poolName); //12、成功創(chuàng)建連接池Connection
}
}
}
/**
* 將連接對象返回給由名字指定的連接池
* @param name 在屬性文件中定義的連接池名字
* @param con 連接對象
*/
public void freeConnection(String name, Connection con) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
pool.freeConnection(con);
}
}
/**
* 獲得一個可用的(空閑的)連接.如果沒有可用連接,且已有連接數(shù)小于最大連接數(shù)
* 限制,則創(chuàng)建并返回新連接
* @param name 在屬性文件中定義的連接池名字
* @return Connection 可用連接或null
*/
public Connection getConnection(String name) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
Debug.writeLog(
"DBConnectionManager getConnection(String) ! pool is not null !"); //20
return pool.getConnection();
}
return null;
}
/**
* 獲得一個可用連接.若沒有可用連接,且已有連接數(shù)小于最大連接數(shù)限制,
* 則創(chuàng)建并返回新連接.否則,在指定的時間內(nèi)等待其它線程釋放連接.
* @param name 連接池名字
* @param time 以毫秒計的等待時間
* @return Connection 可用連接或null
*/
public Connection getConnection(String name, long time) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
return pool.getConnection(time);
}
return null;
}
/**
* 其引用就一直保存在靜態(tài)變量instance中
* 每次調(diào)用getInstance()都增加一個DBConnectionManager的客戶程序計數(shù)。
* 該計數(shù)代表引用DBConnectionManager唯一實例的客戶程序總數(shù),它將被用于控制連接池的關(guān)閉操作。
* @return 返回唯一實例.如果是第一次調(diào)用此方法,則創(chuàng)建實例
*/
public static synchronized DBConnectionManager getInstance() {
if (instance == null) {
instance = new DBConnectionManager();
}
clients++; //對客戶端的訪問計數(shù)
return instance;
}
/**
* 讀取屬性完成初始化
*/
private void init() {
//[配置文件路徑(ISiteEnvironment.ConfigFile)]調(diào)用EnvironmentConfig的getProperties()方法
Properties dbProps = EnvironmentConfig.getInstance().getProperties(
ISiteEnvironment.ConfigFile);
loadDrivers(dbProps); //裝載驅(qū)動
createPools(dbProps); //調(diào)用私有方法createPools()創(chuàng)建連接池對象
}
/**
* 裝載和注冊所有JDBC驅(qū)動程序
* 該方法先用StringTokenizer將drivers屬性值分割為對應(yīng)于驅(qū)動程序名稱的字符串
*
* @param props 屬性
*/
private void loadDrivers(Properties props) {
String driverClasses = props.getProperty("drivers");
StringTokenizer st = new StringTokenizer(driverClasses);
while (st.hasMoreElements()) {
String driverClassName = st.nextToken().trim(); //取得驅(qū)動程序org.gjt.mm.mysql.Driver
try {
Driver driver = (Driver) Class.forName(driverClassName).
newInstance();
DriverManager.registerDriver(driver);
Debug.writeLog("Load Driver Success !"); //1、加載驅(qū)動成功
drivers.addElement(driver);
Debug.writeLog("成功注冊JDBC驅(qū)動程序" + driverClassName); //2、加載JDBC驅(qū)動程序org.gjt.mm.mysql.Driver
}
catch (Exception e) {
Debug.writeLog("無法注冊JDBC驅(qū)動程序: " + driverClassName + ", 錯誤: " + e);
}
}
}
/**
* 客戶程序在關(guān)閉時調(diào)用release()可以遞減該計數(shù)。
* 當(dāng)最后一個客戶程序調(diào)用release(),遞減后的引用計數(shù)為0,就可以調(diào)用各個連接池的release()方法關(guān)閉所有連接了。
* 關(guān)閉所有連接,撤銷驅(qū)動程序的注冊
*/
public synchronized void release() { //等待直到最后一個客戶程序調(diào)用
if (--clients != 0) {
return;
}
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements()) {
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while (allDrivers.hasMoreElements()) {
Driver driver = (Driver) allDrivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
Debug.writeLog("撤銷JDBC驅(qū)動程序 " + driver.getClass().getName() + "的注冊");
}
catch (SQLException e) {
Debug.writeLog("無法撤銷下列JDBC驅(qū)動程序的注冊: " + driver.getClass().getName());
e.printStackTrace(System.out);
}
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -