Mybatis连接池与事务深入

举报
牛哄哄的柯南 发表于 2021/05/26 14:39:59 2021/05/26
【摘要】 Mybatis连接池与事务深入 Mybatis的连接池技术Mybatis连接池的分类Mybatis中数据源的配置Mybatis中DataSource的存取Mybatis中连接的获取过程分析 Mybatis的事务控制JDBC中事务的回顾Mybatis中事务提交方式Mybatis自动提交事务的设置 Mybatis的连接池技术 在 Mybatis...

Mybatis的连接池技术

在 Mybatis 中有连接池技术,它采用的是自己的连接池技术。配置位置是在 Mybatis 的 SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled”>来实现 Mybatis 中连接池的配置

很多时候我们所说的数据源就是为了更好的管理数据库连接,也就是我们所说的连接池技术。连接池的使用是因为它可以减少我们获取连接所消耗的时间

在这里插入图片描述

Mybatis连接池的分类

Mybatis 将它自己的数据源分为下面三类:

取值 说明
POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想
JNDI 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。注意:如果不是web或者maven的war工程,是不能使用的。

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

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>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即:
type=“POOLED”:MyBatis 会创建 PooledDataSource 实例
type=“UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=“JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

Mybatis中DataSource的存取

MyBatis 是 通 过 工 厂 模 式 来 创 建 数 据 源 DataSource 对 象 的 , MyBatis 定 义 了 抽 象 的 工 厂 接口:org.apache.ibatis.datasource.DataSourceFactory,通过其getDataSource()方法返回数据源DataSource。

Mybatis中连接的获取过程分析

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

真正连接打开的时间点,只是在我们执行SQL语句时,才会进行。其实这样做我们也可以进一步发现,数据库连接是我们最为宝贵的资源,只有在要用到的时候,才去获取并打开连接,当我们用完了就再立即将数据库连接归还到连接池中。

Mybatis的事务控制

JDBC中事务的回顾

在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。
Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的setAutoCommit()方法来设置事务提交方式的。
它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚

Mybatis中事务提交方式

Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。

运行测试代码:

package com.keafmd.test;

import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * Keafmd
 *
 * @ClassName: MybatisTest
 * @Description: 测试类,测试crud操作
 * @author: 牛哄哄的柯南
 * @date: 2021-02-08 15:24
 */
public class MybatisTest { private InputStream in; private SqlSession sqlsession; private IUserDao userDao; @Before // 用于在测试方法执行前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工厂生产SqlSession对象 sqlsession = factory.openSession(); //里面写个true,下面每次就不用了写 sqlsession.commit(); 了 //4.使用SqlSession创建Dao接口的代理对象 userDao = sqlsession.getMapper(IUserDao.class); } @After // 用于在测试方法执行后执行 public void destory() throws Exception{ //提交事务 sqlsession.commit(); //6.释放资源 sqlsession.close(); in.close(); } /** * 测试保存操作 */ @Test public void testSave() throws Exception { User user = new User(); user.setUsername("Keafmd laset insertid"); user.setSex("男"); user.setBirthday(new Date()); user.setAddress("XXXXXXX"); System.out.println("保存操作前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作后:"+user); }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

控制台信息:
在这里插入图片描述

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

Mybatis自动提交事务的设置

在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。
我们设置session = factory.openSession(true);,同时去掉destory()中的session.commit();提交语句,这样就成了自动提交事务了

运行测试代码:

package com.keafmd.test;

import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * Keafmd
 *
 * @ClassName: MybatisTest
 * @Description: 测试类,测试crud操作
 * @author: 牛哄哄的柯南
 * @date: 2021-02-08 15:24
 */
public class MybatisTest { private InputStream in; private SqlSession sqlsession; private IUserDao userDao; @Before // 用于在测试方法执行前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工厂生产SqlSession对象 sqlsession = factory.openSession(true); //里面写个true,下面每次就不用了写 sqlsession.commit(); 了 //4.使用SqlSession创建Dao接口的代理对象 userDao = sqlsession.getMapper(IUserDao.class); } @After // 用于在测试方法执行后执行 public void destory() throws Exception{ //提交事务 //sqlsession.commit(); //6.释放资源 sqlsession.close(); in.close(); } /** * 测试保存操作 */ @Test public void testSave() throws Exception { User user = new User(); user.setUsername("Keafmd laset insertid"); user.setSex("男"); user.setBirthday(new Date()); user.setAddress("XXXXXXX"); System.out.println("保存操作前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作后:"+user); }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

DefaultSqlSessionFactory 类的源代码:

public SqlSession openSession(boolean autoCommit) { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }

  
 
  • 1
  • 2
  • 3

控制台信息:
在这里插入图片描述

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

以上就是Mybatis连接池与事务深入的全部内容。

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端的话,看到右下角的 “一键三连” 了吗,没错点它[哈哈]

在这里插入图片描述

加油!

共同努力!

Keafmd

文章来源: keafmd.blog.csdn.net,作者:牛哄哄的柯南,版权归原作者所有,如需转载,请联系作者。

原文链接:keafmd.blog.csdn.net/article/details/113796767

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。