首页 > 代码库 > 浅谈MyBatis3连接池
浅谈MyBatis3连接池
1、在spring中注入MyBatis自带连接池的时候,仅仅只是设置上了一些数据库连接的必要数据,比如driver、url、username、password等,并不会去连接数据库
2、Mybatis连接池的状态都是由PoolState这个类来维护的,最重要的就是两个list:idleConnections、activeConnections,分别用来保存空闲连接和活动连接,这个PoolState对象在使用过程中需要同步
3、PooledConnection也就是连接池里维护的连接对象,这个类里代理了java.sql.Connection这个普通的Connection,主要代理了两种方法:
①close方法,并不是调用RealConnection的close方法,而是把该连接放回连接池
②在调用其他方法时还加了有效性的检验
if (!Object.class.equals(method.getDeclaringClass())) { // issue #579 toString() should never fail // throw an SQLException instead of a Runtime checkConnection(); }
这里要注意的是,PooledDataSource提供了一个静态方法用来得到RealConnection,unwrapConnection(Connection conn),需要传入一个PooledConnection
4、当用户需要一个数据库连接时,连接池会调用popConnection方法,连接池会先看看空余队列里是否有连接,若有的话直接取第一个连接并返回给用户。若没有,那么去判断是否超过了最大活跃连接数,若没,那么就去创建一个数据库连接,调用的是非连接池的getConnection方法
conn = new PooledConnection(dataSource.getConnection(), this);
第二个参数是数据库连接池的引用,这个在将此PooledConnection关闭的时候放回连接池的时候要使用,会调用PooledDataSource里的pushConnection(PooledConnection conn)方法
对popCollection方法我画了一个流程图,画的不好,见谅~
5、在初始化sqlSessionFactory的时候会调用,一个sqlSessionFactory绑定一个datasource
VendorDatabaseIdProvider.getDatabaseId(DataSource dataSource)
// 这里的databaseIdProvider 貌似不会为null,因为初始化时有new if (this.databaseIdProvider != null) { try { configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource)); } catch (SQLException e) { throw new NestedIOException("Failed getting a databaseId", e); } }
6、要得到databaseId,需要连接数据库得到数据库的元数据(metaData)
7、protected boolean pingConnection(PooledConnection conn)
这个方法是用来测试该连接是否还可用,用在PooledConnection.isValid方法中
通过PooledDataSource中的poolPingQuery来设置用来测试的sql语句