有問題可聯系我QQ:429810818

          posts - 4, comments - 6, trackbacks - 0, articles - 8

          自定義jdbc連接池

          Posted on 2012-09-15 17:49 張力 閱讀(301) 評論(0)  編輯  收藏
          最近一直想自己封裝下jdbc,寫個orm,在此拿出來分享分享我的代碼,讓高人指點指點,共同進步,也做個備份
          先上代碼
          DataSource.java
          package org.tension.framework.common.das;

          import java.io.InputStream;
          import java.util.Iterator;

          import org.dom4j.Document;
          import org.dom4j.Element;
          import org.dom4j.io.SAXReader;


          /**
          * 數據源
          * @author tension
          *
          */
          public class DataSource {
          protected static String driverClassName;
          protected static String url;
          protected static String user;
          protected static String password;
          protected static int poolSize;
          protected static int maxUseCount;
          protected static int maxPoolSize;
          protected static int minPoolSize;
          protected static String transaction_Isolation;

          static{
          try {
          InputStream ips = DataSource.class.getClassLoader().getResourceAsStream("user-config.xml");
          SAXReader reader = new SAXReader();
          Document doc = null;
          doc = reader.read(ips);
          Element root = doc.getRootElement();
          Element  module = root.element("module");
          Element group = module.element("group");
          Iterator<?> configValue = group.elementIterator("configValue");
          while(configValue.hasNext()){
          Element e = (Element) configValue.next();
          String key = e.attributeValue("key");
          String value = e.getText();
          if("DriverClass".equalsIgnoreCase(key)){
          driverClassName = value;
          }else if("Url".equalsIgnoreCase(key)){
          url = value;
          }else if("UserName".equalsIgnoreCase(key)){
          user = value;
          }else if("Password".equalsIgnoreCase(key)){
          password = value;
          }else if("PoolSize".equalsIgnoreCase(key)){
          poolSize = Integer.valueOf(value);
          }else if("MaxUseCount".equalsIgnoreCase(key)){
          maxUseCount = Integer.valueOf(value);
          }else if("MaxPoolSize".equalsIgnoreCase(key)){
          maxPoolSize = Integer.valueOf(value);
          }else if("MinPoolSize".equalsIgnoreCase(key)){
          minPoolSize = Integer.valueOf(value);
          }else if("Transaction-Isolation".equalsIgnoreCase(key)){
          transaction_Isolation = value;
          }
          }
          Class.forName(driverClassName);
          } catch (Exception e) {
          throw new ExceptionInInitializerError(e);
          }
          }
          }
          至于為什么沒有去實現DataSource接口,我覺得我暫時不用它,所有沒有去實現


          ConnectionPool.java
          package org.tension.framework.common.das;

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.SQLException;
          import java.util.LinkedList;

          /**
          *
          * 2012-9-12
          *
          * @author <a href="mailto:429810818@qq.com">tension</a>
          *
          */
          public class ConnectionPool extends DataSource{
          /**當前連接數*/
          int currentCount = 0;

          LinkedList<Connection> connectionsPool = new LinkedList<Connection>();


              /**
               * 默認構造方法,一次性獲得poolSize個連接放進connectionsPool連接池中
               */
          public ConnectionPool() {
          CreateConnectionPool(poolSize);
          }
          /**
          * 獲取連接記錄當前連接個數
          * 如果連接池還有連接則直接從連接池取連接,如果連接大于最大連接數
          * @return
          * @throws SQLException
          */
          public Connection getConnection() throws SQLException {
          synchronized (connectionsPool) {
          if (this.connectionsPool.size() > 0){
          this.currentCount++;
          return this.connectionsPool.removeFirst();
          }
                      if(this.currentCount < maxPoolSize){
                      int buffer = this.currentCount + minPoolSize;
                      if (buffer < maxPoolSize || buffer == maxPoolSize) {
              this.currentCount++;
              CreateConnectionPool(minPoolSize);
              }else{
              this.currentCount++;
              CreateConnectionPool(buffer - maxPoolSize);
              }
                      return this.connectionsPool.removeFirst();
                      }

          throw new SQLException("暫無連接可用");
          }
          }
          /**
          * 創建連接放入連接池中,緩沖連接池
          * @param count 個數
          */
          public void CreateConnectionPool(int count){
          try {
          for (int i = 0; i < count; i++) {
          this.connectionsPool.addLast(this.createConnection());
          this.currentCount++;
          }
          } catch (SQLException e) {
          throw new ExceptionInInitializerError(e);
          }
          }
              /**
               * 釋放連接方法
               * 把用完的連接重新放回連接池中
               * @param conn
               */
          public void free(Connection conn) {
          this.connectionsPool.addLast(conn);
          }
              /**
               * 創建連接
               * @return warpedConnection
               * @throws SQLException
               * @author tension
               */
          private Connection createConnection() throws SQLException {
          Connection realConn = DriverManager.getConnection(url, user, password);
          ConnectionHandler proxy = new ConnectionHandler(this);
          return proxy.bind(realConn);
          }
          }
          這個就是所謂的連接池了,簡單,沒有現在主流的那么NB,供學習

          ConnectionHandler
          package org.tension.framework.common.das;

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

          /**
          * 連接池的代理類
          * 用于處理Connection的colse方法,把連接放回連接池
          * @author tension
          * 2012-09-12
          */
          class ConnectionHandler  extends DataSource implements InvocationHandler{
          /**真正的連接對象 */
          private Connection realConnection;
          /**代理的連接對象 */
          private Connection warpedConnection;
          /**連接池*/
          private  ConnectionPool conn;
          /**當前用戶使用的次數*/
          private int currentUserCount = 0;
              /**
               * 默認構造方法
               * @param conn 連接池
               */
          ConnectionHandler(ConnectionPool conn) {
          this.conn = conn;
          }
              /**
               * java.sql.Connection的代理方法
               * @param realConn warpedConnection 代理后的對象
               * @return
               */
          Connection bind(Connection realConn) {
          this.realConnection = realConn;
          this.warpedConnection = (Connection) Proxy.newProxyInstance(this
          .getClass().getClassLoader(), new Class[] { Connection.class },
          this);
          return warpedConnection;
          }
              /**
               * 方法攔截
               * 如果為close方法的話不直接調用真正Connection的close方法
               * 如果使用次數小于5次的話就放回連接池中否則關閉這個連接
               */
          public Object invoke(Object proxy, Method method, Object[] args)
          throws Throwable {
          if ("close".equals(method.getName())) {
          this.currentUserCount++;
          if (maxUseCount == 0 || this.currentUserCount < maxUseCount)
          this.conn.connectionsPool.addLast(this.warpedConnection);
          else {
          this.realConnection.close();
          this.conn.currentCount--;
          }
          }
          return method.invoke(this.realConnection, args);
          }

          }
          Connection的代理,主要是修改colse方法
          user-config.xml
          <?xml version="1.0" encoding="UTF-8" standalone="no"?>
          <application>
              <module name="DataSource">
          <group name="default">
          <configValue key="DriverClass">oracle.jdbc.driver.OracleDriver</configValue>
          <configValue key="Url">jdbc:oracle:thin:@tension:1521:ORCL</configValue>
          <configValue key="UserName">xxx</configValue>
          <configValue key="Password">ooo</configValue>
          <configValue key="PoolSize">1</configValue><!-- 初始大小 -->
          <configValue key="MaxUseCount">0</configValue> <!-- 最大連接數 使用次數-->
          <configValue key="MaxPoolSize">3</configValue> <!-- 最大連接數 -->
          <configValue key="MinPoolSize">2</configValue><!-- 每次增長 -->
          <configValue key="Transaction-Isolation">ISOLATION_READ_COMMITTED</configValue><!-- 事物隔離級別 -->
          </group>
              </module>

          </application>

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 克拉玛依市| 阿克陶县| 阿荣旗| 土默特左旗| 湟中县| 泌阳县| 武胜县| 天全县| 嘉鱼县| 桐乡市| 聂拉木县| 泌阳县| 江阴市| 景洪市| 缙云县| 收藏| 荣成市| 集贤县| 惠东县| 庄浪县| 晋州市| 永新县| 两当县| 正定县| 蚌埠市| 霍邱县| 枣庄市| 凭祥市| 江陵县| 郑州市| 周口市| 华容县| 嘉鱼县| 福州市| 尚志市| 河北区| 三台县| 鹤岗市| 富平县| 扶沟县| 罗平县|