文章目录

  • 引入
  • 一、Mybatis 的连接池技术
  • 1、Mybatis 连接池的分类
  • 2、Mybatis 中数据源的配置
  • 3、POOLED的过程图解
  • 4、POOLED和UNPOOLED区别图解
  • 二、Mybatis 的事务控制
  • 1、JDBC 中事务的回顾
  • 2、Mybatis 中事务提交方式
  • 3、Mybatis 自动提交事务的设置
  • 4、Mybatis自动提交事务解释图


引入

我们在前面的 WEB 课程中也学习过类似的连接池技术,而在 Mybatis 中也有连接池技术,但是它采用的是自己的连接池技术。在 Mybatis 的 SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled”>来实现 Mybatis 中连接池的配置。

一、Mybatis 的连接池技术

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_提交事务

1、Mybatis 连接池的分类

在 Mybatis 中我们将它的数据源 dataSource 分为以下几类:

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_提交事务_02

可以看出 Mybatis 将它自己的数据源分为三类:

UNPOOLED 不使用连接池的数据源
POOLED 使用连接池的数据源
JNDI 使用 JNDI 实现的数据源

具体结构如下:

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_连接池_03

相应地,MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource,PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。

2、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 实例,然后返回使用

3、POOLED的过程图解

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_连接池_04

4、POOLED和UNPOOLED区别图解

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_数据源_05

二、Mybatis 的事务控制

1、JDBC 中事务的回顾

在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。

2、Mybatis 中事务提交方式

Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。我们运行之前所写的代码:

@Test
public void testSaveUser() throws Exception {
	User user = new User();
	user.setUsername("mybatis user09");
	//6.执行操作
	int res = userDao.saveUser(user);
	System.out.println(res);
	System.out.println(user.getId());
}
@Before//在测试方法执行之前执行
public void init()throws Exception {
	//1.读取配置文件
	in = Resources.getResourceAsStream("SqlMapConfig.xml");
	//2.创建构建者对象
	SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
	//3.创建 SqlSession 工厂对象
	factory = builder.build(in);
	//4.创建 SqlSession 对象
	session = factory.openSession();
	//5.创建 Dao 的代理对象
	userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
	//7.提交事务
	session.commit();
	//8.释放资源
	session.close();
	in.close();
}

观察在它在控制台输出的结果:

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_连接池_06


这是我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进行事务的提交,原因是 setAutoCommit()方法,在执行时它的值被设置为 false 了,所以我们在 CRUD 操作中,必须通过 sqlSession.commit()方法来执行提交操作。

3、Mybatis 自动提交事务的设置

通过上面的研究和分析,现在我们一起思考,为什么 CUD 过程中必须使用 sqlSession.commit()提交事务?主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。

明白这一点后,我们现在一起尝试不进行手动提交,一样实现 CUD 操作。

@Before//在测试方法执行之前执行
public void init()throws Exception {
	//1.读取配置文件
	in = Resources.getResourceAsStream("SqlMapConfig.xml");
	//2.创建构建者对象
	SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
	//3.创建 SqlSession 工厂对象
	factory = builder.build(in);
	//4.创建 SqlSession 对象
	session = factory.openSession(true);
	//5.创建 Dao 的代理对象
	userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
	//7.释放资源
	session.close();
	in.close();
}

所对应的 DefaultSqlSessionFactory 类的源代码:

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_提交事务_07


运行的结果如下:

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_提交事务_08


我们发现,此时事务就设置为自动提交了,同样可以实现CRUD操作时记录的保存。虽然这也是一种方式,但就编程而言,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用。因为我们可以根据业务情况来决定提交是否进行提交。

4、Mybatis自动提交事务解释图

SpringBoot 设置 mybatis 连接池数量 mybatis的连接池有几种_数据源_09