MyBatis连接池底层原理探究
概述
我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间。简单来说,连接池就是用于存储连接的一个容器,容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一连接。同时该集合还必须实现队列的特性:先进先出。
MyBatis连接池原理
配置的位置:
主配置文件SqlMapConfig.xml中的dataSource标签,type属性表示采用何种连接池方式。
MyBatis连接池提供了三种方式的配置:
POOLED:
采用传统的javax.Sql.DataSource规范中的连接池,MyBatis有针对规范的连接;(简单来说,使用POOLED,就是从池中获取一个连接)
UNPOOLED:
采用传统的获取连接的方式,虽然也实现javax.Sql.DataSource接口,但是并没有使用池的思想;(使用UNPOOLED,每次都创建一个新连接)
JNDI:
采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的DataSource不同。但注意,如果不是web或maven的war工程,是不能使用的。
UNPOOLED分析池
public interface DataSource extends CommonDataSource,Wrapper{Connection getConnection() throws SQLException;}
public class UnpooledDataSource implements DataSource{@Overridepublic Connection getConnection() throws SQLException{return doGetConnection(username,password);}private Connection doGetConnection(String username,String password) throws SQLException{//省略其他代码return doGetConnection(props);}private Connection doGetConnection(Properties properties) throws SQLException{//注册驱动initializeDriver();//获取连接Connection connection = DriverManger.getConnection(url,properties);configureConnection(connection);return connection;}private synchronized void initializeDriver() throws SQLException{//...}}
POOLED分析池
public interface DataSource extends CommonDataSource,Wrapper{Connection getConnection() throws SQLException;}
public class PooledDataSource implements DataSource{public Connection getConnection() throws SQLException{return popConnection(dataSource.getUsername(),dataSource.getPassword()).getProxyConnection;}private PooledConnection popConnection(String username,String password) throws SQLException{//省略其他代码while(conn == null){synchronized(state){if(!state.idleConnections.isEmpty()){//空闲连接还有conn = state.idleConnections.remove(0);}else{if(state.activeConnections.size()< poolMaximumActiveConnections){conn = new PooledConnection(dataSource.getConnection(),this);}else{PooledConnection oldestActiveConnection = state.activeConnections.get(0);}}}}}}
后记:
若有错误或者不当之处,可与作者联系,以便一起学习改正!
如果你喜欢本文,
请长按二维码,关注 Jianghq
