连接池的作用是限制最大连接数并且能保持几个长连接,这样可以提高连接速度,不用非常频繁的连接和断开,更重要的是能限制最大连接数目,这样完全可以避免出现连接没有断开,连接数超过最大连接数而把数据库连死的情况,一般我认为都应该用连接池给你一个连接池的程序DBConn.java连接池程序import java.sql.*;
import java.io.*;
import javax.naming.*;public class DBConn {
  private Connection myConn = null;
  private Statement stmt = null;
  private ResultSet rs = null;  public Connection getConn() throws Exception {
    Context initContext = new InitialContext();
    Context envContext = (Context) initContext.lookup("java:comp/env"); //获取连接池对象
    javax.sql.DataSource ds = (javax.sql.DataSource) envContext.lookup(
        "jdbc/Provision"); //类型转换
    myConn = ds.getConnection();
    return myConn;
  }  public boolean makeConn() throws Exception { //完成连接数据库的功能
    Context initContext = new InitialContext();
    Context envContext = (Context) initContext.lookup("java:comp/env"); //获取连接池对象
    javax.sql.DataSource ds = (javax.sql.DataSource) envContext.lookup(
        "jdbc/Provision"); //类型转换
    myConn = ds.getConnection();
    return (myConn != null);
  }  public boolean sqlQuery(String sql) throws Exception { //执行select语句    stmt = myConn.createStatement();
    rs = stmt.executeQuery(sql);
    return (rs != null);
  }  public boolean getNext() throws Exception { //看数据库的下一个数据是否为空
    return (rs.next());
  }  public String getString(String inCol) throws Exception { //取得对应数据库字段的数据
    return rs.getString(inCol);
  }  public int getInt(String inCol) throws Exception { //取得对应数据库整型字段的数据
    return rs.getInt(inCol);
  }  public void sqlUpdate(String sql) throws Exception { //执行update、delete、insert的sql语句
    stmt = null;
    stmt = myConn.createStatement();
    stmt.executeUpdate(sql);
  }  public void closeAll() throws Exception {
    if (rs != null)
      rs.close();
    if (stmt != null)
      stmt.close();
    if (myConn != null)
      myConn.close();
  }  public void closeConn() throws Exception { //关闭所有的与数据库相关的操作
    if (stmt != null)
      stmt.close();
    if (myConn != null)
      myConn.close();
  }  public void closeRs() throws Exception {
    if (rs != null)
      rs.close();
  }  public void closeStmt() throws Exception {
    if (stmt != null)
      stmt.close();
  }  public void closeConnect() throws Exception {
    if (myConn != null)
      myConn.close();
  }}调用方法DBConn dbconn; //数据库对象
  Connection conn; //数据连接对象
      dbconn = new DBConn();
      conn = dbconn.getConn();
      //用户通过短信订购直接调用addbusi_ret
      strSQL = "{ call mobuser.addbusi_ret(?,?,?,?) }";
      cstmt_add_sms = conn.prepareCall(strSQL);
      //用户通过web或者wap订购
      strSQL="{ call mobuser.pro_check_reg(?,?,?,?) }";
      cstmt_add_web = conn.prepareCall(strSQL);
      //取消定购
      strSQL = "{ call mobuser.cancelbusi(?,?,?) }";
      cstmt_cancel = conn.prepareCall(strSQL);

