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 相关文章推荐
MySQL pt-slave-restart工具的使用简介
Apr 07 MySQL
mysql 8.0.24 安装配置方法图文教程
May 12 MySQL
MySQL数据库压缩版本安装与配置详细教程
May 21 MySQL
MySQL系列之九 mysql查询缓存及索引
Jul 02 MySQL
MySql子查询IN的执行和优化的实现
Aug 02 MySQL
Node-Red实现MySQL数据库连接的方法
Aug 07 MySQL
MySQL日期时间函数知识汇总
Mar 17 MySQL
如何创建一个创建MySQL数据库中的datetime类型
Mar 21 MySQL
使用Mysql计算地址的经纬度距离和实时位置信息
Apr 29 MySQL
Mysql InnoDB 的内存逻辑架构
May 06 MySQL
MySQL提升大量数据查询效率的优化神器
Jul 07 MySQL
mysqldump进行数据备份详解
Jul 15 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
基于PHP异步执行的常用方式详解
2013/06/03 PHP
PHP设计模式之观察者模式(Observer)详细介绍和代码实例
2014/04/08 PHP
ThinkPHP模板引擎之导入资源文件方法详解
2014/06/18 PHP
php去掉URL网址中带有PHPSESSID的配置方法
2014/07/08 PHP
php使用pdo连接并查询sql数据库的方法
2014/12/24 PHP
PHP的Yii框架入门使用教程
2016/02/15 PHP
一个简单安全的PHP验证码类 附调用方法
2016/06/24 PHP
js实现DIV的一些简单控制
2007/06/04 Javascript
JQUERY CHECKBOX全选,取消全选,反选方法三
2008/08/30 Javascript
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
jquery实现input框获取焦点的简单实例
2017/01/26 Javascript
vue组件学习教程
2017/09/09 Javascript
Vue循环组件加validate多表单验证的实例
2018/09/18 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
layui表格内容溢出的解决方法
2019/09/06 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
关于vue路由缓存清除在main.js中的设置
2019/11/06 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
vue基础知识--axios合并请求和slot
2020/06/04 Javascript
JavaScript数组类型Array相关的属性与方法详解
2020/09/08 Javascript
vue实现一个获取按键展示快捷键效果的Input组件
2021/01/13 Vue.js
Keras 加载已经训练好的模型进行预测操作
2020/06/17 Python
使用Keras训练好的.h5模型来测试一个实例
2020/07/06 Python
使用Python画了一棵圣诞树的实例代码
2020/11/27 Python
英语感恩演讲稿
2014/01/14 职场文书
社区十八大感言
2014/01/19 职场文书
初三化学教学反思
2014/01/23 职场文书
工作态度检讨书
2014/02/11 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
创建文明城市倡议书
2015/04/28 职场文书
初三英语教学反思
2016/02/15 职场文书
六年级作文之家庭作文
2019/12/12 职场文书
如何开发一个渐进式Web应用程序PWA
2021/05/10 Javascript
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers