MySQL池化框架学习接池自定义


Posted in MySQL onJuly 23, 2022

引言

最近在学习了通用池化框架commons-pool2实践之后,再HTTP性能测试中进行了实践,结果出乎意料,对于性能提升没啥卵用。经过我自己的本地测试,性能也是足够好的。

后来我仔细想了想,原来是我用错地方了。本来想自己写一个Redis的连接池的没想到,jedis的连接池本身就是commons-pool2开发的,让我有点意外,看来想的是一样的。commons-pool2用来做连接池是非常不错的。

我仔细找了找,发现还缺一个本地的MySQL连接池,而不是springboot那样需要启动一个服务才行。当然应该也是有的,不过我非常想自己写一个然后进行各类测试,所以也没有仔细找。

可池化对象

首先,我们需要一个可池化对象,这里我选用了com.funtester.db.mysql.FunMySql,这是一个我自己写的单链接的MySQL对象。我计划用这个作为基础可池化对象。

package com.funtester.db.mysql;
import com.funtester.base.interfaces.IMySqlBasic;
import com.funtester.config.SqlConstant;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
/**
 * mysql操作的基础类
 * <p>用于存储数据,多用于爬虫</p>
 */
public class FunMySql extends SqlBase implements IMySqlBasic {
    /**
     *  {@link SqlConstant#FUN_SQL_URL}会替换IP到URL
     */
    String url;
    /**
     * 库
     */
    String database;
    /**
     * 用户
     */
    String user;
    /**
     * 密码
     */
    String password;
    Connection connection;
    Statement statement;
    /**
     * 私有构造方法
     *
     * @param url      连接地址,包括端口
     * @param database 库
     * @param user     用户名
     * @param password 密码
     */
    public FunMySql(String url, String database, String user, String password) {
        this.url = url;
        this.database = database;
        this.user = user;
        this.password = password;
        getConnection(database);
    }
    /**
     * 初始化连接
     */
    @Override
    public void getConnection() {
        getConnection(EMPTY);
    }
    /**
     * 执行sql语句,非query语句,并不关闭连接
     *
     * @param sql
     */
    @Override
    public void executeUpdateSql(String sql) {
        SqlBase.executeUpdateSql(connection, statement, sql);
    }
    /**
     * 查询功能
     *
     * @param sql
     * @return
     */
    @Override
    public ResultSet executeQuerySql(String sql) {
        return SqlBase.executeQuerySql(connection, statement, sql);
    }
    /**
     * 关闭query连接
     */
    @Override
    public void over() {
        SqlBase.close(connection, statement);
    }
    @Override
    public void getConnection(String database) {
        if (connection == null)
            connection = SqlBase.getConnection(SqlConstant.FUN_SQL_URL.replace("ip", url).replace("database", database), user, password);
        if (statement == null) statement = SqlBase.getStatement(connection);
    }
}

池化工厂

相对连接,创建com.funtester.db.mysql.FunMySql的时候,顺便一起初始化MySQL连接。然后再com.funtester.db.mysql.MysqlPool.FunTester#destroyObject的时候进行连接的回收。

    /**
     * 池化工厂类
     */
    private class FunTester extends BasePooledObjectFactory<FunMySql> {
        @Override
        FunMySql create() throws Exception {
            return new FunMySql(url, database, user, password)
        }
        @Override
        PooledObject<FunMySql> wrap(FunMySql obj) {
            return new DefaultPooledObject<FunMySql>(obj)
        }
        @Override
        void destroyObject(PooledObject<FunMySql> p) throws Exception {
            p.getObject().over()
            super.destroyObject(p)
        }
    }

对象池

这里显得有些冗余,后面再使用过程中,我会继续优化。通过创建一个com.funtester.db.mysql.MysqlPool对象,获取一个com.funtester.db.mysql.FunMySql对象池。

/**
 * 自定义MySQL连接池对象
 */
class MysqlPool extends PoolConstant {
    private static final Logger logger = LogManager.getLogger(MysqlPool.class);
    /**
     * {@link com.funtester.config.SqlConstant#FUN_SQL_URL}会替换IP到URL*/
    String url;
    /**
     * 库
     **/
    String database;
    /**
     * 用户
     **/
    String user;
    /**
     * 密码
     **/
    String password;
    private GenericObjectPool<FunMySql> pool
    MysqlPool(String url, String database, String user, String password) {
        this.url = url
        this.database = database
        this.user = user
        this.password = password
        init()
    }
    /**
     * 初始化连接池
     * @return
     */
    def init() {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(MAX);
        poolConfig.setMinIdle(MIN_IDLE);
        poolConfig.setMaxIdle(MAX_IDLE);
        poolConfig.setMaxWaitMillis(MAX_WAIT_TIME);
        poolConfig.setMinEvictableIdleTimeMillis(MAX_IDLE_TIME);
        pool = new GenericObjectPool<FunMySql>(new FunTester(), poolConfig);
    }
}

