JDBC 连接池代码

news/2024/5/18 21:42:57 标签: JDBC, Oracle, SQL, freemarker, thread
import java.sql.*;
import java.lang.reflect.*;

import org.omg.CORBA.portable.InvokeHandler;

import freemarker.template.utility.ObjectConstructor;

/**
 * 定义数据库连接的代理类
 * 
 * @author mark
 * 
 */
public class ConnectionProxy 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 = "rollbakc";

        /**
         * 构造函数,采用私有,防止被直接创建
         * 
         * @param param
         *            连接参数
         */
        private ConnectionProxy(ConnectionParam param) {
                // 记录日志
                try {
                        // 创建连接
                        Class.forName("oracle.jdbc.driver.OracleDriver");
                        conn = DriverManager.getConnection("jdbc:oracle:thin:                                       @10.8.1.234:1521:WF4PPDB","PP42", "PP42");
                        DatabaseMetaData dm = null;
                        dm = conn.getMetaData();
                        // 判断是否支持事务
                        supportTransaction = dm.supportsTransactions();
                } catch (Exception ex) {
                        ex.printStackTrace();
                }
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                Object obj = null;
                // 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
                if (CLOSE.equals(method.getName())) {
                        // 设置不使用标志
                        setFree(false);
                        if (statRef != null)
                                statRef.close();
                        if (preStatRef != null)
                                preStatRef.close();

                        return null;
                }

                // 判断是使用了createStatement语句
                if (CREATESTATE.equals(method.getName())) {
                        try {
                                obj = method.invoke(conn, args);
                                statRef = (Statement) obj;
                                return obj;
                        } catch (ClassCastException ex) {
                                ex.printStackTrace();
                        }
                }

                // 判断是使用了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 ConnectionProxy getConnection(ConnectionFactory factory,
                        ConnectionParam param) {
                // 判断是否正确初始化的工厂
                if (factory.isCreate()) {
                        ConnectionProxy _conn = new ConnectionProxy(param);
                        return _conn;
                } else {
                        return null;
                }

        }

        public Connection getFreeConnection() {
                // 返回数据库连接conn的接管类,以便截住close方法
                Connection cn = (Connection) Proxy.newProxyInstance(conn.getClass()
                         .getClassLoader(), conn.getClass().getInterfaces(), this);
                return cn;
        }

        /**
         * 该方法真正的关闭了数据库的连接
         * 
         * @throws SQLException
         */
        public void close() throws SQLException {
         // 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
                conn.close();
        }

        public void setFree(boolean isFree) {
                this.isFree = isFree;
        }

        public boolean isFree() {
                return isFree;
        }

        /**
         * 判断是否支持事务
         * 
         * @return boolean
         */
        public boolean isSupportTransaction() {
                return supportTransaction;
        }
}


import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;

public class ConnectionFactory {

        private static ConnectionFactory m_instance = null;

        // 在使用的连接池
        private LinkedHashSet ConnectionPool = null;

        // 空闲连接池
        private LinkedHashSet FreeConnectionPool = null;

        // 最大连接数
        private int MaxConnectionCount = 10;

