MyBatis数据源与连接池

MyBatis 把数据源 DataSource 分为三种:

  1. UNPOOLED 不使用连接池的数据源
  2. POOLED 使用连接池的数据源
  3. JNDI(Java Naming and Directory Interface ) 使用 JNDI 实现的数据源

创建数据源

MyBatis 是通过工厂模式来创建数据源 DataSource 对象的,MyBatis 定义了抽象的工厂接
口:org.apache.ibatis.datasource.DataSourceFactory,通过其 getDataSource()方法返回数据源
DataSource。
上述三种不同类型的 type,则有对应的以下 dataSource 工厂:

  • POOLED PooledDataSourceFactory
  • UNPOOLED UnpooledDataSourceFactory
  • JNDI JndiDataSourceFactory

Connection 创建

当我们需要创建 SqlSession 对象并需要执行 SQL 语句时,这时候 MyBatis 才会去调用
dataSource 对象来创建 java.sql.Connection 对象。
也就是说,java.sql.Connection 对象的创
建一直延迟到执行 SQL 语句的时候

Unpooled

当 的 type 属性被配置成了”UNPOOLED”,MyBatis 首先会实例化一个
UnpooledDataSourceFactory 工 厂 实 例 , 然 后 通 过 .getDataSource() 方 法 返 回 一 个
UnpooledDataSource 实例对象引用,我们假定为 dataSource。
使用 UnpooledDataSource 的 getConnection(),每调用一次就会产生一个新的 Connection 实
例对象。
UnpooledDataSource 会做以下事情:

  1. 初始化驱动:判断 driver 驱动是否已经加载到内存中,如果还没有加载,则会动态地加
    载 driver 类,并实例化一个 Driver 对象,使用 DriverManager.registerDriver()方法将其注册
    到内存中,以供后续使用。
  2. 创建 Connection 对象:使用 DriverManager.getConnection()方法创建连接。
  3. 配置 Connection 对象:设置是否自动提交 autoCommit 和隔离级别 isolationLevel。
  4. 返回 Connection 对象

Pooled

PooledDataSource 将 java.sql.Connection 对 象 包 裹 成 PooledConnection 对 象 放 到 了
PoolState 类型的容器中维护。MyBatis 将连接池中的 PooledConnection 分为两种状态: 空闲状态(idle)活动状态(active),这两种状态的 PooledConnection 对象分别被存储到PoolState 容器内的 idleConnectionsactiveConnections 两个 List 集合中:

idleConnections:

空闲(idle)状态 PooledConnection 对象被放置到此集合中,表示当前闲置的
没有被使用的 PooledConnection 集合,调用 PooledDataSource 的 getConnection()方法时,
会优先从此集合中取 PooledConnection 对象。当用完一个 java.sql.Connection 对象时,
MyBatis 会将其包裹成 PooledConnection 对象放到此集合中。

activeConnections:

活 动 (active) 状 态 的 PooledConnection 对 象 被 放 置 到 名 为
activeConnections 的 ArrayList 中,表示当前正在被使用的 PooledConnection 集合,调用
PooledDataSource 的 getConnection() 方 法 时 , 会 优 先 从 idleConnections 集 合 中 取 PooledConnection 对象,如果没有,则看activeConnections集合是否已满,如果未满,PooledDataSource 会创建出一个 PooledConnection,添加到此集合中,并返回。

popConnection()方法到底做了什么:
  1. 先看是否有空闲(idle)状态下的 PooledConnection 对象,如果有,就直接返回一个可用
    的 PooledConnection 对象;否则进行第 2 步。
  2. 查看活动状态的 PooledConnection 池 activeConnections 是否已满;如果没有满,则创
    建一个新的 PooledConnection 对象,然后放到 activeConnections 池中,然后返回此
    PooledConnection 对象;否则进行第三步;
  3. 看最先进入 activeConnections 池中的 PooledConnection 对象是否已经过期:如果已经
    过期,从 activeConnections 池中移除此对象,然后创建一个新的 PooledConnection 对象,
    添加到 activeConnections 中,然后将此对象返回;否则进行第 4 步。
  4. 线程等待

当我们的程序中使用完 Connection 对象时,如果不使用数据库连接池,我们一般会调用
connection.close()方法,关闭 connection 连接,释放资源。
我们希望当 Connection 使用完后,调用.close()方法,而实际上 Connection 资源并没有被释
放,而实际上被添加到了连接池中。
这里要使用代理模式,为真正的 Connection 对象创建一个代理对象,代理对象所有的方法
都是调用相应的真正 Connection 对象的方法实现。当代理对象执行 close()方法时,要特殊
处理,不调用真正 Connection 对象的 close()方法,而是将 Connection 对象添加到连接池中。
MyBatis 的 PooledDataSource 的 PoolState 内部维护的对象是 PooledConnection 类型的对
象,而 PooledConnection 则是对真正的数据库连接 java.sql.Connection 实例对象的包裹器。
PooledConenction 实现了 InvocationHandler 接口,并且 proxyConnection 对象也是根据这它来生成的代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值