API封装

自从学习了Go语言的gorm框架和Redis框架,我发现其实不用把池化相关信息不用暴露出来,直接封装原始的API,暴露给用户使用,这样用户就不用关心连接的回收问题了。

    /**
     * 借出对象
     * @return
     */
    def borrow() {
        try {
            return pool.borrowObject()
        } catch (e) {
            logger.warn("获取${JSONObject.class} 失败", e)
        } finally {
            new JSONObject()
        }
    }
    /**
     * 归还对象
     * @param funMySql
     * @return
     */
    def back(FunMySql funMySql) {
        pool.returnObject(funMySql)
    }
    /**
     * 执行update SQL
     * @param sql
     * @return
     */
    def execute(def sql) {
        def driver = borrow()
        try {
            driver.executeUpdateSql(sql)
        } catch (e) {
            logger.warn("执行:{}失败", sql)
        } finally {
            back(driver)
        }
    }
    /**
     * 执行查询SQL
     * @param sql
     * @return
     */
    def query(def sql) {
        def driver = borrow()
        try {
            return driver.executeQuerySql(sql)
        } catch (e) {
            logger.warn("执行:{}失败", sql)
        } finally {
            back(driver)
        }
    }

以上就是MySQL连接池自定义示例详解的详细内容,更多关于MySQL连接池自定义的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
Windows10下安装MySQL8
Apr 06 MySQL
MySQL 分页查询的优化技巧
May 12 MySQL
MySQL 全文检索的使用示例
Jun 07 MySQL
mysql连接查询中and与where的区别浅析
Jul 01 MySQL
SQL实现LeetCode(196.删除重复邮箱)
Aug 07 MySQL
SQL IDENTITY_INSERT作用案例详解
Aug 23 MySQL
SQL 聚合、分组和排序
Nov 11 MySQL
关于MySQL中的 like操作符详情
Nov 17 MySQL
Mysql Innodb存储引擎之索引与算法
Feb 15 MySQL
MySQL去除密码登录告警的方法
Apr 20 MySQL
mysql 索引的数据结构为什么要采用B+树
Apr 26 MySQL
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
Dec 24 MySQL
mysql sock文件存储了什么信息
Jul 15 #MySQL
mysql sock 文件解析及作用讲解
Jul 15 #MySQL
mysqldump进行数据备份详解
Jul 15 #MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 #MySQL
MySQL事务的隔离级别详情
Jul 15 #MySQL
MySQL事务的ACID特性以及并发问题方案
Jul 15 #MySQL
MySQL的意向共享锁、意向排它锁和死锁
Jul 15 #MySQL
You might like
深入了解php4(2)--重访过去
2006/10/09 PHP
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
关于PHP语言构造器介绍
2013/07/08 PHP
PHP实现加强版加密解密类实例
2015/07/29 PHP
PHP导出带样式的Excel示例代码
2016/08/28 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
JS的递增/递减运算符和带操作的赋值运算符的等价式
2007/12/08 Javascript
Javascript 获取LI里的内容
2008/12/17 Javascript
javascript xml为数据源的下拉框控件
2009/07/07 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
简介JavaScript中的push()方法的使用
2015/06/09 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
将鼠标焦点定位到文本框最后(代码分享)
2017/01/11 Javascript
jQuery tip提示插件(实例分享)
2017/04/28 jQuery
详解JavaScript按概率随机生成事件
2017/08/02 Javascript
javascript帧动画(实例讲解)
2017/09/02 Javascript
浅谈vue路径优化之resolve
2017/10/13 Javascript
js实时监控文本框输入字数的实例代码
2018/01/18 Javascript
新版vue-cli模板下本地开发环境使用node服务器跨域的方法
2018/04/03 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
PyTorch实现重写/改写Dataset并载入Dataloader
2020/07/14 Python
解决Python安装cryptography报错问题
2020/09/03 Python
pandas针对excel处理的实现
2021/01/15 Python
CSS3 渐变(Gradients)之CSS3 线性渐变
2016/07/08 HTML / CSS
瑜伽服装品牌:露露柠檬(lululemon athletica)
2017/06/04 全球购物
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
保时捷设计:Porsche Design
2019/03/30 全球购物
Ruby如何进行文件操作
2014/07/17 面试题
汽车维修与检测专业应届生求职信
2013/11/12 职场文书
应届大学生自荐书
2014/06/17 职场文书
2015年银行个人工作总结
2015/05/14 职场文书
股权投资协议书
2016/03/23 职场文书
低端且暴利的线上线下创业项目分享
2019/09/03 职场文书
教你怎么用python selenium实现自动化测试
2021/05/27 Python