自定义一个简单的JDBC连接池实现方法(附代码演示)

18 篇文章 0 订阅
3 篇文章 0 订阅

Hi i,m JinXiang


⭐ 前言 ⭐

本篇文章主要介绍自定义一个简单的JDBC连接池实现方法以及部分理论知识


🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁

🍉博主收将持续更新学习记录获,友友们有任何问题可以在评论区留言


目录

⭐什么是连接池?

🍧连接池的实现通常会包括以下几个方面:

⭐如何自定义一个连接池

🍧一、准备工作

🍧二、代码呈现

获取连接--(MyAbsyeactDateSource)

关闭连接--(MyConnection)

两个连接池状态 工作/空闲--(MyDataSoures)

🍧三、结果呈现

取用mysql连接数据库 与 自定义连接池 进行 速度比较

结果


⭐什么是连接池?

连接池(Connection Pool)是一种数据库连接管理技术,它可以对数据库连接进行复用,从而减少了重复创建和删除连接的开销,提高了系统的性能和可扩展性

  • 1、连接池在应用程序启动时创建一定数量的数据库连接,将这些连接保存在内存中,等待应用程序需要时提供给它,应用程序在使用完连接后将其放回连接池,而不是直接关闭它。当连接池中的连接数量不足时,连接池会自动创建新的连接,直到达到连接池的最大连接数为止。
  • 2、连接池的主要作用是提高系统的性能和可扩展性,它可以减少数据库连接的创建和销毁次数,避免了频繁的网络交互和数据库连接的资源消耗,同时也方便了系统的升级和扩展。但连接池的缺点是会占用一定的内存和资源,并且在高并发环境中可能会出现连接池满的情况,需要合理设置连接池的参数,以便在保证系统性能的情况下,最大限度地利用连接池的资源。

🍧连接池的实现通常会包括以下几个方面:

  • 1、连接池大小的管理:连接池的大小对应用程序的性能和数据库的性能都有影响。连接池大小的管理需要根据应用程序的负载情况动态调整,以提供最优的连接数量。
  • 2、连接生命周期的控制:连接池管理连接的生命周期,当连接不再使用时,将其关闭并从连接池中移除。这可以释放资源,避免连接泄漏和占用过多的资源。
  • 3、 连接的复用:连接池可以对数据库连接进行复用,避免每次连接数据库时都要重新创建连接,从而提高应用程序的性能和数据库的响应速度。
  • 4、连接的验证:连接池通常会对连接进行验证,以确保连接可用性。如果连接不可用,连接池会移除该连接并创建新的连接。这可以避免应用程序使用已经失效的连接。

总之,连接池可以有效地管理数据库连接,提高应用程序的性能和数据库的响应速度。

⭐如何自定义一个连接池

一、准备工作

在datasoures创建三个类

二、代码呈现

获取连接--(MyAbsyeactDateSource)
//是在实现mysql实现的连接

package user_defined.datasource;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;



public abstract class MyAbsyeactDateSource implements DataSource {
//=======如何得到一个连接

    private String url;
    private String username;
    private String password;
    private String driverClassName;

    //初始连接数
    private int initialSize = 10;
    //最大连接数
    private int maxActive = 30;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public int getInitialSize() {
        return initialSize;
    }

    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }

    public int getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public boolean isInitFlog() {
        return initFlog;
    }

    public void setInitFlog(boolean initFlog) {
        this.initFlog = initFlog;
    }

    //初始化值
    private boolean initFlog = false;

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

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

    private Connection daDetConnection(String username,String password) throws SQLException {
        if (!initFlog){
            try {
                Class.forName(driverClassName);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            initFlog = true;
        }
        return DriverManager.getConnection(url,username,password);
    }
    @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;
    }

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

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
关闭连接--(MyConnection)
package user_defined.datasource;

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

public class MyConnection implements Connection {
//=======如何关闭一个连接

    private MyDataSoures myDataSoures;
    private Connection  connection;

