數據庫連接池技術

          要下班了,先把代碼貼上來,明天有時間來加說明。
          package?com;

          import?java.io.Serializable;

          public?class?ConnectionParam?implements?Serializable?{
          ????
          private?String?driver;?//?數據庫驅動程序

          ????
          private?String?url;?//?數據連接的URL

          ????
          private?String?user;?//?數據庫用戶名

          ????
          private?String?password;?//?數據庫密碼

          ????
          private?int?minConnection?=?0;?//?初始化連接數

          ????
          private?int?maxConnection?=?50;?//?最大連接數

          ????
          private?long?timeoutValue?=?600000;//?連接的最大空閑時間

          ????
          private?long?waitTime?=?30000;?//?取連接的時候如果沒有可用連接最大的等待時間

          ????
          public?ConnectionParam(String?driver,?String?url,?String?user,
          ????????????String?password)?
          {
          ????????
          super();
          ????????
          this.driver?=?driver;
          ????????
          this.password?=?password;
          ????????
          this.url?=?url;
          ????????
          this.user?=?user;
          ????}


          ????
          public?String?getDriver()?{
          ????????
          return?driver;
          ????}


          ????
          public?void?setDriver(String?driver)?{
          ????????
          this.driver?=?driver;
          ????}


          ????
          public?int?getMaxConnection()?{
          ????????
          return?maxConnection;
          ????}


          ????
          public?void?setMaxConnection(int?maxConnection)?{
          ????????
          this.maxConnection?=?maxConnection;
          ????}


          ????
          public?int?getMinConnection()?{
          ????????
          return?minConnection;
          ????}


          ????
          public?void?setMinConnection(int?minConnection)?{
          ????????
          this.minConnection?=?minConnection;
          ????}


          ????
          public?String?getPassword()?{
          ????????
          return?password;
          ????}


          ????
          public?void?setPassword(String?password)?{
          ????????
          this.password?=?password;
          ????}


          ????
          public?long?getTimeoutValue()?{
          ????????
          return?timeoutValue;
          ????}


          ????
          public?void?setTimeoutValue(long?timeoutValue)?{
          ????????
          this.timeoutValue?=?timeoutValue;
          ????}


          ????
          public?String?getUrl()?{
          ????????
          return?url;
          ????}


          ????
          public?void?setUrl(String?url)?{
          ????????
          this.url?=?url;
          ????}


          ????
          public?String?getUser()?{
          ????????
          return?user;
          ????}


          ????
          public?void?setUser(String?user)?{
          ????????
          this.user?=?user;
          ????}


          ????
          public?long?getWaitTime()?{
          ????????
          return?waitTime;
          ????}


          ????
          public?void?setWaitTime(long?waitTime)?{
          ????????
          this.waitTime?=?waitTime;
          ????}


          }

          DataSourceImpl類:
          package?com;

          import?java.io.PrintWriter;
          import?java.sql.Connection;
          import?java.sql.DriverManager;
          import?java.sql.SQLException;

          import?javax.sql.DataSource;

          public?class?DataSourceImpl?implements?DataSource?{

          ????
          private?ConnectionParam?param?;
          ????
          private?Connection?conn?;
          ????
          ????
          public?void?initConnection(){
          ????????
          try{
          ????????????Class.forName(param.getDriver());
          ????????????conn?
          =?DriverManager.getConnection(param.getUrl(),param.getUser(),param.getPassword());
          ????????}
          catch(Exception?e){}
          ????}


          ????
          public?void?stop()?{

          ????}


          ????
          public?void?close()?{

          ????}


          ????
          public?DataSourceImpl(ConnectionParam?param)?{
          ????????
          this.param?=?param;
          ????}


          ????
          public?Connection?getConnection()?throws?SQLException?{
          ????????
          return?conn;
          ????}


          ????
          public?Connection?getConnection(String?username,?String?password)
          ????????????
          throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????return?null;
          ????}


          ????
          public?PrintWriter?getLogWriter()?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????return?null;
          ????}


          ????
          public?void?setLogWriter(PrintWriter?out)?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub

          ????}


          ????
          public?void?setLoginTimeout(int?seconds)?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub

          ????}


          ????
          public?int?getLoginTimeout()?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????return?0;
          ????}


          ????
          public?Object?unwrap(Class?arg0)?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????return?null;
          ????}


          ????
          public?boolean?isWrapperFor(Class?arg0)?throws?SQLException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????return?false;
          ????}


          }

          代理接管連接關閉(Connection.close())的類_Connection:
          package?com;

          import?java.lang.reflect.InvocationHandler;
          import?java.lang.reflect.Method;
          import?java.lang.reflect.Proxy;
          import?java.sql.Connection;
          import?java.sql.SQLException;

          public?class?_Connection?implements?InvocationHandler?{

          ????
          private?final?static?String?CLOSE_METHOD_NAME?=?"close";

          ????
          private?Connection?conn?=?null;

          ????
          //?數據庫的忙狀態
          ????private?boolean?inUse?=?false;

          ????
          //?用戶最后一次訪問該連接方法的時間
          ????private?long?lastAccessTime?=?System.currentTimeMillis();

          ????_Connection(Connection?conn,?
          boolean?inUse)?{
          ????????
          this.conn?=?conn;
          ????????
          this.inUse?=?inUse;
          ????}


          ????
          /**
          ?????*?Returns?the?conn.
          ?????*?
          ?????*?
          @return?Connection
          ?????
          */

          ????
          public?Connection?getConnection()?{
          ????????
          //?返回數據庫連接conn的接管類,以便截住close方法
          ????????Connection?conn2?=?(Connection)?Proxy.newProxyInstance(conn.getClass()
          ????????????????.getClassLoader(),?conn.getClass().getInterfaces(),?
          this);
          ????????
          return?conn2;
          ????}


          ????
          /**
          ?????*?該方法真正的關閉了數據庫的連接
          ?????*?
          ?????*?
          @throws?SQLException
          ?????
          */

          ????
          void?close()?throws?SQLException?{
          ????????
          //?由于類屬性conn是沒有被接管的連接,因此一旦調用close方法后就直接關閉連接
          ????????conn.close();
          ????}


          ????
          /**
          ?????*?Returns?the?inUse.
          ?????*?
          ?????*?
          @return?boolean
          ?????
          */

          ????
          public?boolean?isInUse()?{
          ????????
          return?inUse;
          ????}


          ????
          /**
          ?????*?
          @see?java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
          ?????*??????java.lang.reflect.Method,?java.lang.Object)
          ?????
          */

          ????
          public?Object?invoke(Object?proxy,?Method?m,?Object[]?args)
          ????????????
          throws?Throwable?{
          ????????Object?obj?
          =?null;
          ????????
          //?判斷是否調用了close的方法,如果調用close方法則把連接置為無用狀態
          ????????if?(CLOSE_METHOD_NAME.equals(m.getName()))
          ????????????setInUse(
          false);
          ????????
          else
          ????????????obj?
          =?m.invoke(conn,?args);
          ????????
          //?設置最后一次訪問時間,以便及時清除超時的連接
          ????????lastAccessTime?=?System.currentTimeMillis();
          ????????
          return?obj;
          ????}


          ????
          /**
          ?????*?Returns?the?lastAccessTime.
          ?????*?
          ?????*?
          @return?long
          ?????
          */

          ????
          public?long?getLastAccessTime()?{
          ????????
          return?lastAccessTime;
          ????}


          ????
          /**
          ?????*?Sets?the?inUse.
          ?????*?
          ?????*?
          @param?inUse
          ?????*????????????The?inUse?to?set
          ?????
          */

          ????
          public?void?setInUse(boolean?inUse)?{
          ????????
          this.inUse?=?inUse;
          ????}


          }

          連接池管理類ConnectionFactory:
          package?com;

          import?java.sql.SQLException;
          import?java.util.Hashtable;

          import?javax.naming.NameAlreadyBoundException;
          import?javax.naming.NameNotFoundException;
          import?javax.sql.DataSource;

          /**
          ?*?連接池類廠,該類常用來保存多個數據源名稱合數據庫連接池對應的哈希
          ?*?
          @author?liusoft
          ?
          */

          public?class?ConnectionFactory
          {
          ????
          //該哈希表用來保存數據源名和連接池對象的關系表
          ????static?Hashtable?connectionPools?=?null;
          ????
          static{
          ????????connectionPools?
          =?new?Hashtable(2,0.75F);
          ????}
          ?
          ????
          /**
          ?????*?從連接池工廠中獲取指定名稱對應的連接池對象
          ?????*?
          @param?dataSource????連接池對象對應的名稱
          ?????*?
          @return?DataSource????返回名稱對應的連接池對象
          ?????*?
          @throws?NameNotFoundException????無法找到指定的連接池
          ?????
          */

          ????
          public?static?DataSource?lookup(String?dataSource)?
          ????????
          throws?NameNotFoundException
          ????
          {
          ????????Object?ds?
          =?null;
          ????????ds?
          =?connectionPools.get(dataSource);
          ????????
          if(ds?==?null?||?!(ds?instanceof?DataSource))
          ????????????
          throw?new?NameNotFoundException(dataSource);
          ????????
          return?(DataSource)ds;
          ????}

          ????
          /**
          ?????*?將指定的名字和數據庫連接配置綁定在一起并初始化數據庫連接池
          ?????*?
          @param?name????????對應連接池的名稱
          ?????*?
          @param?param????連接池的配置參數,具體請見類ConnectionParam
          ?????*?
          @return?DataSource????如果綁定成功后返回連接池對象
          ?????*?
          @throws?NameAlreadyBoundException????一定名字name已經綁定則拋出該異常
          ?????*?
          @throws?ClassNotFoundException????????無法找到連接池的配置中的驅動程序類
          ?????*?
          @throws?IllegalAccessException????????連接池配置中的驅動程序類有誤
          ?????*?
          @throws?InstantiationException????????無法實例化驅動程序類
          ?????*?
          @throws?SQLException????????????????無法正常連接指定的數據庫
          ?????
          */

          ????
          public?static?DataSource?bind(String?name,?ConnectionParam?param)
          ????????
          throws?NameAlreadyBoundException,ClassNotFoundException,
          ????????????????IllegalAccessException,InstantiationException,SQLException
          ????
          {
          ????????DataSourceImpl?source?
          =?null;
          ????????
          try{
          ????????????lookup(name);
          ????????????
          throw?new?NameAlreadyBoundException(name);
          ????????}
          catch(NameNotFoundException?e){
          ????????????source?
          =?new?DataSourceImpl(param);
          ????????????source.initConnection();?
          ????????????connectionPools.put(name,?source);
          ????????}

          ????????
          return?source;
          ????}

          ????
          /**
          ?????*?重新綁定數據庫連接池
          ?????*?
          @param?name????????對應連接池的名稱
          ?????*?
          @param?param????連接池的配置參數,具體請見類ConnectionParam
          ?????*?
          @return?DataSource????如果綁定成功后返回連接池對象
          ?????*?
          @throws?NameAlreadyBoundException????一定名字name已經綁定則拋出該異常
          ?????*?
          @throws?ClassNotFoundException????????無法找到連接池的配置中的驅動程序類
          ?????*?
          @throws?IllegalAccessException????????連接池配置中的驅動程序類有誤
          ?????*?
          @throws?InstantiationException????????無法實例化驅動程序類
          ?????*?
          @throws?SQLException????????????????無法正常連接指定的數據庫
          ?????
          */

          ????
          public?static?DataSource?rebind(String?name,?ConnectionParam?param)
          ????????
          throws?NameAlreadyBoundException,ClassNotFoundException,
          ????????????????IllegalAccessException,InstantiationException,SQLException
          ????
          {
          ????????
          try{
          ????????????unbind(name);
          ????????}
          catch(Exception?e){}
          ????????
          return?bind(name,?param);
          ????}

          ????
          /**
          ?????*?刪除一個數據庫連接池對象
          ?????*?
          @param?name
          ?????*?
          @throws?NameNotFoundException
          ?????
          */

          ????
          public?static?void?unbind(String?name)?throws?NameNotFoundException
          ????
          {
          ????????DataSource?dataSource?
          =?lookup(name);
          ????????
          if(dataSource?instanceof?DataSourceImpl){
          ????????????DataSourceImpl?dsi?
          =?(DataSourceImpl)dataSource;
          ????????????
          try{
          ????????????????dsi.stop();
          ????????????????dsi.close();
          ????????????}
          catch(Exception?e){
          ????????????}
          finally{
          ????????????????dsi?
          =?null;
          ????????????}

          ????????}

          ????????connectionPools.remove(name);
          ????}

          ????
          }


          測試主類:
          package?com;

          import?java.sql.Connection;
          import?java.sql.PreparedStatement;
          import?java.sql.ResultSet;

          import?javax.sql.DataSource;

          public?class?test?{

          ????
          public?static?void?main(String[]?args)?throws?Exception?{
          ????????String?name?
          =?"poolA";
          ????????String?driver?
          =?"oracle.jdbc.driver.OracleDriver";
          ????????String?url?
          =?"jdbc:oracle:thin:@127.0.0.1:1521:orcl";
          ????????ConnectionParam?param?
          =?new?ConnectionParam(driver,?url,?"zqbchina",
          ????????????????
          "password");
          ????????param.setMinConnection(
          1);
          ????????param.setMaxConnection(
          5);
          ????????param.setTimeoutValue(
          20000);
          ????????ConnectionFactory.bind(name,?param);
          ????????System.out.println(
          "bind?datasource?ok.");
          ????????
          //?以上代碼是用來登記一個連接池對象,該操作可以在程序初始化只做一次即可
          ????????
          //?以下開始就是使用者真正需要寫的代碼
          ????????DataSource?ds?=?ConnectionFactory.lookup(name);
          ????????String?sql?
          =?"select?name?from?tablea";
          ????????_Connection?_conn?
          =?null;
          ????????
          try?{
          ????????????
          for?(int?i?=?0;?i?<?10;?i++)?{
          ????????????????Connection?conn?
          =??ds.getConnection();
          ????????????????_conn?
          =?new?_Connection(conn,false);
          ????????????????conn?
          =?_conn.getConnection();
          ????????????????
          try?{
          ????????????????????testSQL(conn,?sql);
          ????????????????}
          ?finally?{
          ????????????????????
          try?{
          ????????????????????????conn.close();
          ????????????????????}
          ?catch?(Exception?e)?{
          ????????????????????}

          ????????????????}

          ????????????}

          ????????}
          ?catch?(Exception?e)?{
          ????????????e.printStackTrace();
          ????????}
          ?finally?{
          ????????????ConnectionFactory.unbind(name);
          ????????????System.out.println(
          "unbind?datasource?ok.");
          ????????????System.exit(
          0);
          ????????}


          ????}


          ????
          public?static?void?testSQL(Connection?conn,?String?sql)?throws?Exception?{
          ????????PreparedStatement?ps?
          =?conn.prepareStatement(sql);
          ????????ResultSet?rs?
          =?ps.executeQuery();
          ????????
          while?(rs.next())
          ????????????System.out.println(rs.getString(
          1));
          ????}


          }

          ok。

          posted on 2007-09-18 18:12 心硯 閱讀(484) 評論(0)  編輯  收藏 所屬分類: Java

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(2)

          隨筆分類

          文章分類

          文章檔案

          Forum

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宣威市| 仁化县| 阳信县| 镇赉县| 陵川县| 杨浦区| 江达县| 开江县| 牙克石市| 衡水市| 蒙山县| 扎鲁特旗| 利川市| 广元市| 武宣县| 安塞县| 堆龙德庆县| 彭山县| 四会市| 金溪县| 获嘉县| 郎溪县| 嫩江县| 克东县| 酉阳| 鹤庆县| 福贡县| 襄樊市| 长兴县| 台中县| 嘉禾县| 长丰县| 隆昌县| 玉龙| 大田县| 绵阳市| 建水县| 澎湖县| 怀宁县| 台江县| 阿克|