连接池(一)

数据库中连接数量有限,涉及频繁的连接的打开、关闭,影响程序的运行效率,所以需要对数据库连接进行管理,使用连接池管理。

自定义连接池

管理连接,维护了以下几个参数: 初始化数目(init_count)、最大连接数(max_count)、当前连接(current_count)、 连接池集合(pool)

/**
 * 自定义连接池
 *      自己维护一个一定数量的连接,提供get和释放连接方法
 * @author wsk
 *
 */
public class MyPool {
    private int init_count = 3; //维护的连接数量
    private int max_count = 6; //最大连接数量
    private int current_count = 0; //当前连接数
    private LinkedList<Connection> pool = new LinkedList<Connection>(); // 连接存放点

    /**
     * 初始化连接
     */
    public MyPool(){
        for(int i=0;i<init_count;i++){
            pool.add(createConnection());
        }
        System.out.println("初始化连接数量"+init_count);
    }

    /**
     * 创建连接方法
     * @return
     */
    private Connection createConnection(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取连接 
     */
    public Connection getConnection(){
        // 判断连接池中是否还有连接
        if(pool.size()>0){
            System.out.println("从连接池中取出连接对象");
            current_count++;
            return pool.removeFirst();
        }
        // 判断是否超过最大连接数量
        if(current_count<max_count){
            System.out.println("连接池中初始化连接已经用完,新创建连接");
            current_count++;
            return createConnection();
        }

        // 超过最大连接数,抛出异常
        throw new RuntimeException("超过最大连接数");
    }

    /**
     * 释放连接
     */
    public void realeaseConnection(Connection con){
        // 判断当前连接池中数量是否小于初始化数量
        if(pool.size()<init_count){
            current_count--;
            pool.addLast(con);
            System.out.println("连接放入连接池");
        }
        // 当连接池中数量等于初始化连接数量,就释放连接
        try {
            if(current_count>0)
                current_count--;
            con.close();
            System.out.println("连接已经释放");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }   
    }
}

需要注意:上述代码有一个问题,当用户从连接池中拿出连接,但没有使用连接池中定义的realeaseConnection(con)方法释放连接,直接使用con.close()方法关闭连接就会存在问题。
改进方法:使用代理,对连接池中连接接口的close方法生成代理对象。

代理:如果对某个接口中的某个指定的方法的功能进行扩展,而不想实现接口里所有方法,可以使用(动态)代理模式!
Java中代理模式:静态/动态/Cglib代理(spring)
使用动态代理,可以监测接口中方法的执行!

    /**
     * 创建连接方法
     * @return
     */
    private Connection createConnection(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            // 创建连接
            final Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
            // 对连接对象创建代理对象
            Connection proxy = (Connection)Proxy.newProxyInstance(
                        con.getClass().getClassLoader(),            // 对应对象的类加载器 
//                      con.getClass().getInterfaces(),             // 目标对象是一个具体类时
                        new Class[]{Connection.class},              // 对应对象实现的接口(注意当对应对象是一个接口类型时,需要传入该接口)
                        new InvocationHandler() {                   // 当调用con方法时,自动触发事件处理

                            @Override
                            public Object invoke(Object proxy, Method method, Object[] args)
                                    throws Throwable {
                                // 方法返回值
                                Object result = null;
                                // 当前执行方法的方法名
                                String methodName = method.getName();

                                // 判断是否执行close方法
                                if("close".equals(methodName)){
                                    if(pool.size()<init_count){
                                        System.out.println("执行close方法,连接池没满,放入连接池");
                                        // 放入连接池
                                        pool.addLast(con);
                                    }else{
                                        System.out.println("执行close方法,连接池满,关闭连接");
                                        result = method.invoke(con, args);
                                    }
                                }else{
                                    // 调用目标对象方法
                                    result = method.invoke(con, args);
                                }

                                return result;
                            }
                        });

            return proxy;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值