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
- 点赞
- 收藏
- 关注作者
评论(0)