`
wush121
  • 浏览: 13197 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

几种Java数据库连接池实现(三)<1>

    博客分类:
  • Java
 
阅读更多
package pool;
import java.lang.reflect.*;
import java.sql.*;
/**
*
* 定义数据库连接的代理类
*
*/
public class _Connection implements InvocationHandler {
    // 定义连接
    private Connection conn = null;
    // 定义监控连接创建的语句
    private Statement statRef = null;
    private PreparedStatement prestatRef = null;
    // 是否支持事务标志
    private boolean supportTransaction = false;
    // 数据库的忙状态
    private boolean isFree = false;
    // 最后一次访问时间
    long lastAccessTime = 0;
    // 定义要接管的函数的名字
    String CREATESTATE = "createStatement";
    String CLOSE = "close";
    String PREPARESTATEMENT = "prepareStatement";
    String COMMIT = "commit";
    String ROLLBACK = "rollback";
    /**
    * 构造函数,采用私有,防止被直接创建
    *
    * @param param
    *            连接参数
    */
    private _Connection(ConnectionParam param) { // 记录日志
        try {
            // 创建连接
            Class.forName(param.getDriver()).newInstance();
            conn = DriverManager.getConnection(param.getUrl(), param.getUser(),
                    param.getPassword());
            DatabaseMetaData dm = null;
            dm = conn.getMetaData();
            // 判断是否支持事务
            supportTransaction = dm.supportsTransactions();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    * (non-Javadoc)
    * @see java.lang.reflect.InvocationHandler#invoke
    * (java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
    */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object obj = null;
        // 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
        if (CLOSE.equals(method.getName())) {
            // 设置不使用标志
            setIsFree(false);
            // 检查是否有后续工作,清除该连接无用资源
            if (statRef != null)
                statRef.close();
            if (prestatRef != null)
                prestatRef.close();
            return null;
        }
        // 判断是使用了createStatement语句
        if (CREATESTATE.equals(method.getName())) {
            obj = method.invoke(conn, args);
            statRef = (Statement) obj;// 记录语句
            return obj;
        }
        // 判断是使用了prepareStatement语句
        if (PREPARESTATEMENT.equals(method.getName())) {
            obj = method.invoke(conn, args);
            prestatRef = (PreparedStatement) obj;
            return obj;
        }
        // 如果不支持事务,就不执行该事物的代码
        if ((COMMIT.equals(method.getName()) || ROLLBACK.equals(method
                .getName()))
                && (!isSupportTransaction()))
            return null;
        obj = method.invoke(conn, args);
        // 设置最后一次访问时间,以便及时清除超时的连接
        lastAccessTime = System.currentTimeMillis();
        return obj;
    }

    /**
    * 创建连接的工厂,只能让工厂调用
    * @param factory
    *            要调用工厂,并且一定被正确初始化
    * @param param
    *            连接参数
    * @return 连接
    *
    */
    public static _Connection getConnection(ConnectionFactory factory,
            ConnectionParam param) {
        if (factory.isCreate()) {// 判断是否正确初始化的工厂
            _Connection _conn = new _Connection(param);
            return _conn;
        } else {
            return null;
        }
    }
    public Connection getFreeConnection() {
        // 返回数据库连接conn的接管类,以便截住close方法
        Connection conn2 = (Connection) Proxy.newProxyInstance(conn.getClass()
                .getClassLoader(), conn.getClass().getInterfaces(), this);
        return conn2;
    }
    /**
    *
    * 该方法真正的关闭了数据库的连接
    *
    * @throws SQLException
    *
    */
    void close() throws SQLException {
        // 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
        conn.close();
    }
    public void setIsFree(boolean value) {
        isFree = value;
    }
    public boolean isFree() {
        return isFree;
    }
    /**
    *
    * 判断是否支持事务
    *
    * @return boolean
    *
    */
    public boolean isSupportTransaction() {
        return supportTransaction;
    }
}

package pool;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class ConnectionFactory {
    private static ConnectionFactory m_instance = null;
    // 在使用的连接池
    private LinkedHashSet<_Connection> ConnectionPool = null;
    // 空闲连接池
    private LinkedHashSet<_Connection> FreeConnectionPool = null;
    // 最大连接数
    private int MaxConnectionCount = 4;
    // 最小连接数
    private int MinConnectionCount = 2;
    // 当前连接数
    private int current_conn_count = 0;
    // 连接参数
    private ConnectionParam connparam = null;
    // 是否创建工厂的标志
    private boolean isflag = false;
    // 是否支持事务
    private boolean supportTransaction = false;
    // 定义管理策略
    private int ManageType = 0;
    private ConnectionFactory() {
        ConnectionPool = new LinkedHashSet<_Connection>();
        FreeConnectionPool = new LinkedHashSet<_Connection>();
    }
    /**
    *
    * 使用指定的参数创建一个连接池
    *
    */
    public ConnectionFactory(ConnectionParam param, FactoryParam fparam)
            throws SQLException {
        // 不允许参数为空
        if ((param == null) || (fparam == null))
            throw new SQLException("ConnectionParam和FactoryParam不能为空");
        if (m_instance == null) {
            synchronized (ConnectionFactory.class) {
                if (m_instance == null) {
                    // new instance
                    // 参数定制
                    m_instance = new ConnectionFactory();
                    m_instance.connparam = param;
                    m_instance.MaxConnectionCount = fparam.getMaxConn();
                    m_instance.MinConnectionCount = fparam.getMinConn();
                    m_instance.ManageType = fparam.getType();
                    m_instance.isflag = true;
                    // 初始化,创建MinConnectionCount个连接
                    System.out.println("connection factory 创建!");
                    try {
                        for (int i = 0; i < m_instance.MinConnectionCount; i++) {
                            _Connection _conn = _Connection.getConnection(
                                    m_instance, m_instance.connparam);
                            if (_conn == null)
                                continue;
                            System.out.println("connection创建");
                            m_instance.FreeConnectionPool.add(_conn);// 加入空闲连接池
                            m_instance.current_conn_count++;
                            // 标志是否支持事务
                            m_instance.supportTransaction = _conn
                                    .isSupportTransaction();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 根据策略判断是否需要查询
                    if (m_instance.ManageType != 0) {
                        Thread t = new Thread(
                                new FactoryMangeThread(m_instance));
                        t.start();
                    }
                }
            }
        }
    }

    /**
    *
    * 标志工厂是否已经创建
    *
    * @return boolean
    *
    */
    public boolean isCreate() {
        return m_instance.isflag;
    }

    /**
    *
    * 从连接池中取一个空闲的连接
    *
    * @return Connection
    *
    * @throws SQLException
    *
    */
    public synchronized Connection getFreeConnection() throws SQLException {
        Connection conn = null;
        // 获取空闲连接
        Iterator iter = m_instance.FreeConnectionPool.iterator();
        while (iter.hasNext()) {
            _Connection _conn = (_Connection) iter.next();
            // 找到未用连接
            if (!_conn.isFree()) {
                conn = _conn.getFreeConnection();
                _conn.setIsFree(true);
                // 移出空闲区
                m_instance.FreeConnectionPool.remove(_conn);
                // 加入连接池
                m_instance.ConnectionPool.add(_conn);
                break;
            }
        }
        // 检查空闲池是否为空
        if (m_instance.FreeConnectionPool.isEmpty()) {
            // 再检查是否能够分配
            if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
                // 新建连接到空闲连接池
                int newcount = 0;
                // 取得要建立的数目
                if (m_instance.MaxConnectionCount
                        - m_instance.current_conn_count >= m_instance.MinConnectionCount) {
                    newcount = m_instance.MinConnectionCount;
                } else {
                    newcount = m_instance.MaxConnectionCount
                            - m_instance.current_conn_count;
                }
                // 创建连接
                for (int i = 0; i < newcount; i++) {
                    _Connection _conn = _Connection.getConnection(m_instance,
                            m_instance.connparam);
                    m_instance.FreeConnectionPool.add(_conn);
                    m_instance.current_conn_count++;
                }
            } else {// 如果不能新建,检查是否有已经归还的连接
                iter = m_instance.ConnectionPool.iterator();
                while (iter.hasNext()) {
                    _Connection _conn = (_Connection) iter.next();
                    if (!_conn.isFree()) {
                        conn = _conn.getFreeConnection();
                        _conn.setIsFree(false);
                        m_instance.ConnectionPool.remove(_conn);
                        m_instance.FreeConnectionPool.add(_conn);
                        break;
                    }
                }
            }
        }// if (FreeConnectionPool.isEmpty())
        // 再次检查是否能分配连接
        if (conn == null) {
            iter = m_instance.FreeConnectionPool.iterator();
            while (iter.hasNext()) {
                _Connection _conn = (_Connection) iter.next();
                if (!_conn.isFree()) {
                    conn = _conn.getFreeConnection();
                    _conn.setIsFree(true);
                    m_instance.FreeConnectionPool.remove(_conn);
                    m_instance.ConnectionPool.add(_conn);
                    break;
                }
            }
            if (conn == null)// 如果不能则说明无连接可用
                throw new SQLException("没有可用的数据库连接");
        }
        System.out.println("get connection");
        return conn;
    }

    /**
    *
    * 关闭该连接池中的所有数据库连接
    *
    * @throws SQLException
    *
    */
    public synchronized void close() throws SQLException {
        this.isflag = false;
        SQLException excp = null;
        // 关闭空闲池
        Iterator iter = m_instance.FreeConnectionPool.iterator();
        while (iter.hasNext()) {
            try {
                ((_Connection) iter.next()).close();
                System.out.println("close connection:free");
                m_instance.current_conn_count--;
            } catch (Exception e) {
                if (e instanceof SQLException)
                    excp = (SQLException) e;
            }
        }
        // 关闭在使用的连接池
        iter = m_instance.ConnectionPool.iterator();
        while (iter.hasNext()) {
            try {
                ((_Connection) iter.next()).close();
                System.out.println("close connection:inused");
                m_instance.current_conn_count--;
            } catch (Exception e) {
                if (e instanceof SQLException)
                    excp = (SQLException) e;
            }
        }
        if (excp != null)
            throw excp;
    }

    /**
    *
    * 返回是否支持事务
    *
    * @return boolean
    *
    */
    public boolean isSupportTransaction() {
        return m_instance.supportTransaction;
    }

    /**
    *
    * 连接池调度管理
    *
    *
    *
    */
    public void schedule() {
        //Connection conn = null;
        // 再检查是否能够分配
        Iterator iter = null;
        // 检查是否有已经归还的连接
        iter = m_instance.ConnectionPool.iterator();
        while (iter.hasNext()) {
            _Connection _conn = (_Connection) iter.next();
            if (!_conn.isFree()) {
                //conn = _conn.getFreeConnection();
                _conn.setIsFree(false);
                m_instance.ConnectionPool.remove(_conn);
                m_instance.FreeConnectionPool.add(_conn);
                break;
            }
        }

        if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
            // 新建连接到空闲连接池
            int newcount = 0;
            // 取得要建立的数目
            if (m_instance.MaxConnectionCount - m_instance.current_conn_count >= m_instance.MinConnectionCount) {
                newcount = m_instance.MinConnectionCount;
            } else {
                newcount = m_instance.MaxConnectionCount
                        - m_instance.current_conn_count;
            }
            // 创建连接
            for (int i = 0; i < newcount; i++) {
                _Connection _conn = _Connection.getConnection(m_instance,
                        m_instance.connparam);
                m_instance.FreeConnectionPool.add(_conn);
                m_instance.current_conn_count++;
            }
        }
    }
}

package pool;

import java.io.Serializable;

public class ConnectionParam implements Serializable {
    private static final long serialVersionUID = 1L;

    private String driver; // 数据库驱动程序

    private String url; // 数据连接的URL

    private String user; // 数据库用户名

    private String password; // 数据库密码

    /**
    *
    * 唯一的构造函数,需要指定连接的四个必要参数
    *
    * @param driver
    *            数据驱动
    *
    * @param url
    *            数据库连接url
    *
    * @param user
    *            用户名
    *
    * @param password
    *            密码
    *
    */
    public ConnectionParam(String driver, String url, String user,
            String password) {
        this.driver = driver;
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public String getDriver() {
        return driver;
    }

    public String getPassword() {
        return password;
    }

    public String getUrl() {
        return url;
    }

    public String getUser() {
        return user;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUser(String user) {
        this.user = user;
    }

    /**
    *
    * @see java.lang.Object#clone()
    *
    */
    public Object clone() {
        ConnectionParam param = new ConnectionParam(driver, url, user, password);
        return param;
    }

    /**
    *
    * @see java.lang.Object#equals(java.lang.Object)
    *
    */
    public boolean equals(Object obj) {
        if (obj instanceof ConnectionParam) {
            ConnectionParam param = (ConnectionParam) obj;
            return ((driver.compareToIgnoreCase(param.getDriver()) == 0)
                    && (url.compareToIgnoreCase(param.getUrl()) == 0)
                    && (user.compareToIgnoreCase(param.getUser()) == 0) && (password
                    .compareToIgnoreCase(param.getPassword()) == 0));
        }
        return false;
    }
}
分享到:
评论

相关推荐

    Java jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...

    java数据库连接池

    Java数据库连接池(JDBC Connection Pool)是一种管理数据库连接的技术,它允许应用程序重复使用已经存在的数据库连接,而不是每次需要时都创建新的连接。这大大提高了应用程序的性能和效率,因为创建和销毁数据库...

    JAVA数据库连接池类

    本篇文章将深入解析一个自定义的JAVA数据库连接池类,帮助开发者更好地理解和运用这一关键技术。 首先,连接池的基本思想是预先创建一定数量的数据库连接,并存储在一个集合(如Vector)中,供应用程序按需获取和...

    java项目开发实践经验之二:几种常见数据库连接池的使用比较(转)

    本篇文章将探讨几种常见的数据库连接池的使用比较,包括Proxool、DBCP、C3P0,并通过配置文件(如`proxool.xml`、`dbcp.xml`和`c3p0.xml`)来展示它们的配置细节。 首先,我们来看Proxool,它是一个轻量级的数据库...

    Java数据库连接池的原理与应用.pdf

    Java数据库连接池的原理与应用 在Java开发领域,数据库连接池(Database Connection Pool,简称DBCP)是一种提高数据库访问性能、降低资源消耗的重要技术。它通过预先建立一定数量的数据库连接,存储在一个“池”中...

    TOMCAT中数据库连接池的几种配置方法_TOMCAT中数据库连接池的几种配置方法_

    本文将详细讲解在Tomcat中配置数据库连接池的几种常见方法,帮助开发者实现高效、稳定的数据库访问。 一、Apache Commons DBCP Apache Commons DBCP是Apache组织提供的一款开源数据库连接池组件,它基于Jakarta-...

    java数据库连接池源码及使用示例

    总结来说,本资源提供了学习和实践Java数据库连接池的一个起点。通过分析源码并运行示例,你可以深入理解数据库连接池的实现细节,这将对提升Java应用的数据库性能有很大帮助。同时,这也是一次了解和比较不同连接池...

    Java各数据库连接池配置介绍

    Java数据库连接池是管理数据库连接的一种机制,它可以有效地复用数据库连接,避免每次数据库操作时创建和销毁连接的开销,从而提高了应用的性能。在Java中,有多种数据库连接池实现,包括C3P0、DBCP和Proxool等。 *...

    java数据库连接池的资料

    Java数据库连接池是一种高效管理数据库连接的技术,它在Java应用程序中扮演着至关重要的角色。连接池的基本思想是预先创建一定数量的数据库连接,存储在内存中,当应用程序需要时,从池中获取一个已存在的连接,用完...

    JAVA数据库连接池

    总的来说,Java数据库连接池是提高JSP网站性能的关键技术之一,它通过优化数据库连接的创建和管理,降低了系统资源的消耗,提升了网站的响应速度。正确理解和使用数据库连接池,是每个Java开发者必备的技能。

    java 数据库连接池

    Java数据库连接池是一种重要的技术,它在Java应用程序与数据库交互时起到了关键的作用。数据库连接池在多线程、高并发的环境下尤其重要,因为它能够有效地管理和重用数据库连接,从而提高系统性能,减少资源消耗。 ...

    数据库连接池的配置与使用

    数据库连接池是现代应用程序开发中的重要组成部分,它有效地管理和复用数据库连接,提高了系统的性能和资源利用率。在Java Web开发中,C3P0和DBCP是常用的两种连接池实现。下面将详细介绍这两种连接池的配置与使用。...

    Spring下配置几种常用连接池

    HikariCP被誉为最快的Java数据库连接池,它的设计目标是提供最小的延迟和最大的并发性能。在Spring中配置HikariCP,首先需要添加依赖: ```xml &lt;dependency&gt; &lt;groupId&gt;com.zaxxer&lt;/groupId&gt; &lt;artifactId&gt;HikariCP...

    tomcat数据库连接池的使用

    在Java开发中,Tomcat作为一款广泛使用的应用服务器,提供了对数据库连接池的支持,使得应用程序可以高效、便捷地管理数据库连接。本文将详细介绍如何在Tomcat中配置和使用数据库连接池,以及相关的知识点。 首先,...

Global site tag (gtag.js) - Google Analytics