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

吾爱主题 阅读:143 2024-04-01 23:20:08 评论:0
目录
  • 引言
  • 可池化对象
  • 池化工厂
  • 对象池
  • API封装

引言

最近在学习了通用池化框架commons-pool2实践之后,再HTTP性能测试中进行了实践,结果出乎意料,对于性能提升没啥卵用。经过我自己的本地测试,性能也是足够好的。

后来我仔细想了想,原来是我用错地方了。本来想自己写一个Redis的连接池的没想到,jedis的连接池本身就是commons-pool2开发的,让我有点意外,看来想的是一样的。commons-pool2用来做连接池是非常不错的。

我仔细找了找,发现还缺一个本地的MySQL连接池,而不是springboot那样需要启动一个服务才行。当然应该也是有的,不过我非常想自己写一个然后进行各类测试,所以也没有仔细找。

可池化对象

首先,我们需要一个可池化对象,这里我选用了com.funtester.db.mysql.FunMySql,这是一个我自己写的单链接的MySQL对象。我计划用这个作为基础可池化对象。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 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的时候进行连接的回收。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18      /**       * 池化工厂类       */      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对象池。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 / * *   *  自定义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,暴露给用户使用,这样用户就不用关心连接的回收问题了。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51      / * *       *  借出对象       *  @ 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连接池自定义的资料请关注服务器之家其它相关文章!

原文链接:https://mp.weixin.qq.com/s/3VYzupjP8URkOYakidNOrg

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容