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

news2025/6/8 7:59:13

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!!如有问题,欢迎评论区批评指正😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1285916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

github首次将文件合到远端分支,发现名字不是master,而是main

暂存区和本地仓库的信息都存储在.git目录中其中 其中&#xff0c;暂存区和本地仓库的信息都存储在.git目录中 在自己的github上实践 1、刚开始&#xff0c;git clone gitgithub.com:lingze8678/my_github.git到本地 2、在克隆后的代码中加入一个pdf文件 3、在git bash中操作…

查询绑定了所有id的name

1、如图&#xff0c;绑定了所有id的有A,B两个name 2、第一种Sql及效率 explain SELECT name,count(id) as count from test GROUP BY name HAVING count(id)(SELECT count(DISTINCT id) from test); 3、第二种sql及效率 explain select * from (SELECT name,count(id) as co…

VS2022异常解决Could not get emulator name after starting AVD

1、问题描述 在启动安卓仿真器时&#xff0c;弹出这个框 2、设置信息 冲着NET 8升级的VS2022&#xff0c;将其升级为 17.8.2&#xff0c;结果Xamarin开发时&#xff0c;安卓模拟器死活起不来&#xff0c;起来就黑屏。然后网上各种搜解决方案&#xff08;包括不限于&#xf…

Fiddler抓包详细实用保姆级教程,小白一看就会

一、Fiddler4工作原理 Fiddler 是一款以代理web服务器的形式工作的&#xff0c;它使用代理地址:127.0.0.1&#xff0c;端口:8888,这是fiddler的默认端口。 我们发送的每一个请求和收到的每一个响应都会先经过fiddler&#xff0c;这样就实现了抓取数据包的工作 当Fiddler退出时…

C++基础 -41- 迭代器

每个stl 模板接口都有一个专用的迭代器 迭代器就是 stl 库中的 一个特殊指针&#xff0c;功能与指针类似(类似但不是) 迭代器定义格式 迭代器的使用,使用迭代器遍历向量容器的参数 代码运行结果 无论使用普通方式还是迭代器方式去都可以遍历vector容器

软著项目推荐 深度学习的智能中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分&#xff1a;4.2 损失函数&#xff1a;4.3 搭建seq2seq框架&#xff1a;4.4 测试部分&#xff1a;4.5 评价NLP测试效果&#xff1a;4.6 梯度截断…

线程池原理初探

1.引言 合理利用线程池能够带来三个好处。第一&#xff1a;降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二&#xff1a;提高响应速度。当任务到达时&#xff0c;任务可以不需要的等到线程创建就能立即执行。第三&#xff1a;提高线程的可管理性。…

windows下DSS界面本地集成linkis管理台

说明&#xff1a;当前开发环境为windows&#xff0c;node版本使用16.15.1。启动web时&#xff0c;确保后端服务已准备就绪。 1.linkis web编译 #进入项目WEB根目录 $ cd linkis/linkis-web #安装项目所需依赖 $ npm install参考官方编译说明&#xff0c;windows下编译一直异常…

【USRP】5G / 6G 原型系统 5g / 6G prototype system

面向5G/6G科研应用 USRP专门用于5G/6G产品的原型开发与验证。该系统可以在实验室搭建一个真实的5G 网络&#xff0c;基于开源的代码&#xff0c;专为科研用户设计。 软件无线电架构&#xff0c;构建真实5G移动通信系统 X410 采用了目前流行的异构式系统&#xff0c;融合了FP…

利用 EC2 和 S3 免费搭建私人网盘

网盘是一种在线存储服务&#xff0c;提供文件存储&#xff0c;访问&#xff0c;备份&#xff0c;贡献等功能&#xff0c;是我们日常中不可或缺的一种服务。 &#x1f4bb;创建实例 控制台搜索EC2 点击启动EC2 选择AMI 选择可免费试用的 g代表采用了Graviton2芯片。 配置存储 配…

AIGC创作ChatGPT源码+AI绘画(Midjourney绘画)+支持GPT-4-Turbo模型+DALL-E3文生图

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

插入排序和希尔排序

目录 1.插入排序 &#xff08;1&#xff09;基本思想&#xff1a; &#xff08;2&#xff09;直接插入排序 2.希尔排序&#xff08;进阶插排&#xff09; 1.插入排序 &#xff08;1&#xff09;基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本…

客户关系管理系统的功能内容

客户管理是企业经营中至关重要的一环&#xff0c;它涉及到与客户建立、维护和加强关系的全过程。一个成功的客户管理系统能够帮助企业更好地了解客户需求、提供个性化服务&#xff0c;从而提高客户满意度和忠诚度&#xff0c;推动企业的可持续发展。本文将探讨客户管理的各个方…

协议栈的内部结构

上层会向下层逐层委派工作。 最上面的部分是网络应用程序&#xff0c;它们会将收发数据等工作委派给下层的部分来完成。尽管不同的应用程序收发的数据内容不同&#xff0c;但收发数据的操作是共通的。 应用程序的下面是Socket库&#xff0c;其中包括解析器&#xff0c;解析器…

持续集成交付CICD:Jenkins使用GitLab共享库实现后端项目Sonarqube

目录 一、实验 1.Jenkins使用GitLab共享库实现Sonarqube 2.优化GitLab共享库 二、问题 1.sonar-scanner 未找到命令 一、实验 1.Jenkins使用GitLab共享库实现Sonarqube &#xff08;1&#xff09;已搭建GitLab共享库 ① 进入共享库项目 ② 封装库目录(2)Jenkins修改配置…

揭秘DeepMind、OpenAI成立内幕,马斯克、奥特曼、佩奇、哈萨比斯的爱恨情仇......

前些天OpenAI内斗的政权之争&#xff0c;相信各位看官在吃瓜的同时会感到大为震撼。OpenAI这次“政变”事件&#xff0c;让世人第一次看到那些将决定人工智能发展未来的科技大佬之间的激烈争斗。 但权利的斗争在硅谷AI激荡发展十余年中绝不是第一次。《纽约时报》为此采访了80…

MX6ULL学习笔记 (七) 中断实验

前言&#xff1a; 本章我们就来学习一 下如何在 Linux 下使用中断。在linux内核里面使用中断&#xff0c;不同于我们以往在别的裸机开发一样&#xff0c;需要进行各种寄存器的配置&#xff0c;中断使能之类的&#xff0c;而在Linux 内核中&#xff0c;提供了完善的中断框架…

Twincat功能块使用经验总结

控制全局变量&#xff1a; //轴控制指令 bi_Power: BOOL; //使能 bi_Reset: BOOL; //复位 bi_Stop: BOOL; //停止 bi_JogForward: BOOL; //正向点动 bi_JogBackwards: BOOL; //反向点动 bi_MoveAdditive: BOOL; //增量位…

人工智能-机器翻译:技术发展与代码实战

在本文中&#xff0c;我们深入探讨了机器翻译的历史、核心技术、特别是神经机器翻译&#xff08;NMT&#xff09;的发展&#xff0c;分析了模型的优化、挑战及其在不同领域的应用案例。同时&#xff0c;我们还提出了对未来机器翻译技术发展的展望和潜在的社会影响。 关注TechLe…

企业微信配置可信域名

首先去申请一个域名&#xff0c;然后将域名绑定到有公网ip的云服务器上&#xff0c;绑定到具体的网站&#xff1b;然后再企业微信&#xff0c;管理后台&#xff0c;点击具体的应用&#xff0c;进【网页授权及JS-SDK】&#xff1b;点击底部的【申请校验域名】点击下载文件&#…