自定义连接池、连接池解决现状问题的原理

1.1 连接池的概念

  • 我们现实生活中的每日三餐,并不会吃一餐饭就将碗扔掉,而是吃完饭后将碗放到橱柜中,下一餐接着使用。目的是重复利用碗,我们数据库连接也可以重复使用,可以减少数据库连接的创建次数。提高数据库连接对象的使用率。
  • 连接池的概念:连接池是创建和管理数据库连接的缓冲池技术。连接池就是一个容器,连接池中保存了一些数据库连接,这些连接是可以重复使用的

1.2 没有连接池的状态

  •  之前JDBC访问数据库的步骤:创建数据库连接-》运行SQL语句=》关闭连接  ,每次数据库访问执行这样重复的动作。

 自定义连接池、连接池解决现状问题的原理_第1张图片

 

  •  每次创建数据库连接的问题:
  1. 获取数据库连接需要消耗比较多的资源,而每次操作都要重新获取新的连接对象,执行一次操作就把连接关闭,而数据库创建连接通常需要消耗相对较多的资源,创建时间也较长。这样数据库连接对象的使用率低。
  2. 假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大地浪费了数据库的资源,并且极易造成数据库服务器内存溢出。

1.3 连接池解决现状问题的原理

  1. 程序一开始就创建一定数量的连接,放在一个容器中,这个容器称为连接池(相当于碗柜/容器)。
  2. 使用的时候直接从连接池中取出一个已经创建好的连接对象。
  3. 关闭的时候不是真正关闭连接,而是将连接对象再次放回到连接池中。 

 自定义连接池、连接池解决现状问题的原理_第2张图片

 


2.1 自定义连接池

2.1.1 数据库连接池相关API

  • java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池。

2.1.2 自定义连接池步骤

  1.  定义一个类实现javax.sql.DataSource接口。
  2. 实现DataSource中的抽象方法。
  3. 定义连接池相关参数。
  4. 创建容器保存连接。
  5. 提供获取连接方法。
  6. 提供关闭连接方法。
package pool;

import Utils.JDBCUtils;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
/*
    自定义连接池
 */
public class MyPool implements DataSource {
    public static void main(String[] args) throws SQLException {
        //创建连接池
        MyPool pool = new MyPool();
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        System.out.println("连接:"+pool.getConnection());
        Connection connection = pool.getConnection();
        System.out.println("连接:"+connection);
        //由于我们的编程习惯,关闭一个资源的时候,我们都习惯使用   资源.close(); 而不是 pool.close(connection);
        //别人调用connection对象的close方法的时候,实现的是还给连接池,也不是真正意义的关闭
        //connection.close();
        pool.close(connection);
        System.out.println("连接:"+pool.getConnection());
    }


     //初始化池子连接个数
    private int initCount = 3;
    //最大连接个数
    private int maxCount = 10;
    //当前已经创建的连接个数
    private int curCount = 0;


    //定义一个容器用于存储连接
    private LinkedList list = new LinkedList();


    //创建连接
    public Connection createConnection(){
        Connection connection = JDBCUtils.getConnection();
        curCount++;
        return connection;
    }

    public MyPool(){
        //一旦创建连接池的时候就会存在3个连接
        for(int i=0;i0){
            Connection connection = list.removeFirst();
            return connection;
        }
        //情况二:当前创建的连接个数并没超出最大值
        if(curCount T unwrap(Class iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class iface) throws SQLException {
        return false;
    }
}
  • 自定义连接池当前存在的问题
  • 根本原因connection对象的close方法并不能满足我们当前的需求,要解决这个问题,就需要用到动态代理
  • 由于我们的编程习惯,关闭一个资源的时候,我们都习惯使用    资源.close。
  • 别人调用connection对象的close方法的时候,实现的是还给连接池,也不是真正意义的关闭。

 自定义连接池、连接池解决现状问题的原理_第3张图片

 

你可能感兴趣的:(JDBC,连接池解决现状问题的原理,自定义连接池和动态代理)