我自己在java里写了一个连接池,可一运行就出错,改了这两天,越改越错。现在实在不想再改了,恳请各位好心人发一份实现单例连接池的代码(最好附上如何从外部调用得到一个连接),肯请各位大侠帮帮忙,要不我项目就无法进行了。小弟在此先谢谢各位了。或[email protected]
注:在tomcat下配置的就不用了,我们这个必须是在java里自己写的。

解决方案 »

  1.   

    晕,才给10,我有一个以前自己写的链接,不知道你满不满意!package fx.sql;import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;/**
     * 
     * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最大连接数为止.
     * 
     * 在返回连接给客户程序之前,它能够验证连接的有效性.
     * 
     * @author FX
     * 
     */
    public class DBConnectionPool {
    /**
     * 传说中的连接池
     */
    private List<Connection> freeConnections = new ArrayList<Connection>();
    private Connection con = null;
    private int connect = 0; // 使用的连接数 private int maxConn; // 最大连接
    @SuppressWarnings("unused")
    private String name; // 连接池名字
    private String driver; // 驱动
    private String url; // 数据库连接地址
    private String user; // 用户名
    private String password;// 密码 /**
     * 有惨构造创建连接池
     * 
     * @param driver
     * @param name
     * @param URL
     * @param user
     * @param password
     * @param maxConn
     */
    public DBConnectionPool(String name, String driver, String URL,
    String user, String password, int maxConn) {
    this.name = name;
    this.driver = driver;
    this.url = URL;
    this.user = user;
    this.password = password;
    this.maxConn = maxConn;
    poolInfo();
    } /**
     * 显示准备创建连接池的信息
     */
    private void poolInfo() {
    Connection conn = this.newConnection();
    freeConnections.add(conn);
    for (int i = 0; i < this.maxConn - 1; i++) {
    Connection freeConn = conn;
    freeConnections.add(freeConn);
    }
    } /**
     * 用完,释放连接
     * 
     * @param con
     *            释放一个连接
     */
    public synchronized void freeConnection(Connection con) {
    this.freeConnections.add(con);
    this.connect--;
    } /**
     * 从连接池中获取一个可用连接
     * 
     * 当无法从池中获取可用连接时,新创建一个连接
     * 
     * @return 返回连接对象
     */
    public synchronized Connection getConnection() {
    if (this.freeConnections.size() > 0) {
    con = this.freeConnections.get(0);
    /**
     * 当在池中取出一个连接后,删除此连接
     */
    this.freeConnections.remove(0);
    /**
     * 当取出的连接为null时,递归调用自己,直到获得一个可用连接为止
     */
    if (con == null)
    con = getConnection();
    } else {
    con = newConnection();
    }
    if (this.maxConn == 0 || this.maxConn < this.connect) {
    /**
     * 等待 超过最大连接时
     */
    con = null;
    }
    if (con != null) {
    this.connect++;
    }
    return con;
    } /**
     * 释放全部连接
     * 
     */
    public synchronized void release() {
    Iterator<Connection> allConns = this.freeConnections.iterator();
    while (allConns.hasNext()) {
    Connection conn = (Connection) allConns.next();
    try {
    if (null != conn) {
    conn.close();
    }
    conn = null;
    } catch (SQLException e) {
    e.printStackTrace();
    } }
    this.freeConnections.clear(); } /**
     * 创建一个数据库连接对象
     * 
     * @return 返回数据库连接
     */
    private Connection newConnection() {
    try {
    Class.forName(driver);
    } catch (ClassNotFoundException e2) { e2.printStackTrace();
    }
    try {
    con = DriverManager.getConnection(url, user, password);
    } catch (SQLException e1) {
    e1.printStackTrace();
    System.exit(0);
    }
    return con;
    }
    }package fx.sql;import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Enumeration;
    import java.util.Hashtable;import fx.toolkit.Evn;/**
     * 连接池的管理类,负责读取配置连接池的文件,并创建连接池
     * 
     * 从池中获取,释放连接
     * 
     * @author FX
     * 
     */
    public class DBConnectionManager {
    /**
     * 唯一数据库连接池管理实例类
     * 
     * 使用单例模式创建
     */
    private static DBConnectionManager instance;
    /**
     * 连接池的集合,
     */
    private Hashtable<String, DBConnectionPool> pools = new Hashtable<String, DBConnectionPool>(); /**
     * 得到唯一实例管理类
     * 
     * @return 一个连接池的管理类
     */
    public static synchronized DBConnectionManager getInstance() {
    if (instance == null) {
    instance = new DBConnectionManager();
    }
    return instance; } /**
     * 只允许内部实例化管理类
     */
    private DBConnectionManager() {
    this.init();
    } /**
     * 加载驱动程序
     */
    private void init() {
    Evn evn = new Evn("/db.properties");
    String name = evn.getProperty("name");
    String driver = evn.getProperty("driver");
    String url = evn.getProperty("url");
    String user = evn.getProperty("user");
    String password = evn.getProperty("password");
    int maxConn = Integer.parseInt(evn.getProperty("maxConn"));
    DBConnectionPool pool = new DBConnectionPool(name, driver, url, user,
    password, maxConn);
    pools.put(name, pool);
    } /**
     * 根据连接池的名字得到一个连接
     * 
     * @param name
     *            连接池的名称
     * @return 池中的一个可用连接
     */
    public Connection getConnection(String name) {
    DBConnectionPool pool = null;
    Connection con = null;
    pool = pools.get(name);
    try {
    con = pool.getConnection();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return con;
    } /**
     * 释放一个连接
     * 
     * @param name
     *            连接池的名称
     * @param con
     *            将要是释放的连接对象
     */
    public synchronized void freeConnection(String name, Connection con) {
    DBConnectionPool pool = pools.get(name);// 根据连接池名称得到连接池
    if (pool != null)
    pool.freeConnection(con);// 释放连接
    } /**
     * 释放所有连接
     */
    public synchronized void release() {
    Enumeration<DBConnectionPool> allpools = pools.elements();
    while (allpools.hasMoreElements()) {
    DBConnectionPool pool = allpools.nextElement();
    if (pool != null)
    pool.release();
    }
    pools.clear();
    } public static void main(String[] args) throws SQLException {
    DBConnectionManager manager = new DBConnectionManager();
    Connection conn = manager.getConnection("fxConnPool");
    conn.close();
    }
    }
      

  2.   

    自己要实现一个连接池太复杂了!要考虑的东西太多,比如:连接对象的 close 方法处理、物理连接中断时处理、
    数据库连接池耗尽了之后如何处理等等诸如此类的问题。建议使用 c3p0, dbcp 等等这些开源的连接池。下面这个是 c3p0 的,使用 ConnectionFactory.getConnection() 获得连接之后其他与 JDBC 一样使用。import java.beans.PropertyVetoException;
    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.SQLException;import org.apache.log4j.Logger;import com.bao.config.Config;
    import com.mchange.v2.c3p0.ComboPooledDataSource;public class ConnectionFactory {
        
        private final static Logger LOG = Logger.getLogger(ConnectionManager.class);
        
        private static ComboPooledDataSource ds = new ComboPooledDataSource();
        
        private ConnectionFactory() {
            
        }
        
        static {
            try {
                if(LOG.isDebugEnabled()) {
                    LOG.debug("正在初始化数据连接池");
                }
                Config config = Config.getInstance();
                // c3p0 的 DataSource 设置,其他的参数还有很多,参考 c3p0 文档   
                ds.setDriverClass(config.getJdbcDriver());           // JDBC 驱动
                ds.setJdbcUrl(config.getJdbcUrl());                  // JDBC URL
                ds.setUser(config.getDatabaseUsername());            // 数据库连接用户名
                ds.setPassword(config.getDatabasePassword());        // 数据库连接用户名的密码
                ds.setMaxPoolSize(config.getDatabasePoolMaxSize());  // 最大连接数
                ds.setMinPoolSize(config.getDatabasePoolMinSize());  // 最小连接数
                if(LOG.isDebugEnabled()) {
                    LOG.debug("数据连接池初始化完成" +
                     ", 最大可用连接数:" +ds.getMaxPoolSize() + 
                            ", 最小连接数:" + ds.getMinPoolSize());
                }
            } catch (PropertyVetoException e) {
                LOG.error("连接池初始化失败,原因:" + e.getMessage());
                e.printStackTrace();
            }
        }
        
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
    }
      

  3.   

    如果是我,我会会用动态代理,去处理Connection得close方法
      

  4.   

    为什么我的clients一直在增加没有减少???