解决方案 »

  1.   

    太感谢你的帮助了,厉害厉害。严重崇拜中!!!
    那么它有没有不同数据库之间编写代码的不同呢?比如mysql oracle and ms sqlserver在编写连接池的时候不同?
      

  2.   

    在哪里是制定他访问什么数据库?还有你也是做WAP的?llin998??
      

  3.   

    这个是TOMCAT里配置的,我再给你一个可以自由配置的
    DBConnectionManager.javapackage ChatServer;
    import java.io.*;
    import java.sql.*;
    import java.util.*;
    import java.util.Date;
    /**
     *管理类DBConnectionManager支持对一个或多个有属性文件定义的数据库连接
     *池的访问,客户程序可以调用getInstance()方法访问本类的唯一实例
     */
    public class DBConnectionManager {
      static private DBConnectionManager instance; //唯一实例
      static private int clients;
      private Vector drivers = new Vector(); //数据库驱动
      private PrintWriter log;
      private Hashtable pools = new Hashtable(); //
      /**
       *返回唯一实例,如果是第一次调用此方法,则创建实例
       *
       */
      static synchronized public DBConnectionManager getInstance() {
        if (instance == null) {
          instance = new DBConnectionManager();
        }
        clients++;
        return instance;
      }
      /**
       *构造函数私有以防止其它对象创建本类实例
       */
      private DBConnectionManager() {
        init();
      }
      /**
       *将连接对象返回给由名字指定的连接池
       *
       *@param name 在属性文件中定义的连接池名字
       *@param con连接对象
       */
      public void freeConnection(String name, Connection con) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
          pool.freeConnection(con);
        }
      }  /**
       *获得一个可用的(空闲)连接,如果没有可用连接,且已有连接数小于最大连接数限制,
       *则创建并返回新连接
       *
       *@param name 在属性文件中定义的连接池名字
       *@return Connection 可用连接或null
       */
      public Connection getConnection(String name) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
          return pool.getConnection();
        }
        return null;
      }
      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);
            log("撤销JDBC驱动程序" + driver.getClass().getName() + "的注册");
          }
          catch (SQLException e) {
            log(e, "无法撤销下列JDBC驱动程序的注册:" + driver.getClass().getName());
          }
        }
      }
      /**
       *根据指定属性创建连接池实例
       *
       *@param props连接池属性
       */
      private 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) {
              log("没有为连接池" + poolName + "指定URL");
              continue;
            }
            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 (NumberFormatException e) {
              log("错误的最大连接数限制:" + maxconn + ".连接池" + poolName);
              max = 0;
            }
            DBConnectionPool pool = new DBConnectionPool(poolName, url, user,
                password, max);
            pools.put(poolName, pool);
            log("成功创建连接池" + poolName);
          }
        }
      }  /**
       *读取属性完成初始化
       */
      private void init() {
        Properties dbProps = new Properties();
        try {
          FileInputStream is = new FileInputStream("conf\\db.properties");
          dbProps.load(is);    }
        catch (Exception e) {
          System.err.println("不能读取属性文件" + "请确保db.properties在classPath指定的路径中");
          return;
        }
        String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
        try {
          log = new PrintWriter(new FileWriter(logFile, true), true);
        }
        catch (IOException e) {
          System.err.println("无法打开日志文件:" + logFile);
          log = new PrintWriter(System.err);
        }
        loadDrivers(dbProps);
        createPools(dbProps);  }
      /**
       *装载和注册所有JDBC驱动程序
       *
       *@param props属性
       */
      private void loadDrivers(Properties props) {
        String driverClasses = props.getProperty("drivers");
        StringTokenizer st = new StringTokenizer(driverClasses);
        while (st.hasMoreElements()) {
          String driverClassName = st.nextToken().trim();
          try {
            Driver driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
            drivers.addElement(driver);
            log("成功注册JDBC驱动程序" + driverClassName);
          }
          catch (Exception e) {
            log("无法注册JDBC驱动程序" + driverClassName + ",错误:" + e);
          }
        }
      }
      /**
       *将文本信息写入日志文件
       */
      private void log(String msg) {
        log.println(new Date() + ":" + msg);
      }
      /**
       *将文本信息与异常写入日志文件
       */
      private void log(Throwable e, String msg) {
        log.println(new Date() + ":" + msg);
        e.printStackTrace(log);
      }
      /**
       *此类定义了一个连接池,它能够根据要求创建新连接,直到预定的最大连接数为止,
       *在返回连接给客户程序之前,它能够验证连接的有效性。
       */
      class DBConnectionPool {
        private int checkedOut;
        private Vector freeConnections = new Vector();
        private int maxConn;
        private String name;
        private String password;
        private String URL;
        private String user;    /**
         *创建新的连接池
         *
         *@param name连接池名称
         *@param URL数据库的JDBC URL
         *@param user数据库账号,或null
         *@param password密码,或null
         *@param maxConn此连接池允许建立的最大连接数
         */
        public DBConnectionPool(String name, String URL, String user,
                                String password, int maxConn) {
          this.name = name;
          this.URL = URL;
          this.user = user;
          this.password = password;
          this.maxConn = maxConn;
        }
      

  4.   

    接上边的 
       /**
         *将不再使用的连接返回给连接池
         *
         *@param con客户程序释放的连接
         */
        public synchronized void freeConnection(Connection con) {
          //将指定连接加入到向量末尾
          freeConnections.addElement(con);
          checkedOut--;
          notifyAll();
        }    /**
         *从连接池获得一个可用连接,如果没有空闲的连接且当前连接数小于最大连接数限制,
         *则创建新连接,如原来登记为可用连接不再有效,则从向量删除之,然后递归调用自
         *己以尝试新的可用连接
         */
        public synchronized Connection getConnection() {
          Connection con = null;
          if (freeConnections.size() > 0) {
            //获取向量中第一个可用连接
            con = (Connection) freeConnections.firstElement();
            freeConnections.removeElementAt(0);
            try {
              if (con.isClosed()) {
                log("从连接池" + name + "删除一个无效连接");
                //递归调用自己,尝试再次获取可用连接
                con = getConnection();
              }
            }
            catch (SQLException e) {
              log("从连接池" + name + "删除一个无效连接");
              //递归调用自己,尝试再次获取可用连接
              con = getConnection();
            }
          }
          else if (maxConn == 0 || checkedOut < maxConn) {
            con = newConnection();
          }
          if (con != null) {
            checkedOut++;
          }
          return con;
        }    /**
         *从连接池获取可用连接,可以指定客户程序能够等待的最长时间
         *参见前一个getConnection()方法
         *
         *@param timeout 以毫秒计的等待时间限制
         */
        public synchronized Connection getConnection(long timeout) {
          long startTime = new Date().getTime();
          Connection con;
          while ( (con = getConnection()) == null) {
            try {
              wait(timeout);
            }
            catch (InterruptedException e) {}
            if ( (new Date().getTime() - startTime) >= timeout) {
              //wait()返回的原因是超时
              return null;
            }
          }
          return con;
        }    /**
         *关闭所有连接
         */
        public synchronized void release() {
          Enumeration allConnections = freeConnections.elements();
          while (allConnections.hasMoreElements()) {
            Connection con = (Connection) allConnections.nextElement();
            try {
              con.close();
              log("关闭连接池" + name + "中的一个连接");
            }
            catch (SQLException e) {
              log(e, "无法关闭连接池" + name + "中的连接");
            }
          }
          freeConnections.removeAllElements();
        }    /**
         *创建新的连接
         */
        private Connection newConnection() {
          Connection con = null;
          try {
            if (user == null) {
              con = DriverManager.getConnection(URL);
            }
            else {
              con = DriverManager.getConnection(URL, user, password);
            }        log("连接池" + name + "创建一个新的连接");
          }
          catch (SQLException e) {
            log(e, "无法创建下列URL的连接:" + URL);
            System.err.println(e.getMessage());
            System.out.println("url=" + URL + "\nuser=" + user + "\npassword=" +
                               password);
            return null;
          }
          return con;
        }
      }
    }
      

  5.   

    调用方法package ChatServer;
    /**
     * <p>Title:连接数据库的程序 </p>
     * <p>Description: </p>
     * <p>Copyright: Copyright (c) 2005</p>
     * <p>Company: </p>
     * @author not attributable
     * @version 1.0
     */
    import java.io.*;
    import java.util.*;
    import java.sql.*;
    public class ConnectDB{
      String strDB;
      String strUsr;
      String strPasswd;
      Connection conn = null;
      Properties prop;
      private String CONF = "conf\\db.conf";
      public ConnectDB(String dbConf) {
        CONF = dbConf;
        try  //获取数据库配置文件
        {
          prop = new Properties();
          prop.load(new FileInputStream(CONF));
          System.out.println("成功读取数据库配置文件:" + CONF);
        }
        catch(IOException e)
        {
          e.printStackTrace();
          System.out.println("数据库配置文件读取错误!系统将要退出!");
          System.exit(-1);
        }
        //从配置文件中读取配置信息
        strDB = prop.getProperty("DBNAME").trim();
        strUsr = prop.getProperty("DBUSER").trim();
        strPasswd = prop.getProperty("DBPASSWORD").trim();
      }
      public Connection getConn()
      {
        try {
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            conn = DriverManager.getConnection(strDB, strUsr, strPasswd);
            conn.setAutoCommit(false);
            System.out.println("数据库连结正常!");
           return conn;
         }
        catch (SQLException e) {
          System.out.println("数据库连接错误!错误类型:" + e.toString());
          return null;
        }
      }
    }配置文件#驱动程序
    drivers=oracle.jdbc.driver.OracleDriver
    #日志文件
    logfile=log\\connPoolLog.txt
    #webdb1_unicom连接池
    #登陆用户:webuser
    webdb1_unicom.url=jdbc:oracle:thin:@211.154.171.116:1521:WEBDB1
    webdb1_unicom.maxconn=3
    webdb1_unicom.user=CHATSERVER
    webdb1_unicom.password=chat_server
    #webdb1_unicom连接池
    #登陆用户:webuser
    webdb1_mobcom.url=jdbc:oracle:thin:@211.136.82.145:1521:WEBDB1
    webdb1_mobcom.maxconn=3
    webdb1_mobcom.user=CPSERVER
    webdb1_mobcom.password=CPSERVER
    只要修改drivers就可以修改了你可以仔细看一下原来我是做SP的,短信,WAP我都做过,不过我现在不做了
    呵呵!
      

  6.   

    帅哥,你太牛X了,我现在在做sp,但是我一直都不想做了,你有没有msn或者qq能留给我吗?这样我们可以更多的交流一下java编程,多谢你的帮助!!!
      

  7.   

    我的MSN是[email protected]
    我也讨厌做SP