引言
最近在学习了通用池化框架commons-pool2
实践之后,再HTTP性能测试中进行了实践,结果出乎意料,对于性能提升没啥卵用。经过我自己的本地测试,性能也是足够好的。
后来我仔细想了想,原来是我用错地方了。本来想自己写一个Redis的连接池的没想到,jedis
的连接池本身就是commons-pool2
开发的,让我有点意外,看来想的是一样的。commons-pool2
用来做连接池是非常不错的。
我仔细找了找,发现还缺一个本地的mysql连接池,而不是springboot那样需要启动一个服务才行。当然应该也是有的,不过我非常想自己写一个然后进行各类测试,所以也没有仔细找。
可池化对象
首先,我们需要一个可池化对象,这里我选用了com.funtester.db.mysql.FunMySql
,这是一个我自己写的单链接的MySQL对象。我计划用这个作为基础可池化对象。
packagecom.funtester.db.mysql;
importcom.funtester.base.interfaces.IMySqlBasic;
importcom.funtester.config.SqlConstant;
importJava.sql.Connection;
importjava.sql.ResultSet;
importjava.sql.Statement;
publicclassFunMySqlextendsSqlBaseimplementsIMySqlBasic{
Stringurl;
Stringdatabase;
Stringuser;
Stringpassword;
Connectionconnection;
Statementstatement;
publicFunMySql(Stringurl,Stringdatabase,Stringuser,Stringpassword){
this.url=url;
this.database=database;
this.user=user;
this.password=password;
getConnection(database);
}
@Override
publicvoidgetConnection(){
getConnection(EMPTY);
}
@Override
publicvoidexecuteUpdateSql(Stringsql){
SqlBase.executeUpdateSql(connection,statement,sql);
}
@Override
publicResultSetexecuteQuerySql(Stringsql){
returnSqlBase.executeQuerySql(connection,statement,sql);
}
@Override
publicvoidover(){
SqlBase.close(connection,statement);
}
@Override
publicvoidgetConnection(Stringdatabase){
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
的时候进行连接的回收。
privateclassFunTesterextendsBasePooledObjectFactory<FunMySql>{
@Override
FunMySqlcreate()throwsException{
returnnewFunMySql(url,database,user,password)
}
@Override
PooledObject<FunMySql>wrap(FunMySqlobj){
returnnewDefaultPooledObject<FunMySql>(obj)
}
@Override
voiddestroyObject(PooledObject<FunMySql>p)throwsException{
p.getObject().over()
super.destroyObject(p)
}
}
对象池
这里显得有些冗余,后面再使用过程中,我会继续优化。通过创建一个com.funtester.db.mysql.MysqlPool
对象,获取一个com.funtester.db.mysql.FunMySql
对象池。
classMysqlPoolextendsPoolConstant{
privatestaticfinalLoggerlogger=LogManager.getLogger(MysqlPool.class);
Stringurl;
Stringdatabase;
Stringuser;
Stringpassword;
privateGenericObjectPool<FunMySql>pool
MysqlPool(Stringurl,Stringdatabase,Stringuser,Stringpassword){
this.url=url
this.database=database
this.user=user
this.password=password
init()
}
definit(){
GenericObjectPoolConfigpoolConfig=newGenericObjectPoolConfig();
poolConfig.setMaxTotal(MAX);
poolConfig.setMinIdle(MIN_IDLE);
poolConfig.setMaxIdle(MAX_IDLE);
poolConfig.setMaxWaitMillis(MAX_WAIT_TIME);
poolConfig.setMinEvictableIdleTimeMillis(MAX_IDLE_TIME);
pool=newGenericObjectPool<FunMySql>(newFunTester(),poolConfig);
}
}
API封装
自从学习了Go语言的gorm框架和Redis框架,我发现其实不用把池化相关信息不用暴露出来,直接封装原始的API,暴露给用户使用,这样用户就不用关心连接的回收问题了。
defborrow(){
try{
returnpool.borrowObject()
}catch(e){
logger.warn("获取${jsONObject.class}失败",e)
}finally{
newJSONObject()
}
}
defback(FunMySqlfunMySql){
pool.returnObject(funMySql)
}
defexecute(defsql){
defdriver=borrow()
try{
driver.executeUpdateSql(sql)
}catch(e){
logger.warn("执行:{}失败",sql)
}finally{
back(driver)
}
}
defquery(defsql){
defdriver=borrow()
try{
returndriver.executeQuerySql(sql)
}catch(e){
logger.warn("执行:{}失败",sql)
}finally{
back(driver)
}
}
以上就是MySQL连接池自定义示例详解的详细内容,更多关于MySQL连接池自定义的资料请关注我们其它相关文章!