SpringBoot中手动实现JDBC连接池

创建一个工具类:JDBCUtils

package com.example.demo.Util;

import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;

/**
 * @ClassName: JDBCUtils
 * @Description: 实现连接池效果,初始化10个JDBC连接对象并放入池中,提供方法每次返回一个对象
 * @Author: xuezhouyi
 * @Version: V1.0
 **/
@Slf4j
public class JDBCUtils {

    private static String driver;

    private static String url;

    private static String username;

    private static String password;

    //连接池
    private static Queue<Connection> pool = new LinkedList<>();

    static {
        Properties properties = new Properties();
        InputStream is = null;
        try {
            is = JDBCUtils.class.getClassLoader().getResourceAsStream("mysql.properties");
            properties.load(is);
            driver = properties.getProperty("mysql.driver");
            url = properties.getProperty("mysql.url");
            username = properties.getProperty("mysql.username");
            password = properties.getProperty("mysql.password");
        } catch (Exception e) {
            e.printStackTrace();
        }

        //创建三个连接对象(包装类对象)放到池子中
        for (int i = 0; i < 10; i++) {
            Connection connection;
            try {
                Class.forName(driver);
                connection = DriverManager.getConnection(url, username, password);
                Connection connectionWrapper = new ConnectionWrapper(connection, pool);
                pool.add(connectionWrapper);
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("第" + i + "个连接对象放入池中");
        }
    }

    //返回连接对象
    public static Connection getConnection() {

        Connection connection = null;

        if (pool.size() > 0) {
            connection = pool.poll();
        } else {
            //等待超时,返回一个新创建的对象
            try {
                connection = DriverManager.getConnection(url, username, password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        log.info("取出一个对象后,当前池子中有" + pool.size() + "个对象");
        return connection;
    }

}

实现Connection接口修改close方法

package com.example.demo.Util;

import lombok.extern.slf4j.Slf4j;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.Executor;

/**
 * @ClassName: ConnectionWrapper
 * @Description: 实现一个Connection接口重写close方法将对象归还池中
 * @Author: xuezhouyi
 * @Version: V1.0
 **/
@Slf4j
public class ConnectionWrapper implements Connection {

    private Connection connection;

    private Queue<Connection> pool;

    public ConnectionWrapper(Connection connection, Queue<Connection> pool) {
        this.connection = connection;
        this.pool = pool;
    }

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

    //传入SQL
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        return prepareStatement;
    }

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

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

    @Override
    public void setAutoCommit(boolean autoCommit) throws SQLException {

    }

    @Override
    public boolean getAutoCommit() throws SQLException {
        return false;
    }

    @Override
    public void commit() throws SQLException {

    }

    @Override
    public void rollback() throws SQLException {

    }

    //归还
    @Override
    public void close() throws SQLException {
        pool.offer(this);
        log.info("归还一个连接对象后,当前池中还剩" + pool.size() + "个对象");
    }

    @Override
    public boolean isClosed() throws SQLException {
        return false;
    }

    @Override
    public DatabaseMetaData getMetaData() throws SQLException {
        return null;
    }

    @Override
    public void setReadOnly(boolean readOnly) throws SQLException {

    }

    @Override
    public boolean isReadOnly() throws SQLException {
        return false;
    }

    @Override
    public void setCatalog(String catalog) throws SQLException {

    }

    @Override
    public String getCatalog() throws SQLException {
        return null;
    }

    @Override
    public void setTransactionIsolation(int level) throws SQLException {

    }

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

    @Override
    public SQLWarning getWarnings() throws SQLException {
        return null;
    }

    @Override
    public void clearWarnings() throws SQLException {

    }

    @Override
    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    @Override
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    @Override
    public Map<String, Class<?>> getTypeMap() throws SQLException {
        return null;
    }

    @Override
    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {

    }

    @Override
    public void setHoldability(int holdability) throws SQLException {

    }

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

    @Override
    public Savepoint setSavepoint() throws SQLException {
        return null;
    }

    @Override
    public Savepoint setSavepoint(String name) throws SQLException {
        return null;
    }

    @Override
    public void rollback(Savepoint savepoint) throws SQLException {

    }

    @Override
    public void releaseSavepoint(Savepoint savepoint) throws SQLException {

    }

    @Override
    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    @Override
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
        return null;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
        return null;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
        return null;
    }

    @Override
    public Clob createClob() throws SQLException {
        return null;
    }

    @Override
    public Blob createBlob() throws SQLException {
        return null;
    }

    @Override
    public NClob createNClob() throws SQLException {
        return null;
    }

    @Override
    public SQLXML createSQLXML() throws SQLException {
        return null;
    }

    @Override
    public boolean isValid(int timeout) throws SQLException {
        return false;
    }

    @Override
    public void setClientInfo(String name, String value) throws SQLClientInfoException {

    }

    @Override
    public void setClientInfo(Properties properties) throws SQLClientInfoException {

    }

    @Override
    public String getClientInfo(String name) throws SQLException {
        return null;
    }

    @Override
    public Properties getClientInfo() throws SQLException {
        return null;
    }

    @Override
    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
        return null;
    }

    @Override
    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
        return null;
    }