    //构造方法
    public MyConnection(MyDataSoures myDataSoures, Connection connection) {
        this.myDataSoures = myDataSoures;
        this.connection = connection;
    }
    //只需要实现这两个方法(close,isClosed)
    @Override
    public void close() throws SQLException {
        //把连接从工作连接池放回空闲连接池
        if (myDataSoures.getIdlePool().size() < myDataSoures.getMaxActive()){
            myDataSoures.getWorkPool().remove(this);
            myDataSoures.getIdlePool().addLast(this);
        }

    }

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

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

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return connection.prepareStatement(sql);
    }

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

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

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

    }

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

    @Override
    public void commit() throws SQLException {

    }

    @Override
    public void rollback() throws SQLException {

    }


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

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

    }

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

    @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;
    }
}
两个连接池状态 工作/空闲--(MyDataSoures)
package user_defined.datasource;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyDataSoures extends MyAbsyeactDateSource {
//======两个连接池状态(工作,空闲)

    //工作连接池
    private LinkedList<MyConnection> workPool = new LinkedList<>();

    //空闲连接池
    private LinkedList<MyConnection> idlePool = new LinkedList<>();

    //get方法
    public LinkedList<MyConnection> getWorkPool() {
        return workPool;
    }

    public LinkedList<MyConnection> getIdlePool() {
        return idlePool;
    }

    public MyDataSoures(){

    }

    // TODO  从工作连接池获取到一个连接

    private boolean initFlag = false;


    //重写getconnection方法
    @Override
    public Connection getConnection() throws SQLException {
        MyConnection connection = null;
        this.init();
        //如果空闲连接不为空就直接取
        if (!idlePool.isEmpty()){
            connection = idlePool.removeFirst();
        }else {
            //如果工作连接数小于最大连接数,就创建一个
            if (workPool.size() < super.getMaxActive()){
                connection = new MyConnection(this,super.getConnection());
            }
        }

        if (connection !=null){
            workPool.addLast(connection);
        }

        return connection;
    }

    public void init() throws SQLException {
        //初始化十个连接
        if (!initFlag) {
            while (idlePool.size() < super.getInitialSize()) {
                idlePool.add(new MyConnection(this, super.getConnection()));
            }
            initFlag = true;
        }
    }
}

三、结果呈现

取用mysql连接数据库 与 自定义连接池 进行 速度比较
package user_defined;

import user_defined.datasource.MyDataSoures;

import java.sql.*;

public class Test {
    //自定义连接池
    public static String url = "jdbc:mysql://localhost:3306/1201moviedb?rewriteBatchedStatements=true&serverTimezone=UTC";
    public static String username = "root";
    public static String password = "root";
    public static String driverClassName = "com.mysql.cj.jdbc.Driver";

    @org.junit.Test
    public void TestDateSource() throws SQLException, ClassNotFoundException {
        MyDataSoures myConnection = new MyDataSoures();
        myConnection.setDriverClassName(driverClassName);
        myConnection.setUrl(url);
        myConnection.setUsername(username);
        myConnection.setPassword(password);

        long statr = System.currentTimeMillis(); //
        for (int i = 0; i < 500; i++) {
            Connection connection = myConnection.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        System.out.println("MyDateSource 耗时:"+(end - statr)+"ms");


        //mysql连接数据库
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/1201moviedb?rewriteBatchedStatements=true&serverTimezone=UTC";
        String username = "root";
        String password = "root";

        long statr2 = System.currentTimeMillis(); //
        for (int i = 0; i < 500; i++) {   //执行500次
            Connection con2 = DriverManager.getConnection(url,username,password);
            con2.close();
        }
        long end2 = System.currentTimeMillis();
        System.out.println("传统数据库 耗时:"+(end2 - statr2)+"ms");
    }
}
结果:

MySql连接数据库 耗时4秒 自定义连接池 1秒

总结不易,希望uu们不要吝啬亲爱的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个数据库连接池,需要考虑以下关键思路: 1. 连接池初始化:在初始化时,需要创建一定数量的数据库连接,并将其保存在连接池中,可以使用Java中的数据结构LinkedBlockingQueue来实现连接池。 2. 连接池的获取:当有请求需要连接数据库时,从连接池中获取连接,如果连接池中已经没有可用的连接,可以根据需要创建新的连接。 3. 连接池的释放:当连接使用完毕后,需要及时将其释放回连接池中,以供其他请求使用。 下面是一个简单实现连接池的核心代码: ```java public class DBPool { private static ConnectionPool pool; private static final int POOL_SIZE = 10; // 连接池大小 static { pool = new ConnectionPool(POOL_SIZE); } public static Connection getConnection() throws SQLException { return pool.getConnection(); } public static void releaseConnection(Connection conn) { pool.releaseConnection(conn); } private static class ConnectionPool { private BlockingQueue<Connection> queue; public ConnectionPool(int poolSize) { queue = new LinkedBlockingQueue<>(poolSize); for (int i = 0; i < poolSize; i++) { try { Connection conn = createConnection(); queue.offer(conn); } catch (SQLException e) { e.printStackTrace(); } } } public Connection getConnection() throws SQLException { Connection conn = null; try { conn = queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } return conn; } public void releaseConnection(Connection conn) { if (conn != null) { try { queue.put(conn); } catch (InterruptedException e) { e.printStackTrace(); } } } private Connection createConnection() throws SQLException { // 创建数据库连接 return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456"); } } } ``` 在上面的代码中,我们使用了Java中的BlockingQueue来实现连接池,并在连接池初始化时创建了一定数量的数据库连接。getConnection方法用于获取连接,如果连接池中没有可用连接,该方法会阻塞等待。releaseConnection方法用于将连接释放回连接池中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值