使用commons.pool2实现mysql连接池
Posted 数客联盟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用commons.pool2实现mysql连接池相关的知识,希望对你有一定的参考价值。
在使用mysql进行开发的时候,经常会遇到如何控制mysql连接数的问题。比较好的解决方案就是使用一个连接池,控制连接数。org.apache.commons.pool2中提供了对象池管理的框架,可以很方便的解决这个问题。
具体实现
1import java.sql.{Connection, DriverManager}
2import org.apache.commons.pool2.impl.{DefaultPooledObject, GenericObjectPool}
3import org.apache.commons.pool2.{BasePooledObjectFactory, PooledObject}
4object MysqlConnectionPool {
5 def apply(url: String, userName: String, password: String, className: String): GenericObjectPool[Connection] = {
6 new GenericObjectPool[Connection](new MysqlConnectionFactory(url, userName, password, className))
7 }
8}
9class MysqlConnectionFactory(url: String, userName: String, password: String, className: String) extends BasePooledObjectFactory[Connection]{
10 override def create(): Connection = {
11 Class.forName(className)
12 DriverManager.getConnection(url, userName, password)
13 }
14 override def wrap(conn: Connection): PooledObject[Connection] = new DefaultPooledObject[Connection](conn)
15 override def validateObject(pObj: PooledObject[Connection]) = !pObj.getObject.isClosed
16 override def destroyObject(pObj: PooledObject[Connection]) = pObj.getObject.close()
17}
测试
1import java.sql.{Connection, ResultSet, Statement}
2import org.apache.commons.pool2.impl.{GenericObjectPool, GenericObjectPoolConfig}
3object RunApp {
4 def getData(pool: GenericObjectPool[Connection]): Unit ={
5 var stmt: Statement = null
6 var rs: ResultSet = null
7 try {
8 val conn = pool.borrowObject()
9 stmt = conn.createStatement
10 rs = stmt.executeQuery("SELECT * FROM user")
11 for (index <- 1 to rs.getMetaData.getColumnCount){
12 println(rs.getMetaData.getColumnName(index))
13 }
14 Thread.sleep(10000)
15 pool.returnObject(conn)
16 } catch {
17 case ex: Exception =>
18 // handle any errors
19 System.out.println("SQLException: " + ex.getMessage)
20 }
21 }
22 def main(args: Array[String]): Unit = {
23 val conf = new GenericObjectPoolConfig
24 conf.setMaxTotal(2)
25 conf.setMaxIdle(1)
26 conf.setMaxWaitMillis(20000)
27 val pool = MysqlConnectionPool("jdbc:mysql://localhost:3306/tutorials", "root", "root", "com.mysql.jdbc.Driver")
28 pool.setConfig(conf)
29 for (_ <- 1 to 3){
30 new Thread(new Runnable {
31 override def run(): Unit = {
32 getData(pool)
33 }
34 }).start()
35 }
36 }
37}
测试代码中通过conf.setMaxTotal(2)
设置最大使用的连接数为2,也就是说只能同时有两个对象连接mysql,其他对象等待,并且等待的超时时间为conf.setMaxWaitMillis(20000)
。那么在main
函数中启动了3个线程同时对数据库进行查询操作,并且每次查询都会sleeep 10秒。程序运行的时候可以通过show full processlist;
查看mysql的连接数,会发现只有2个对象会同时连接mysql,只有等其中一个运行结束后pool.returnObject(conn)
将连接返还给连接池,第三个线程才会得到资源连接mysql。conf.setMaxIdle(1)
的作用是最多处于idle状态的对象的个数,如果超过这个数量,会自动调用MysqlConnectionFactory
中的destroyObject
方法销毁对象。
总结
通过本文介绍的方式可以有效的控制mysql的连接数。
以上是关于使用commons.pool2实现mysql连接池的主要内容,如果未能解决你的问题,请参考以下文章
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig(示例代
[redis] The type org.apache.commons.pool2.impl.GenericObjectPoolConfig cannot be resolved.It is indi
Spring Boot集成Redis启动失败Caused by: java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.G