创建一个自己的数据库连接池

思路

1,我的思想是,用一个链表对JDBC连接线程进行保存。这个链表中保存在执行的连接,当一个连接调用close方法的时候,也就证明此连接线程的生命正在走向终结,就将这个连接通过反射代理回收。在添加新的连接线程。
2,我们往线程池中获取连接的时候,getConnection就OK了。

话不多说,直接上代码,对于反射和代理有过了解的,一看代码就明白,写的一个很简陋的连接池。

配置信息

url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
user=root
pass=root
driverClassName=com.mysql.jdbc.Driver

代码

public class MyJDBCPool implements DataSource{

    //创建连接池列表,中间的连接线程通过列表来进行管理
    private final LinkedList<Connection> connections = new LinkedList<>();

    private final Integer numThreads;

    public MyJDBCPool(Integer numThreads) {
        this.numThreads = numThreads;
        this.init();
    }

    //获取配置信息
    private void init() {

        // 获取properties的配置文件,并以流的方式存储
        InputStream inputStream = MyJDBCPool.class.getClassLoader()
                .getResourceAsStream("jdbc.properties");
        // 创建properties的属性处理对象
        Properties properties = new Properties();
        try {
            // 将属性文件载入
            properties.load(inputStream);
            // 获取连接的驱动文件
            Class.forName(properties.getProperty("driverClassName"));
            // 循环创建连接并放入连接池
            for(int i = 0 ;i<this.numThreads;i++){
                // 创建连接对象
                final Connection conn = DriverManager.getConnection(
                        properties.getProperty("url"),
                        properties.getProperty("user"),
                        properties.getProperty("pass"));
                // 将创建分连接对象添加到连接池
                // 通过动态代理处理close的方法实现取出的连接对象返回连接池的效果
                connections.add((Connection) Proxy.newProxyInstance(
                        MyJDBCPool.class.getClassLoader(),
                        new Class[] { Connection.class },
                        new InvocationHandler() {
                            @Override
                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                // 判断当前执行的方法名是不是close时还执行自己的方法体
                                if (!method.getName().equals("close")) {
                                    // 执行目标方法
                                    return method.invoke(conn, args);
                                }
                                System.out.println("又一个连接用玩完了,返回个连接池,当前连接池有"
                                        + connections.size() + "个连接对象");
                                return null;
                            }
                        }));
                System.out.println("线连接池添加了一个链接对象,当前连接池有======"
                        + connections.size() + "=====个连接对象");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
        @Override
    public Connection getConnection() throws SQLException {
            // 声明连接对象
            Connection conn = null;
            // 判断连接池中是否有连接对象
            if (connections.size() > 0) {
                // 从连接池取出连接对象
                conn = connections.removeFirst();
                System.out.println("有一个连接对象被占用,连接池还有=========" + connections.size()
                        + "个连接");
            }

            return conn;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}

测试

public class MyJDBCTest {
    public static void main(String[] args) throws SQLException {
        DataSource dataPool = new MyJDBCPool(10);
        for(int i =0 ;i<5;i++){
            dataPool.getConnection();
        }
        Connection conn = dataPool.getConnection();
        conn.close();
        dataPool.getConnection();
        dataPool.getConnection();
    }
}

测试结果

这里写图片描述

我们在之前有了6次getConnection之后,还剩了4个连接对象,此时close一个,被代理回收了,所以还剩5个连接可用。

猜你喜欢

转载自blog.csdn.net/WeiJiFeng_/article/details/81570413