    @Override
    public void setSchema(String schema) throws SQLException {

    }

    @Override
    public String getSchema() throws SQLException {
        return null;
    }

    @Override
    public void abort(Executor executor) throws SQLException {

    }

    @Override
    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {

    }

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

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

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

测试类

package com.example.demo;

import com.example.demo.Util.JDBCUtils;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {

    @Test
    public void contextLoads() throws SQLException {
        final Connection connection = JDBCUtils.getConnection();
        final PreparedStatement pstm = connection.prepareStatement("select * from db");
        final ResultSet resultSet = pstm.executeQuery();
        while (resultSet.next()) {
            System.out.println(resultSet.getString("db")+"-"+resultSet.getString("user"));
        }
        final Connection connection1 = JDBCUtils.getConnection();
        final Connection connection2 = JDBCUtils.getConnection();
        connection.close();
        connection1.close();
        connection2.close();
    }

}

测试日志

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.1.RELEASE)

2019-11-24 20:18:55.617  INFO 4244 --- [           main] com.example.demo.DemoApplicationTests    : Starting DemoApplicationTests on XavierXue with PID 4244 (started by XavierXue in C:\Users\XavierXue\IdeaProjects\apache\demo)
2019-11-24 20:18:55.619  INFO 4244 --- [           main] com.example.demo.DemoApplicationTests    : No active profile set, falling back to default profiles: default
2019-11-24 20:18:56.368  INFO 4244 --- [           main] com.example.demo.DemoApplicationTests    : Started DemoApplicationTests in 1.283 seconds (JVM running for 2.649)
2019-11-24 20:18:56.929  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第0个连接对象放入池中
2019-11-24 20:18:56.934  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第1个连接对象放入池中
2019-11-24 20:18:56.938  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第2个连接对象放入池中
2019-11-24 20:18:56.942  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第3个连接对象放入池中
2019-11-24 20:18:56.946  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第4个连接对象放入池中
2019-11-24 20:18:56.951  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第5个连接对象放入池中
2019-11-24 20:18:56.955  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第6个连接对象放入池中
2019-11-24 20:18:56.960  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第7个连接对象放入池中
2019-11-24 20:18:56.963  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第8个连接对象放入池中
2019-11-24 20:18:56.967  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 第9个连接对象放入池中
2019-11-24 20:18:56.968  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 取出一个对象后,当前池子中有9个对象
sys-mysql.sys
2019-11-24 20:18:56.982  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 取出一个对象后,当前池子中有8个对象
2019-11-24 20:18:56.982  INFO 4244 --- [           main] com.example.demo.Util.JDBCUtils          : 取出一个对象后,当前池子中有7个对象
2019-11-24 20:18:56.982  INFO 4244 --- [           main] com.example.demo.Util.ConnectionWrapper  : 归还一个连接对象后,当前池中还剩8个对象
2019-11-24 20:18:56.982  INFO 4244 --- [           main] com.example.demo.Util.ConnectionWrapper  : 归还一个连接对象后,当前池中还剩9个对象
2019-11-24 20:18:56.982  INFO 4244 --- [           main] com.example.demo.Util.ConnectionWrapper  : 归还一个连接对象后,当前池中还剩10个对象

Process finished with exit code 0
发布了54 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/DataIntel_XiAn/article/details/103228303