        // 最小连接数S
        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();
                FreeConnectionPool = new LinkedHashSet();
        }

        /**
         * 使用指定的参数创建一个连接池
         * 
         * @throws SQLException
         */
        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) {
                                        // 参数定制
                                    m_instance = new ConnectionFactory();
                                        connparam = param;
                                    m_instance.MaxConnectionCount = fparam
                                                        .getMaxConnectionCount();
                                    m_instance.MinConnectionCount = fparam
                                                        .getMinConnectionCount();
                                    m_instance.ManageType = fparam.getManageType();
                                    m_instance.isflag = true;

                                        // 初始化,创建MinConnectionCount个连接
                                   System.out.println("connection factory 创建!");
                                        try {
                                                for (int i = 0; i < m_instance.MinConnectionCount; i++) {
                                                        ConnectionProxy conn = ConnectionProxy
                                                        .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 ex) {
                                                ex.printStackTrace();
                                        }

                                        // 根据策略判断是否需要查询
                                        if (m_instance.ManageType != 0) {
                                                Thread t = new Thread(new FactoryManageThread(
                                                                m_instance));
                                                t.start();
                                        }
                                }
                        }
                }
        }

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

        /**
         * 从连接池中取一个空闲的连接
         * 
         * @return Connection
         * @throws SQLException
         */
        public synchronized Connection getFreeConnection() throws SQLException {
                Connection cn = null;
                // 获取空闲连接
                Iterator ir = m_instance.FreeConnectionPool.iterator();
                while (ir.hasNext()) {
                        ConnectionProxy conn = (ConnectionProxy) ir.next();
                        // 找到未用的连接
                        if (!conn.isFree()) {
                                cn = conn.getFreeConnection();
                                conn.setFree(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++) {
                                        ConnectionProxy _conn = ConnectionProxy.getConnection(
                                                        m_instance, connparam);
                                        m_instance.FreeConnectionPool.add(_conn);
                                        m_instance.current_conn_count++;
                                }
                        } else {
                                // 如果不能新建,检查是否有已经归还的连接
                                ir = m_instance.ConnectionPool.iterator();
                                while (ir.hasNext()) {
                                        ConnectionProxy _conn = (ConnectionProxy) ir.next();
                                        if (!_conn.isFree()) {
                                                cn = _conn.getFreeConnection();
                                                _conn.setFree(false);
                                                m_instance.ConnectionPool.remove(_conn);
                                                m_instance.FreeConnectionPool.add(_conn);
                                                break;
                                        }
                                }
                        }
                }

                // 再次检查是否能分配连接
                if (cn == null) {
                        ir = m_instance.FreeConnectionPool.iterator();
                        while (ir.hasNext()) {
                                ConnectionProxy _conn = (ConnectionProxy) ir.next();
                                if (!_conn.isFree()) {
                                        cn = _conn.getFreeConnection();
                                        _conn.setFree(true);
                                        m_instance.FreeConnectionPool.remove(_conn);
                                        m_instance.ConnectionPool.add(_conn);
                                        break;
                                }
                        }
                        if (cn == null)
                                // 如果不能则说明无连接可用
                                throw new SQLException("没有可用的数据库连接");
                }

                System.out.println("Get Connection");
                return cn;
        }

        /**
         * 关闭该连接池中的所有数据库连接
         * 
         * @throws SQLException
         */
        public synchronized void close() throws SQLException {
                this.isflag = false;
                SQLException sqlError = null;
                // 关闭空闲池
                Iterator ir = m_instance.FreeConnectionPool.iterator();
                while (ir.hasNext()) {
                        try {
                                ((ConnectionProxy) ir.next()).close();
                                System.out.println("Close connection:Free");
                                m_instance.current_conn_count--;
                        } catch (Exception ex) {
                                if (ex instanceof SQLException) {
                                        sqlError = (SQLException) ex;
                                }
                        }
                }

                // 关闭在使用的连接池
                ir = m_instance.ConnectionPool.iterator();
                while (ir.hasNext()) {
                        try {
                                ((ConnectionProxy) ir.next()).close();
                                System.out.println("Close connection:Using");
                        } catch (Exception ex) {
                                if (ex instanceof SQLException) {
                                        sqlError = (SQLException) ex;
                                }
                        }
                }

                if (sqlError != null)
                        throw sqlError;
        }

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

        /**
         * 连接池调度管理
         * 
         */
        public void schedule() {
                Connection cn = null;
                // 再检查是否能够分配
                Iterator ir = null;
                // 检查是否有已经归还的连接
                ir = m_instance.ConnectionPool.iterator();
                while (ir.hasNext()) {
                        ConnectionProxy _conn = (ConnectionProxy) ir.next();
                        if (!_conn.isFree()) {
                                cn = _conn.getFreeConnection();
                                _conn.setFree(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++) {
                                ConnectionProxy _conn = ConnectionProxy.getConnection(
                                                m_instance, connparam);
                                m_instance.FreeConnectionPool.add(_conn);
                                m_instance.current_conn_count++;
                        }
                }
        }

}

import java.io.Serializable;
import com.mark.human.model.*;

/**
 * 实现数据库连接的参数类
 * 
 * @author mark
 * 
 */
public class ConnectionParam implements Serializable {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        private String driver; // 数据库驱动程序
        private String url; // 数据连接的URL
        private String user; // 数据库用户名
        private String password; // 数据库密码

        public String getDriver() {
                return driver;
        }

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

        public String getPassword() {
                return password;
        }

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

