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 root密码的重置方法
Apr 21 MySQL
MySQL的join buffer原理
Apr 29 MySQL
MySQL创建高性能索引的全步骤
May 02 MySQL
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
May 29 MySQL
如何使用分区处理MySQL的亿级数据优化
Jun 18 MySQL
MySQL系列之八 MySQL服务器变量
Jul 02 MySQL
MySQL 聚合函数排序
Jul 16 MySQL
MYSQL 运算符总结
Nov 11 MySQL
MySQL插入数据与查询数据
Mar 25 MySQL
解决MySQL Varchar 类型尾部空格的问题
Apr 06 MySQL
MySQL数据库Innodb 引擎实现mvcc锁
May 06 MySQL
delete in子查询不走索引问题分析
Jul 07 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
动态新闻发布的实现及其技巧
2006/10/09 PHP
PHP5函数小全(分享)
2013/06/06 PHP
PHP图片处理之使用imagecopyresampled函数实现图片缩放例子
2014/11/19 PHP
php可生成缩略图的文件上传类实例
2014/12/17 PHP
WordPress中编写自定义存储字段的相关PHP函数解析
2015/12/25 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
2016/09/11 PHP
帮助避免错误的Javascript陷阱清单
2009/05/31 Javascript
jQuery中将函数赋值给变量的调用方法
2012/03/23 Javascript
JavaScript操作cookie类实例
2015/03/31 Javascript
异步JS框架的作用以及实现方法
2015/10/29 Javascript
轻松5句话解决JavaScript的作用域
2016/07/15 Javascript
JS判断form内所有表单是否为空的简单实例
2016/09/09 Javascript
a标签置灰不可点击的实现方法
2017/02/06 Javascript
如何理解jQuery中的ajaxSubmit方法
2017/03/13 Javascript
vue router demo详解
2017/10/13 Javascript
基于webpack4搭建的react项目框架的方法
2018/06/30 Javascript
微信小程序时间标签和时间范围的联动效果
2019/02/15 Javascript
vue+iview动态渲染表格详解
2019/03/19 Javascript
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
Python返回真假值(True or False)小技巧
2015/04/10 Python
详细分析python3的reduce函数
2017/12/05 Python
详解python执行shell脚本创建用户及相关操作
2019/04/11 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
python global和nonlocal用法解析
2020/02/03 Python
Python sys模块常用方法解析
2020/02/20 Python
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
越南母婴用品购物网站:Kids Plaza
2020/04/09 全球购物
班级年度安全计划书
2014/05/01 职场文书
小学生九一八纪念日83周年演讲稿500字
2014/09/17 职场文书
党的群众路线教育实践活动个人整改措施材料
2014/11/04 职场文书
涪陵白鹤梁导游词
2015/02/09 职场文书
2015年售票员工作总结
2015/04/29 职场文书
校车司机安全责任书
2015/05/11 职场文书
MongoDB支持的索引类型
2022/04/11 MongoDB
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang