Create a database connection pool of your own

thinking

1. My idea is to save JDBC connection thread with a linked list. When a connection calls the close method, it also proves that the life of the connection thread is ending, so the connection is recycled through the reflection agent. Add a new connection thread at.
2. When we get the connection to the thread pool, getConnection is OK.

If you don't say much, just go to the code. If you have any knowledge of reflection and proxy, you can see it at a glance. It's a very simple connection pool.

configuration information

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

Code

public class MyJDBCPool implements DataSource{

    //Create the connection pool list, and the connection threads in the middle are managed through the list
    private final LinkedList<Connection> connections = new LinkedList<>();

    private final Integer numThreads;

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

    //Get configuration information
    private void init() {

        // Get the configuration file of properties and store it as a stream
        InputStream inputStream = MyJDBCPool.class.getClassLoader()
                .getResourceAsStream("jdbc.properties");
        // Create property handling objects for properties
        Properties properties = new Properties();
        try {
            // Load properties file
            properties.load(inputStream);
            // Get connected driver file
            Class.forName(properties.getProperty("driverClassName"));
            // Loop create connections and put them in the connection pool
            for(int i = 0 ;i<this.numThreads;i++){
                // Create connection object
                final Connection conn = DriverManager.getConnection(
                        properties.getProperty("url"),
                        properties.getProperty("user"),
                        properties.getProperty("pass"));
                // Add the create sub connection object to the connection pool
                // The effect of returning the connection object to the connection pool is realized by the method of dynamic agent processing 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 {
                                // When judging whether the currently executed method name is close, it also executes its own method body
                                if (!method.getName().equals("close")) {
                                    // Implementation target method
                                    return method.invoke(conn, args);
                                }
                                System.out.println("Another connection is finished,Return connection pools,The current connection pool has"
                                        + connections.size() + "Connection objects");
                                return null;
                            }
                        }));
                System.out.println("Line connection pool added a link object,The current connection pool has======"
                        + connections.size() + "=====Connection objects");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
        @Override
    public Connection getConnection() throws SQLException {
            // Declare connection object
            Connection conn = null;
            // Determine whether there are connection objects in the connection pool
            if (connections.size() > 0) {
                // Remove connection objects from connection pool
                conn = connections.removeFirst();
                System.out.println("There is a connection object occupied,The connection pool also has=========" + connections.size()
                        + "A connection");
            }

            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;
    }
}

test

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();
    }
}

test result

After we had getConnection six times before, there are four connection objects left. At this time, one is close d and recycled by the agent, so there are five connections available.

Keywords: JDBC MySQL

Added by ttmt on Sun, 05 Jan 2020 22:33:27 +0200