Mybatis中的数据源与连接池

Mybatis中的数据源与连接池

在使用Mybatis框架时需要对核心配置文件进行设置,其中就包括了数据源和连接池。
本文只进行原理的描述,不包含实际代码。

一、为什么要使用连接池?

创建一个Conncection代价是巨大的,因为创建了一个连接,在底层就与数据库建立了通信连接,
连接之后往往只进行简单的sql操作,浪费了巨大的资源。

二、数据库连接池的基本思想

为数据库建立一个“连接池”,预先创建一定数量的连接,当需要连接时,只需从中取出一个,使用
完毕之后再放回。

三、数据源与连接池的描述

1.数据源的分类

(1)UNPOOLED 不使用连接池的数据源
                --用实现了java.sql.DataSource的UnpooledDataSource类来表示
(2)POOLED 使用连接池的数据源
                --用实现了java.sql.DataSource的PooledDataSource类来表示
(3)JNDI 使用JNDI实现的数据源
                --通过JNDI上下文中取值

注释:PooledDataSource和UnpooledDataSource都实现了java.sql.DataSource接口。
可是当PooledDataSource需要创建java.sql.Connection对象时,是通过UnpooledDataSource来创建的,因为在PooledDataSource中持有一个UnpooledDataSource的引用,PooledDataSource只是提供一种缓存连接池机制。

2.数据源DataSource的创建过程

Mybatis数据源DataSource对象的创建发生在MyBatis初始化过程中。

(1)Mybatis初始化时,解析xml,根据<datasource>中的type属性来创建相应类型的DataSource。

注释:Mybatis创建DataSource根据工厂模式,三种工厂分别是
    UnpooledDataSourceFactory 实现了DataSourceFactory接口
    JndiDataSourceFactory   实现了DataSourceFactory接口
    PooledDataSourceFactory  继承了UnpooledDataSourceFactory

(2)创建DataSource实例之后,会将实例放入Configuration对象中的Environment对象中。

3.DataSource什么时候创建Connection对象

创建SqlSession对象执行SQL语句时才调用相应的DataSource来创建Connection对象。
例如执行到sqlSession.selectList("SELECT * FROM STUDENTS");  才创建Connection对象。

4.不使用连接池的UnpooledDataSource

使用UnpooledDataSource的getConnection(),每调用一次就会产生一个新的Connection实例对象。

5.使用了连接池的PooledDataSource

PooledDataSource将Connection对象包裹成PooledConnection对象放入PoolState类型容器中。
Mybatis将PoolConnection分为两种状态:空闲状态(idle)和活动状态(active),这两种状态
被分别存储到PoolState容器内的idleConnections和activeConnections两个List集合中。

idleConnections:idle状态的PooledConnection放入其中,表示当前没被使用的连接,需要连接时,优先从中取出。当用完一个Connection对象后,又会被包裹成PooledConnection放到此集合中。

activeConections:active状态的PoolConnection放入其中,表示正在使用。当需要连接时,优先从idleConnections中取,如果没有,就看activeConnections集合是否已经满了,没满的话PooledDataSource会创建出一个PooledConnection添加到这个集合中,并返回。

6.获取java.sql.Connection对象的过程

先看是否有空闲(idle)状态下的PooledConnection对象,如果有,就直接返回一个可用的PooledConnection对象;否则进行第2步。

查看活动状态的PooledConnection池activeConnections是否已满;如果没有满,则创建一个新的PooledConnection对象,然后放到activeConnections池中,然后返回此PooledConnection对象;否则进行第3步;

看最先进入activeConnections池中的PooledConnection对象是否已经过期:如果已经过期,从activeConnections池中移除此对象,然后创建一个新的PooledConnection对象,添加到activeConnections中,然后将此对象返回;否则进行第4步。

线程等待,循环2步(代码见参考资料)

7.java.sql.Connection对象的回收

如何将用完之后的连接自动放回连接池,而不是手动将Connection放到Pool连接池?
所以应该实现Connection对象调用了close()方法,实际上却是将对象添加到连接池。
这是要使用代理模式,为真正的Connection对象创建一个代理对象,
代理对象所有的方法都是调用相应的真正Connection对象的方法实现。当代理对象执行close()方法时,
要特殊处理,不调用真正Connection对象的close()方法,而是将Connection对象添加到连接池中。
具体代码见参考资料。

8.JNDI类型的数据源DataSource

对于JNDI类型的数据源DataSource的获取就比较简单,MyBatis定义了一个JndiDataSourceFactory工厂
来创建通过JNDI形式生成的DataSource。具体代码见参考资料。

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值