数据库连接池入门

我测试的环境是:WindowsXP、eclipse3.2、jdk1.6、dom4j1.6.1.jar

其中dom4j1.6.1.jar可以在本人资源库中下载

数据库连接池:说白了就是先建立一堆数据库连接放到集合里面,在用的时候到集合里面中取一个,用完之后放入到连接池中。因此在建立连接池时要通过某个东西来区别,那些正在别使用,那些是空闲连接。

package com.zony.base.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Hashtable;

import com.zony.base.Globals;

/**
 * 一个数据库连接池
 * 连接池中的连接通过键值对保存HashTable:键是:Y(N)+System.currentTimeMillis()
 *             值是:Connection
 *
 * 获取连接时,先从池中判断取出一个有用连接Y + System.currentTimeMillis()
 * 以键值对的形式返回,并池中的该连接删除,新增加一个连接
 *   该连接的键是将原连接键中的Y换成N, 以表示该连接上被占用状态
 * 用完连接之后,将其以键值对的形式返回,返回之前,改变键值对中的键N为Y,
 * 然后查找并删除池中被占用的该连接,添加现在可用的连接
 * 
 *  如:
 * 
 *  开始con =null                  池中Y1352900127421
 *  取出后con = Y1352900127421     池中N1352900127421
 * 
 *  用完后con = Y1352900127421     通过键N1352900127421删除池中的连接,添加Y1352900127421
 * 
 *  之后con =null       池中Y1352900127421
 * 
 */
public class ConnectionManager_pool {

        private static String drivername ;//数据库驱动
        private static String url ;       //数据库连接路径
        private static String username ;  //数据库名称
        private static String password ;  //数据库密码
   
        private static int minCon ;  //连接池中最小连接数量
        private static int maxCon ;  //连接池中最大连接数量
   
        //Hashtable是一个线程安全的集合,conlist的键值以N开头则是占用状态,以Y开头则是空闲状态
        public static Hashtable<String,Connection> conlist = new Hashtable<String,Connection>();//可用连接数量
       

        private ConnectionManager_pool(){//获取数据量连接所需参数
                drivername = Globals.getProperty("database.defaultProvider.driver");
                url = Globals.getProperty("database.defaultProvider.serverURL");
                username = Globals.getProperty("database.defaultProvider.username");
                password = Globals.getProperty("database.defaultProvider.password");
                minCon = Integer.parseInt(Globals.getProperty("database.defaultProvider.minConnections"));
                maxCon = Integer.parseInt(Globals.getProperty("database.defaultProvider.maxConnections"));
        }
        /**
          * 在程序启动时,先创建连接池,开始为最小连接数minCon
          */
         public static void init(){
                new ConnectionManager_pool();//获取数据库连接所需的所有参数
                for(int i=1 ; i<=minCon ; i++){
                      conlist.put("Y"+System.currentTimeMillis(),createConnection());//初始化的时给连接池建立3个连接 
                }
        }
        //建立数据库连接
        private static Connection createConnection(){
               Connection con = null;
               try{
                      Class.forName(drivername);
                      con = DriverManager.getConnection(url,username,password);
               }catch (ClassNotFoundException se) {
                      se.printStackTrace();
               } catch (SQLException se){
                      se.printStackTrace();
               }
               return con;
         }
   
        /**
          * 从数据库连接池中取出一个可用的数据库连接,
          * 如果连接池中没有可用连接,则在数据库最大连接数内重新创建数据库连接
          */
         public static Object[] getConnection(){
                Object[] keycon = new Object[2];
                Enumeration<String> e = conlist.keys();
                while (e.hasMoreElements()) {
                       if(e.nextElement().startsWith("Y")){//如果是可用的数据库连接
                               keycon[0] = e.nextElement();
                               keycon[1] = conlist.get(e.nextElement());//连接被占用
                               conlist.remove(keycon[0]);//连接池中先删除被占用连接
                               conlist.put("N"+keycon[0].toString().substring(1), (Connection)keycon[1]);//添加被占用的连接
                               return keycon;
                        }
                 }
                 //如果连接池中没有可用连接,则在数据库最大连接数内重新创建数据库连接
                 if(keycon[0].toString().length()<1&&conlist.size()<=maxCon){
                        keycon[0] = "Y" + System.currentTimeMillis();
                        keycon[1] = createConnection();
                        //将新创建的数据库连接放入到连接池中,此时它是被占用状态 
                        conlist.put("N"+keycon[0].toString().substring(1), (Connection)keycon[1]);
                  }
                  return keycon;
          }

           /**
             * 将使用完的数据库连接放入到连接池中
             * @param con 被使用完成的数据库连接
             */
          public static void setConnection(Object[] keycon){
                  String key = keycon[0].toString().substring(1);//没有状态的key
                  Connection con = (Connection)keycon[1];
                  try {
                          if(con!=null&&!con.isClosed()){//该连接是可用连接
                                  synchronized(conlist) {//同步连接池
                                          conlist.remove("N"+key);//删除被占用的连接
                                          conlist.put("Y"+key,con);//将已经被使用完的可用连接添加到连接池中
                                  }
                          }
                   } catch (SQLException e) {
                         e.printStackTrace();
                   }
          }
}

你可能感兴趣的:(数据库连接池入门)