        public String getUrl() {
                return url;
        }

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

        public String getUser() {
                return user;
        }

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

        public ConnectionParam(String driver, String url, String user,
                        String password) {
                this.driver = driver;
                this.url = url;
                this.user = user;
                this.password = password;
        }

        /**
         * @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;
        }

}

/**
 * 连接池调度线程
 * 
 * @author mark
 * 
 */
public class FactoryManageThread implements Runnable {
        ConnectionFactory cf = null;

        long delay = 1000;

        public FactoryManageThread(ConnectionFactory obj) {
                cf = obj;
        }

        /*
         * (non-Javadoc)
         * 
         * @see java.lang.Runnable#run()
         */
        public void run() {
                while (true) {
                        try {
                                Thread.sleep(delay);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        System.out.println("run.....run.....");
                        // 判断是否已经关闭了工厂,那就退出监听
                        if (cf.isCreate())
                                cf.schedule();
                        else
                                System.exit(1);
                }
        }
}

/**
 * 连接池工厂参数
 * 
 * @author mark
 * 
 */
public class FactoryParam {
        // 最大连接数
        private int MaxConnectionCount = 4;

        // 最小连接数
        private int MinConnectionCount = 2;

        // 回收策略
        private int ManageType = 0;

        public FactoryParam() {
        }

        /**
         * 构造连接池工厂参数的对象
         * 
         * @param max
         *            最大连接数
         * @param min
         *            最小连接数
         * @param type
         *            管理策略
         */
        public FactoryParam(int max, int min, int type) {
                this.MaxConnectionCount = max;
                this.MinConnectionCount = min;
                this.ManageType = type;
        }

        public int getManageType() {
                return ManageType;
        }

        public void setManageType(int manageType) {
                ManageType = manageType;
        }

        public int getMaxConnectionCount() {
                return MaxConnectionCount;
        }

        public void setMaxConnectionCount(int maxConnectionCount) {
                MaxConnectionCount = maxConnectionCount;
        }

        public int getMinConnectionCount() {
                return MinConnectionCount;
        }

