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 相关文章推荐
linux下导入、导出mysql数据库命令的实现方法
May 26 MySQL
Mysql systemctl start mysqld报错的问题解决
Jun 03 MySQL
mysql 直接拷贝data 目录下文件还原数据的实现
Jul 25 MySQL
SQL实现LeetCode(180.连续的数字)
Aug 04 MySQL
SQL基础的查询语句
Nov 11 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
MySQL数据库如何给表设置约束详解
Mar 13 MySQL
MySQL创建表操作命令分享
Mar 25 MySQL
MySQL 计算连续登录天数
May 11 MySQL
MySQL中EXPLAIN语句及用法
May 20 MySQL
mysql拆分字符串作为查询条件的示例代码
Jul 07 MySQL
MySQL数据库查询之多表查询总结
Aug 05 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
老机欣赏|中国60年代精品收音机
2021/03/02 无线电
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
php对称加密算法示例
2014/05/07 PHP
php遍历解析xml字符串的方法
2016/05/05 PHP
js chrome浏览器判断代码
2010/03/28 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
基于jquery实现复选框全选,反选,全不选等功能
2015/10/16 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
2016/02/15 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
基于JavaScript代码实现自动生成表格
2016/06/15 Javascript
Web安全测试之XSS实例讲解
2016/08/15 Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
2016/09/20 Javascript
vue-router 导航钩子的具体使用方法
2017/08/31 Javascript
vue.js简单配置axios的方法详解
2017/12/13 Javascript
从setTimeout看js函数执行过程
2017/12/19 Javascript
Node.js搭建WEB服务器的示例代码
2018/08/15 Javascript
微信小程序网络层封装的实现(promise, 登录锁)
2019/05/08 Javascript
浅谈Vue组件单元测试究竟测试什么
2020/02/05 Javascript
vue.config.js中配置Vue的路径别名的方法
2020/02/11 Javascript
python在线编译器的简单原理及简单实现代码
2018/02/02 Python
python kmeans聚类简单介绍和实现代码
2018/02/23 Python
python 获取字符串MD5值方法
2018/05/29 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
python3 assert 断言的使用详解 (区别于python2)
2019/11/27 Python
详解字符串在Python内部是如何省内存的
2020/02/03 Python
django-利用session机制实现唯一登录的例子
2020/03/16 Python
Python集成开发工具Pycharm的安装和使用详解
2020/03/18 Python
使用CSS3实现字体颜色渐变的实现
2020/08/10 HTML / CSS
html5使用canvas画三角形
2014/12/15 HTML / CSS
什么是数据库锁?Oracle中都有哪些类型的锁?
2015/08/21 面试题
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
高三语文教学反思
2014/01/15 职场文书
导游词格式
2015/02/13 职场文书
2016党员干部廉洁自律心得体会
2016/01/13 职场文书
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android