连接池的实现以及适配器的介绍

连接池的实现

基本思想:之前使用JDBC得到一个Connection是使用 DriverManager 获得一个Connection,随时用,随时创建Connection。而连接池则是通过重写 java.sql.DataSource 的方法得到Connection以及包装Connection的方法完成close操作。

具体步骤:通过创建 Mydatasource implements datascource 首先就在这里通过 LinkedList 创建好10个Connection ,重写getConnection返回LinkedList里的Connection ,在这里需要包装Connection的close()方法(使得用完了的connection返回到LinkedList里面去)

TestJDBC.java

package com.datasource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestJDBC {

    public void test1() {
        Connection conn = null;
        PreparedStatement ps = null;

        DataSource ds = new MyDataSource();
        try {
            conn = ds.getConnection();//从池中取出一个连接

            ps = conn.prepareStatement("...");

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            try{
           	 conn.close();//调用的是包装后的方法,使得用完的conn返回到连接池中
            }
            catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
}

Mydatasource.java

package com.datasource;

import com.util.DButils;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.logging.Logger;

public class MyDataSource implements DataSource {

    //创建一个存放连接的池子
    private static LinkedList<Connection> pool = (LinkedList<Connection>) Collections.synchronizedList(new LinkedList<Connection>());

    static{
        try {
            for (int i = 0; i < 10; i++) {
                Connection conn = DButils.getConnection();
                pool.add(conn);
            }
        }catch(SQLException e){
                throw new ExceptionInInitializerError("初始化数据库连接失败,请检查配置文件是否正确");
        }
    }

    public Connection getConnection() throws SQLException {
        Connection conn = null;
        if(pool.size()>0){
            conn = pool.removeFirst();//从池中取出一个连接
            Connection myConn = new MyConnection(conn,pool);//得到一个包装后的MyConnection对象
            return myConn;
        }else{
            //等待
            //新创建一个连接
            throw new RuntimeException("服务器忙。。。");
        }
    }

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



    @Override
    public ConnectionBuilder createConnectionBuilder() throws SQLException {
        return null;
    }

   //...省略需要重写的方法
}

MyConnection.java

package com.datasource;

import java.sql.*;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

public class MyConnection implements Connection {

    private Connection oldConnection;//com.mysql.jdbc.Connection
    private LinkedList<Connection> pool;//连接池对象

    public MyConnection(Connection oldConnection, LinkedList<Connection>pool){
        this.oldConnection = oldConnection;//得到com.mysql.jdbc.Connection
        this.pool = pool;//得到连接池对象

    }


    public void close() throws SQLException {
        pool.addLast(oldConnection);
    }

    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return oldConnection.prepareStatement(sql);  //这些语句就依然调用原来的方法
    }

    @Override
    public Statement createStatement() throws SQLException {
        return oldConnection.createStatement();
    }



    @Override
    public CallableStatement prepareCall(String sql) throws SQLException {
        return oldConnection.prepareCall(sql);
    }

    @Override
    public String nativeSQL(String sql) throws SQLException {
        return oldConnection.nativeSQL(sql);
    }

    //假设所有需要重写的方法都写完了调用的原来自己的方法
   
}

有个很明显的缺点在于,其他不用的方法,需要全部自己实现调用原来的方法,那么解决这个问题,需要使用适配器
1)public class MyConnectionWraper implements Connection //这里面提前写好oldConn里面所有的调用原来的方法。
2)public class MyConnection extends MyConnectionWarper //这样这里只需要写你需要修改的方法,如close()

猜你喜欢

转载自blog.csdn.net/weixin_42036647/article/details/82869487