        public void setMinConnectionCount(int minConnectionCount) {
                MinConnectionCount = minConnectionCount;
        }
}


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class testPool {

        public void test1() {
                String user = "ppuser";
                String password = "ppuser";
                String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
                String driver = "oracle.jdbc.driver.OracleDriver";

                ConnectionParam param = new ConnectionParam(driver, url, user, password);
                ConnectionFactory cf = null;
                // new ConnectionFactory(param,new FactoryParam());
                try {
                        cf = new ConnectionFactory(param, new FactoryParam());
                        Connection conn1 = cf.getFreeConnection();
                        Connection conn2 = cf.getFreeConnection();
                        Connection conn3 = cf.getFreeConnection();
                        Statement stmt = conn1.createStatement();
                        ResultSet rs = stmt.executeQuery("select * from ADMINISTRATION");
                        if (rs.next()) {
                                System.out.println("conn1 y");
                        } else {
                                System.out.println("conn1 n");
                        }
                        stmt.close();
                        conn1.close();
                        Connection conn4 = cf.getFreeConnection();
                        Connection conn5 = cf.getFreeConnection();

                        stmt = conn5.createStatement();
                        rs = stmt.executeQuery("select * from ADMINISTRATION");
                        if (rs.next()) {
                                System.out.println("conn5 y");
                        } else {
                                System.out.println("conn5 n");
                        }

                        conn2.close();
                        conn3.close();
                        conn4.close();
                        conn5.close();
                } catch (Exception ex) {
                        ex.printStackTrace();
                } finally {
                        try {
                                cf.close();
                        } catch (Exception ex) {
                                ex.printStackTrace();
                        }
                }
        }

        /**
         * @param args
         */
        public static void main(String[] args) {
                String user = "ppuser";
                String password = "ppuser";
                String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
                String driver = "oracle.jdbc.driver.OracleDriver";
                ConnectionParam param = new ConnectionParam(driver, url, user, password);
                System.out.println("-------" + param.getDriver());
                ConnectionFactory cf = null;
                try {
                        cf = new ConnectionFactory(param, new FactoryParam());
                        Connection conn1 = null;
                        long time = System.currentTimeMillis();
                        for (int i = 0; i < 10; i++) {
                                conn1 = cf.getFreeConnection();
                                Statement stmt = conn1.createStatement();
                                ResultSet rs = stmt.executeQuery("select * from actioncode");
                                if (rs.next()) {
                                        System.out.println("conn1 y");
                                } else {
                                        System.out.println("conn1 n");
                                }
                                conn1.close();
                        }
                        System.out.println("pool:" + (System.currentTimeMillis() - time));
                        time = System.currentTimeMillis();
                        Class.forName(param.getDriver()).newInstance();
                        for (int i = 0; i < 10; i++) {
                                conn1 = DriverManager.getConnection(param.getUrl(), param
                                                .getUser(), param.getPassword());
                                Statement stmt = conn1.createStatement();
                                ResultSet rs = stmt.executeQuery("select * from actioncode");
                                if (rs.next()) {
                                        System.out.println("conn1 y");
                                        System.out.println(rs.getString(1));
                                        System.out.println(rs.getString(2));
                                } else {
                                        System.out.println("conn1 n");
                                }
                                conn1.close();
                        }
                        System.out
                                        .println("no pool:" + (System.currentTimeMillis() - time));
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        try {
                                cf.close();
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
        }

}
 

http://www.niftyadmin.cn/n/1764686.html

相关文章

解决QQ“抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息”

很多网站&#xff0c;目前无法发起临时会话&#xff0c;自己在找网上找到教程&#xff0c;特分享给大家。自从2014年3月1日开始&#xff0c;网站上放置QQ客服代码的网站&#xff0c;在点击联系QQ时&#xff0c;以前可以正常发起临时会话的&#xff0c;现在提示&#xff1a;“抱…

一种简单JDBC数据库连接池的实现

1.前言   数据库应用&#xff0c;在许多软件系统中经常用到&#xff0c;是开发中大型系统不可缺少的辅助。但如果对数据库资源没有很好地管理(如&#xff1a;没有及时回收数据库的游标(ResultSet)、Statement、连接 (Connection)等资源)&#xff0c;往往会直接导致系统的稳定…

特征选择和特征提取

参考文献1&#xff1a;PCA的数学原理&#xff08;讲得极好&#xff09; 参考文献2&#xff1a;《机器学习导论》 题外话&#xff1a;   上次&#xff0c;参加国内业界最牛逼之一的格林深瞳的笔试和面试&#xff0c;没想到竟然都通过了。高兴之余&#xff0c;实际上&#xff0…

AssetsLibrary 实现访问相册,选取多张照片显示

1 #import "ViewController.h"2 #import <AssetsLibrary/AssetsLibrary.h>3 4 5 /**6 * ALAssetsLibrary.h 代表资源库(所有的视频,照片)7 ALAssetsGroup.h 代表资源库中的相册8 ALAsset.h 代表相册中一个视频或者一张照片9 ALAssetRe…

Java虚拟机参数设置详解

下面的讨论以Windows平台的Sun MicroSystem实现的java5虚拟机为蓝本&#xff0c;其他操作系统或其他公司实现的虚拟机参数会有部分不同&#xff0c;但大部分含义都和Windows上的类似。 Java5与以前版本相比&#xff0c;虚拟机参数大部分保持了向前兼容&#xff0c;同时也增加了…

PMAC运动程序例程(一)

PMAC运动程序例程(一) 日期&#xff1a;2015/06/10 作者&#xff1a;Z.K. 修订信息&#xff1a;2015/08/13修改1 Example1 &1 选择坐标系1 Close 关闭所有的缓冲寄存器 #1->X 将1号电机分配给X轴 OPEN PROG1 …

简单makefile的写法

一个项目下的文件比较多&#xff0c;如果单个的输入&#xff0c;比较费劲&#xff0c;所以就需要把编译过程写进一个MakeFile文件中。 下面建立5个文件&#xff0c;3个cxx文件&#xff0c;2个hxx头文件 //filename main.cxx#include<iostream> #include"printf1.hxx…

用迭代器与组合模式对树进行遍历

相信大家对迭代器模式还是比较熟悉的&#xff0c;在Java的集合中有比较多的应用。比如你想使用迭代器遍历一个集合&#xff0c;代码可能是这样&#xff1a; 1. for (Iterator it collection.iterator(); it.hasNext();)2. {3. doSomething(it.next());4. }迭代器的作用在于…