即使世界明天毀滅,我也要在今天種下我的葡萄樹。
          posts - 112, comments - 14, trackbacks - 0, articles - 11

          關于ORACLE連接池

          Posted on 2006-05-26 11:24 閱讀(252) 評論(0)  編輯  收藏 所屬分類: DateBase Design

          到目前為目,JDBC2的連結池只是一個接口,沒有真正的實現,JDBC3正在開發中,據報已經支持連結池,但JDBC3用了JNDI技術,連結池的配置可以讓一個高手都煩死.

          目前第三方已經實現的連結池當然是poolman,1.0版對一般用戶來說已經足夠用了.配置也簡單,2.0版雖然增加了一些功能,但配置也是采用JNDI,對RMI和EJB不懂的朋友可能很煩.建議用1.0的了.

          如果有興趣,自己也可以實現連結池,最關鍵的技術也就是把連結作為參數傳給一個BEAN,用完后返回這個參數連結而不是關閉.
          下面是一個簡單的實現:
          DBConnectionManager.java程序清單如下:

          001 import java.io.*;
          002 import java.sql.*;
          003 import java.util.*;
          004 import java.util.Date;
          005
          006 /**
          007 * 管理類DBConnectionManager支持對一個或多個由屬性文件定義的數據庫連接
          008 * 池的訪問.客戶程序可以調用getInstance()方法訪問本類的唯一實例.
          009 */
          010 public class DBConnectionManager {
          011 static private DBConnectionManager instance; // 唯一實例
          012 static private int clients;
          013
          014 private Vector drivers = new Vector();
          015 private PrintWriter log;
          016 private Hashtable pools = new Hashtable();
          017
          018 /**
          019 * 返回唯一實例.如果是第一次調用此方法,則創建實例
          020 *
          021 * @return DBConnectionManager 唯一實例
          022 */
          023 static synchronized public DBConnectionManager getInstance() {
          024 if (instance == null) {
          025 instance = new DBConnectionManager();
          026 }
          027 clients++;
          028 return instance;
          029 }
          030
          031 /**
          032 * 建構函數私有以防止其它對象創建本類實例
          033 */
          034 private DBConnectionManager() {
          035 init();
          036 }
          037
          038 /**
          039 * 將連接對象返回給由名字指定的連接池
          040 *
          041 * @param name 在屬性文件中定義的連接池名字
          042 * @param con 連接對象\\r

          043 */
          044 public void freeConnection(String name, Connection con) {
          045 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
          046 if (pool != null) {
          047 pool.freeConnection(con);
          048 }
          049 }
          050
          051 /**
          052 * 獲得一個可用的(空閑的)連接.如果沒有可用連接,且已有連接數小于最大連接數
          053 * 限制,則創建并返回新連接
          054 *
          055 * @param name 在屬性文件中定義的連接池名字
          056 * @return Connection 可用連接或null
          057 */
          058 public Connection getConnection(String name) {
          059 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
          060 if (pool != null) {
          061 return pool.getConnection();
          062 }
          063 return null;
          064 }
          065
          066 /**
          067 * 獲得一個可用連接.若沒有可用連接,且已有連接數小于最大連接數限制,
          068 * 則創建并返回新連接.否則,在指定的時間內等待其它線程釋放連接.
          069 *
          070 * @param name 連接池名字
          071 * @param time 以毫秒計的等待時間\\r

          072 * @return Connection 可用連接或null
          073 */
          074 public Connection getConnection(String name, long time) {
          075 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
          076 if (pool != null) {
          077 return pool.getConnection(time);
          078 }
          079 return null;
          080 }
          081
          082 /**
          083 * 關閉所有連接,撤銷驅動程序的注冊\\r

          084 */
          085 public synchronized void release() {
          086 // 等待直到最后一個客戶程序調用
          087 if (--clients != 0) {
          088 return;
          089 }
          090
          091 Enumeration allPools = pools.elements();
          092 while (allPools.hasMoreElements()) {
          093 DBConnectionPool pool = (DBConnectionPool

          ) allPools.nextElement();
          094 pool.release();
          095 }
          096 Enumeration allDrivers = drivers.elements();
          097 while (allDrivers.hasMoreElements()) {
          098 Driver driver = (Driver) allDrivers.nextElement();
          099 try {
          100 DriverManager.deregisterDriver(driver);
          101 log("撤銷JDBC驅動程序 " + driver.getClass().getName()+"的注冊\\\");
          102 }
          103 catch (SQLException e) {
          104 log(e, "無法撤銷下列JDBC驅動程序的注冊: " + driver.getClass().getName());
          105 }
          106 }
          107 }
          108
          109 /**
          110 * 根據指定屬性創建連接池實例.
          111 *
          112 * @param props 連接池屬性
          113 */
          114 private void createPools(Properties props) {
          115 Enumeration propNames = props.propertyNames();
          116 while (propNames.hasMoreElements()) {
          117 String name = (String) propNames.nextElement();
          118 if (name.endsWith(".url")) {
          119 String poolName = name.substring(0, name.lastIndexOf("."));
          120 String url = props.getProperty(poolName + ".url");
          121 if (url == null) {
          122 log("沒有為連接池" + poolName + "指定URL");
          123 continue;
          124 }
          125 String user = props.getProperty(poolName + ".user");
          126 String password = props.getProperty(poolName + ".password");
          127 String maxconn = props.getProperty(poolName + ".maxconn", "0");
          128 int max;
          129 try {
          130 max = Integer.valueOf(maxconn).intValue();
          131 }
          132 catch (NumberFormatException e) {
          133 log("錯誤的最大連接數限制: " + maxconn + " .連接池: " + poolName);
          134 max = 0;
          135 }
          136 DBConnectionPool pool =
          137 new DBConnectionPool(poolName, url, user, password, max);
          138 pools.put(poolName, pool);
          139 log("成功創建連接池" + poolName);
          140 }
          141 }
          142 }
          143
          144 /**
          145 * 讀取屬性完成初始化
          146 */
          147 private void init() {
          148 InputStream is = getClass().getResourceAsStream("/db.properties");
          149 Properties dbProps = new Properties();
          150 try {
          151 dbProps.load(is);
          152 }
          153 catch (Exception e) {
          154 System.err.println("不能讀取屬性文件. " +
          155 "請確保db.properties在CLASSPATH指定的路徑中");
          156 return;
          157 }
          158 String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
          159 try {
          160 log = new PrintWriter(new FileWriter(logFile, true), true);
          161 }
          162 catch (IOException e) {
          163 System.err.println("無法打開日志文件: " + logFile);
          164 log = new PrintWriter(System.err);
          165 }
          166 loadDrivers(dbProps);
          167 createPools(dbProps);
          168 }
          169
          170 /**
          171 * 裝載和注冊所有JDBC驅動程序\\r

          主站蜘蛛池模板: 乌兰察布市| 塔河县| 长武县| 禹城市| 松溪县| 邳州市| 金堂县| 舒城县| 孟州市| 吉木萨尔县| 资源县| 馆陶县| 鄂伦春自治旗| 惠州市| 班戈县| 芦山县| 昌宁县| 黄平县| 贡嘎县| 永修县| 汾阳市| 手游| 西林县| 太康县| 牙克石市| 奇台县| 弋阳县| 进贤县| 三河市| 岳阳市| 梨树县| 泸定县| 津南区| 海门市| 梧州市| 湖南省| 健康| 博爱县| 浮梁县| 颍上县| 浦城县|