這可是一個好東東。
不過
小弟我花了兩天也沒有想好外面的類是怎么樣給DBConnectionManager傳遞參數進去的
以便調用ConntionPool來創建。
我有注釋,不過,為了移植性,小弟全是用英文注釋的
也可能有錯
希望大俠們理解
我這里把不理解的地方有中文標識,謝謝指教
能夠寫一個完整的調用實例,小弟我是感激不盡呀!:
(別看代碼長,很簡單,只不過我加了注釋,其中還有一個類中類,取出來就短了)
package gui.www.mypackage;import java.io.*;import java.sql.*;import java.util.*;
import java.util.Date;import oracle.jdbc.driver.OracleDriver;
/**
 * DBConnectionManager is a class includes a inside class named DBConnectionPool.
 * DBConnectionPool is used to create a Connection Pool.
 * DBConnectionManager is used to manage the pools because it can create many pools
 * and every pool can have several connection.
 * useage:
 */
public class DBConnectionManager 
{
  /**
   * include methods:
   * init()
   * static synchronized public DBConnectionManager getInstance()
   * public void freeConnection(String name,Connection conn)
   * public Connection getConnection(String name)
   * public Connection getConnection(String name,long time)
   * public synchronized void release()
   * public void createPools(Properties props)
   * public void loadDrivers(Properties props) 
   * AND A CLASS NAMED DBConnectionPool
   */
  private DBConnectionManager()
  {
    init();
  }
  
  private static DBConnectionManager instance;
  private static int clients;
  
  private Vector drivers=new Vector();
  private Hashtable pools=new Hashtable();
  
  static synchronized public DBConnectionManager getInstance()
  {
    if(instance==null)
    {
      instance=new DBConnectionManager();
    }
    clients++;
    return instance;
  }
  
  /**
   * Free the Connection Named by parameter <name>
   * @param conn
   * @param name
   */
  public void freeConnection(String name,Connection conn)
  {
    DBConnectionPool pool=(DBConnectionPool)pools.get(name);
    if(pool!=null)//if exists the connection named by the parameter <name>
    {
      pool.freeConnection(conn);//then free
    }
  }
  /**
   * Create a connection named by the parameter <name>
   * @return 
   * @param name
   */
  public Connection getConnection(String name)
  {
    DBConnectionPool pool=(DBConnectionPool)pools.get(name);
    if(pool!=null)
    {
      return pool.getConnection();
    }
    return null;
  }
  /**
   * Create a new connection named by parameter <name> but the create time is limited by 
   * the parameter <time>
   * @return 
   * @param time
   * @param name
   */
  public Connection getConnection(String name,long time)
  {
    DBConnectionPool pool=(DBConnectionPool)pools.get(name);
    if(pool!=null)
    {
      return pool.getConnection(time);
    }
    return null;
  }
  
  public synchronized void release()
  {
    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);
      }
      catch(Exception e){}
    }
  }
  
  public void createPools(Properties props)
  {
    Enumeration propNames=props.propertyNames();
    while(propNames.hasMoreElements())
    {
      String name=(String)propNames.nextElement();
      
      if(name.endsWith(".url"))
      {
        String poolName=name.substring(0,name.lastIndexOf("."));
        String url=props.getProperty(poolName+".url");
        
        if(url==null)
          continue;
        /**
         * 就是這里最難理解了,是怎么樣將參數傳過來的
         * 是采用set什么什么方法嗎
         */
        String user=props.getProperty(poolName+".user");
        String password=props.getProperty(poolName+".password");
        String maxConn=props.getProperty(poolName+".maxconn","0");
        int max;
        try
        {
          max=Integer.valueOf(maxConn).intValue();
        }
        catch(Exception e){max=0;}
        
        DBConnectionPool pool= new DBConnectionPool(poolName,password,url,user,max);
        pools.put(poolName,pool);
      }
    }
  }
  
  public void init()
  {
    /**
      * The <code>Properties</code> class represents a persistent set of
      * properties. The <code>Properties</code> can be saved to a stream
      * or loaded from a stream. Each key and its corresponding value in
      * the property list is a string.
      * <p>
      * A property list can contain another property list as its
      * "defaults"; this second property list is searched if
      * the property key is not found in the original property list.
      */
    Properties dbProps=new Properties();
    /**
     * getClass():return the runtime class of an object
     */     
    /**
     * getResourceAsStream(..):
     * Finds a resource with a given name.  This method returns null if no
     * resource with this name is found.  The rules for searching
     * resources associated with a given class are implemented by the
     * defining class loader of the class.
     *
     * <p> This method delegates the call to its class loader, after making
     * these changes to the resource name: if the resource name starts with
     * "/", it is unchanged; otherwise, the package name is prepended to the
     * resource name after converting "." to "/".  If this object was loaded by
     * the bootstrap loader, the call is delegated to
     * <code>ClassLoader.getSystemResourceAsStream</code>.
     *
     * @param name  name of the desired resource
     * @return      a <code>java.io.InputStream</code> object.
     * @throws NullPointerException if <code>name</code> is <code>null</code>.
     * @see         java.lang.ClassLoader
     * @since JDK1.1
     */
    InputStream is = getClass().getResourceAsStream("db.properties");
    //System.out.println(is.toString());
    try
    {
      /**
       *  load:Reads a property list (key and element pairs) from the input
       *  stream.
       */
      dbProps.load(is);
    }
    catch(Exception e)
    {
      //System.out.println("www");
      //e.printStackTrace();
      return;
    }
    /**
     * public String getProperty(String key, String defaultValue)
     * @param   key            the hashtable key.
     * @param   defaultValue   a default value.
     * @return  the value in this property list with the specified key value.
     */
    String logFile=dbProps.getProperty("logfile","DBConnectionManager.log");
    try
    {
      //write logFile
      PrintWriter log = new PrintWriter(new FileWriter(logFile, true), true);
    }
    catch (IOException e) 
    {}
    loadDrivers(dbProps);
    createPools(dbProps);
    
  }
  
  /**
   * Load Drivers
   * @param props
   */
  public void loadDrivers(Properties props)
  {
    String driverclass=props.getProperty("drivers");
    StringTokenizer st=new StringTokenizer(driverclass);
    while(st.hasMoreElements())
    {
      String driverClassName=st.nextToken().trim();
      //System.out.println("driverClassName:"+driverClassName);
      try
      {
        Driver driver=(Driver)Class.forName(driverClassName).newInstance();
        DriverManager.registerDriver(driver);
        drivers.addElement(driver);
      }
      catch(Exception e){}
    }
    //System.out.println("driverClassName:"+driverclass);
  }

