您现在的位置是:网站首页> 编程资料编程资料

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

2023-05-26 462人已围观

简介 MySQL池化框架学习接池自定义_Mysql_

引言

最近在学习了通用池化框架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操作的基础类  * 

用于存储数据,多用于爬虫

 */ 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 {         @Override         FunMySql create() throws Exception {             return new FunMySql(url, database, user, password)         }         @Override         PooledObject wrap(FunMySql obj) {             return new DefaultPooledObject(obj)         }         @Override         void destroyObject(PooledObject 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 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(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连接池自定义的资料请关注其它相关文章!

-六神源码网