如何一文快速了解Mybatis连接池和事务
文章目录
- 1、Mybatis 的连接池技术
- 1.1、Mybatis 连接池的分类
- 1.2、Mybatis 中数据源的配置
- 1.3、Mybatis 中 DataSource 的存取
- 1.4、Mybatis 中连接的获取过程分析
2、Mybatis 的事务控制
1、Mybatis 的连接池技术
Mybatis 的连接池是在 Mybatis 的主配置文件: SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled” / >来对 Mybatis 中的连接池进行配置。
1.1、Mybatis 连接池的分类
在 Mybatis 中我们将它的数据源 dataSource 分为以下几类:
可以看出 Mybatis 将它自己的数据源分为三类:
- UNPOOLED 不使用连接池的数据源
- POOLED 使用连接池的数据源
- JNDI 使用 JNDI 实现的数据源
具体结构如下:
相应地,MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource 类和 PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。
在这三种数据源中,我们一般采用的是 POOLED 数据源(很多时候我们所说的数据源就是为了更好的管理数据库连接,也就是我们所说的连接池技术)。
1.2、Mybatis 中数据源的配置
<!-- 我们的数据源配置就是在Mybatis主配置文件: SqlMapConfig.xml 文件中,具体配置如下:--> <!-- 配置数据源(连接池)信息 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> <!-- MyBatis 在初始化时,根据<dataSource>的 type 属性来创建相应类型的的数据源 DataSource,即: type=”POOLED”:MyBatis 会创建 PooledDataSource 实例 type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例 type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用 -->
1.3、Mybatis 中 DataSource 的存取
MyBatis 是通过工厂模式来创建数据源 DataSource 对象的, MyBatis 定义了抽象的工厂接
口:org.apache.ibatis.datasource.DataSourceFactory,通过其 getDataSource()方法返回数据源
DataSource。
下面是 DataSourceFactory 源码,具体如下:
package org.apache.ibatis.datasource; import java.util.Properties; import javax.sql.DataSource; /** * @author cjh */ public interface DataSourceFactory { void setProperties(Properties props); DataSource getDataSource(); }
MyBatis 创建了 DataSource 实例后,会将其放到 Configuration 对象内的 Environment 对象中, 供以后使用。
具体分析过程如下:
1.先进入 XMLConfigBuilder 类中,可以找到如下代码:
2.分析 configuration 对象的 environment 属性,结果如下:
1.4、Mybatis 中连接的获取过程分析
当我们需要创建 SqlSession 对象并需要执行 SQL 语句时,这时候 MyBatis 才会去调用 dataSource 对象来创建java.sql.Connection对象。也就是说,java.sql.Connection对象的创建一直延迟到执行SQL语句的时候。
@Test public void testSql() throws Exception { InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); SqlSession sqlSession = factory.openSession(); List<User> list = sqlSession.selectList("findUserById",41); System.out.println(list.size()); }
只有当第 4 句sqlSession.selectList(“findUserById”),才会触发 MyBatis 在底层执行下面这个方
法来创建 java.sql.Connection 对象。
如何证明它的加载过程呢?
我们可以通过断点调试,在 PooledDataSource 中找到如下 popConnection()方法,如下所示:
分析源代码,得出 PooledDataSource 工作原理如下:
下面是连接获取的源代码:
最后我们可以发现,真正连接打开的时间点,只是在我们执行SQL语句时,才会进行。其实这样做我们也可以进一步发现,数据库连接是我们最为宝贵的资源,只有在要用到的时候,才去获取并打开连接,当我们用完了就再立即将数据库连接归还到连接池中。
2、Mybatis 的事务控制
2.1、JDBC 中事务的回顾
在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。
通过 JDK 文档,我们找到该方法如下:
那么我们的 Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC的setAutoCommit()方法来设置事务提交方式的。
2.2、Mybatis 中事务提交方式
在控制台观察Mybatis执行CUD三类操作的控制台输出:
这是我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进行事务的提交,原因是 setAutoCommit()方法,在执行时它的值被设置为 false 了,所以我们在 CUD 操作中,必须通过 sqlSession.commit()方法来执行提交操作。
2.3、Mybatis 自动提交事务的设置
通过上面的研究和分析,现在我们一起思考,为什么 CUD 过程中必须使用 sqlSession.commit()提交事务?主要原因就是在连接池中取出的连接,都会将调用connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。
明白这一点后,我们现在一起尝试不进行手动提交,一样实现 CUD 操作。
// 利用 SqlSessionFactory 工厂传入 true 参数来创建 SqlSession 对象, SqlSession session = factory.openSession(true);
所对应的 DefaultSqlSessionFactory 类的源代码:
此时事务就设置为自动提交了,同样可以实现CUD操作时记录的保存。虽然这也是一种方式,但就编程而言,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用。因为我们可以根据业务情况来决定提交何时提交何时回滚。
- 点赞
- 收藏
- 分享
- 文章举报
- 一文带你快速了解,python是如何解析XML文件
- 一文带你快速了解,python是如何解析XML文件
- 如何一文快速了解 Mybatis 的注解开发
- 如何一文快速了解 Mybatis 的缓存机制
- 如何一文快速了解 Mybatis 的延迟加载策略
- 一文了解使用swoole如何搭建聊天室程序
- 如何快速的了解一个领域?
- 【工业物联网】一文了解如何实现新型工业化、制造强国(工业物联网白皮书2017)服务|金融|生产|物流应用案例
- 一文了解新营销,数字经济时代如何以个人为中心重建品牌?
- 找工作时如何快速了解一家公司?
- 转贴: 如何快速了解一个项目
- 一文快速了解Java集合框架
- 软件开发者面试百问-----是否了解什么是无状态的业务层?长事务如何与之相适应?
- 如何简单快速的了解"区块链"技术(结尾有惊喜)
- 一文了解:Redis事务
- 如何快速了解自己的Java基础水平
- 如何快速了解企业网盘的安全性?(技术贴)
- 如何快速了解函数的用法
- 干货!手把手教你如何快速了解一个行业--游戏产业概况
- 找工作时如何快速了解一家公司?