解决方案 »

  1.   

    /**
       * Class in Class
       */
      class DBConnectionPool
      {
        /**
         * include methods:
         * public DBConnectionPool(String name,String password,String url,String user,int maxConn)//initialize
         * public synchronized void freeConnection(Connection conn)//do a free action
         * public synchronized Connection getConnection()//get an action
         * public synchronized Connection getConnection(long timeout)//get an conn depending on the parameteor
         * public synchronized void release()//free all the connection
         * private Connection newConnection()//create a connection
         */
        private int checkout;//current num of alive threads
        private Vector freeConnections=new Vector();
        private int maxConn;
        private String name;
        private String password;
        private String URL;
        private String user;
        
        public DBConnectionPool(String name,String password,String url,String user,int maxConn)
        {
          //initialize parameter
          this.maxConn=maxConn;//max connection
          this.name=name;//username
          this.password=password;//user password
          this.URL=url;//database in the url
          this.user=user;
        }
        
        public synchronized void freeConnection(Connection conn)
        {/**
          * add all the free Connection into the vevtor named freeConnections
          */
          freeConnections.addElement(conn);//add and thread in the vector
          checkout--;//the busy conn sub one
          /**
           * Because this method is synchronized
           * ,when this method is running other threads is awaiting this method
           * .so after this work is over,we will use notityAll() to tell other
           * threads can work now.
           */
          notifyAll();//notify all the theads
        }
        
        /**
         * get a connection or create a new connection if the user doesn't use thread pool
         */
        public synchronized Connection getConnection()
        {
          Connection conn=null;
          if(checkout==maxConn)//if current connection is the max
            checkout=0;
          if(freeConnections.size()>0)//if there has free connction
          {
            //get the first element in the vector
            conn=(Connection)freeConnections.firstElement();
            //so to remove the first element in the freeConnections
            //and the second will become the first one
            freeConnections.removeElementAt(0);
            try
            {
              //make sure that this thread don't have other work to do now
              if(conn.isClosed())
              {           
                conn=getConnection();
              }
            }
            catch(Exception e){}
          }
          /**
           * if the user doesn't ask connection pool request or there are free connections
           */
          else if(maxConn==0 || checkout<maxConn)
          {
            conn=newConnection();
          }
          if(conn!=null)//get success
          {
            checkout++;
          }
          return conn;
        }
        /**
         * 
         * create a method to create an connection during the parameter
         * if OK and the used time is less or equal the parameter then return connection
         * else return null
         * @return 
         * @param timeout
         */
        public synchronized Connection getConnection(long timeout)
        {
          long startTime=new Date().getTime();
          Connection conn;
          while((conn=getConnection())==null)
          {
            try
            {
              /**
               * if current doesn't hava free connection
               * the wait for sometime
               */         
              wait(timeout);
            }
            catch(Exception e){}
            /**
             * Is it used to avoid the deadlock?
             */
            if(new Date().getTime()-startTime>=timeout)
              return null;
          }
          return conn;
        }
        
        /**
         * release all the connection
         */
        public synchronized void release()
        {
          /**Enumeration:
            * An object that implements the Enumeration interface generates a
            * series of elements, one at a time.
            */
          /**
           * 
           * public Enumeration elements():
           * Returns an enumeration of the components of this vector. The 
           * returned <tt>Enumeration</tt> object will generate all items in 
           * this vector. The first item generated is the item at index <tt>0</tt>, 
           * then the item at index <tt>1</tt>, and so on.
           */
          Enumeration allConnections=freeConnections.elements();
          while(allConnections.hasMoreElements())
          {
            Connection conn=(Connection)allConnections.nextElement();
            try
            {
              conn.close();//release the conn
            }
            catch(Exception e){}
          }
          /**
           *remove all the element in the vector
           */
          freeConnections.removeAllElements();
        }
        
        /**
         * create a new connection
         * @return 
         */
        private Connection newConnection()
        {
          Connection conn=null;
          try
          {
            DriverManager.registerDriver(new OracleDriver());
            if(user==null)
            {
              conn=DriverManager.getConnection(URL);
            }
            else
            {
              conn=DriverManager.getConnection(URL,user,password);
            }
          }
          catch(Exception e){return null;}
          return conn;
        }
      } 
    }