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 Innodb关键特性之插入缓冲(insert buffer)
Apr 08 MySQL
MySQL索引知识的一些小妙招总结
May 10 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
如何搭建 MySQL 高可用高性能集群
Jun 21 MySQL
MySQL之MyISAM存储引擎的非聚簇索引详解
Mar 03 MySQL
Mysql 如何合理地统计一个数据库里的所有表的数据量
Apr 18 MySQL
MySQL如何使备份得数据保持一致
May 02 MySQL
Mysql开启外网访问
May 15 MySQL
MySQL数据库 任意ip连接方法
May 20 MySQL
MySQL聚簇索引和非聚簇索引的区别详情
Jun 14 MySQL
mysql sock 文件解析及作用讲解
Jul 15 MySQL
MySQL表字段数量限制及行大小限制详情
Jul 23 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
虫族 Zerg 魔法科技
2020/03/14 星际争霸
利用phpexcel把excel导入数据库和数据库导出excel实现
2014/01/09 PHP
PHP文件类型检查及fileinfo模块安装使用详解
2019/05/09 PHP
php设计模式之建造器模式分析【星际争霸游戏案例】
2020/01/23 PHP
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
javascript 定义新对象方法
2010/02/20 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
javascript语言结构小记(一)
2011/09/10 Javascript
JavaScript实现自己的DOM选择器原理及代码
2013/03/04 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
JS设置cookie、读取cookie
2016/02/24 Javascript
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
vue webpack重写cookie路径的方法
2019/07/10 Javascript
Vue 用Vant实现时间选择器的示例代码
2019/10/25 Javascript
Python的argparse库使用详解
2018/10/09 Python
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
2019/03/11 Python
python将字符串转换成json的方法小结
2019/07/09 Python
pytorch 固定部分参数训练的方法
2019/08/17 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
2020/05/20 Python
tensorflow下的图片标准化函数per_image_standardization用法
2020/06/30 Python
python UIAutomator2使用超详细教程
2021/02/19 Python
美国特价机票专家:Airfarewatchdog
2018/01/24 全球购物
记帐员岗位责任制
2014/02/08 职场文书
销售员个人求职的自我评价
2014/02/10 职场文书
亮化工程实施方案
2014/03/17 职场文书
农村产权制度改革实施方案
2014/03/21 职场文书
敬老院活动总结
2014/04/28 职场文书
企业员工爱岗敬业演讲稿
2014/08/26 职场文书
2014年电厂工作总结
2014/12/04 职场文书
计算机教师工作总结
2015/08/13 职场文书
初中生活随笔
2015/08/15 职场文书
详解vue身份认证管理和租户管理
2021/05/25 Vue.js
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
教你部署vue项目到docker
2022/04/05 Vue.js
Debian11 Xfce终端光标的颜色怎么设置?
2022/08/14 数码科技