MyBatis连接池底层原理探究

Posted Jianghq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis连接池底层原理探究相关的知识,希望对你有一定的参考价值。

概述

我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间。简单来说,连接池就是用于存储连接的一个容器,容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一连接。同时该集合还必须实现队列的特性:先进先出。



MyBatis连接池原理

  • 配置的位置:

    主配置文件SqlMapConfig.xml中的dataSource标签,type属性表示采用何种连接池方式。

  • MyBatis连接池提供了三种方式的配置:

  1. POOLED:

    采用传统的javax.Sql.DataSource规范中的连接池,MyBatis有针对规范的连接;(简单来说,使用POOLED,就是从池中获取一个连接)

  2. UNPOOLED:

    采用传统的获取连接的方式,虽然也实现javax.Sql.DataSource接口,但是并没有使用池的思想;(使用UNPOOLED,每次都创建一个新连接)

  3. JNDI:

    采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的DataSource不同。但注意,如果不是web或maven的war工程,是不能使用的。



UNPOOLED分析池

public interface DataSource extends CommonDataSource,Wrapper{ Connection getConnection() throws SQLException;}
public class UnpooledDataSource implements DataSource{ @Override public 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{ @Override  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);         }        }      } }  }}
此时涉及到两个池:一个是空闲池,另一个是活动池。如果空闲池中没有连接,再看活动池。如果活动连接池的最大数量小于设定的最大值,则创建一个连接,否则,获取活动连接池中最先进来的那个连接(oldest)。



后记

     若有错误或者不当之处,可与作者联系,以便一起学习改正!




如果你喜欢本文,

请长按二维码,关注 Jianghq


以上是关于MyBatis连接池底层原理探究的主要内容,如果未能解决你的问题,请参考以下文章

[iOS开发]@autoreleasepool原理探究

《深入理解mybatis原理3》 Mybatis数据源与连接池

iOS底层原理 - Block本质探究

swoole4.6.x 连接池底层原理深度分析

springboot官方为何不支持mybatis,而选择底层为hibernate的JPA?

理解数据库连接池底层原理之手写实现