MyBatis的基本API简介

MyBatis是一个优秀的基于Java的持久层框架。其内部封装了JDBC,使开发者只需要关注SQL语句本身,不用花费精力去处理如注册驱动,创建Connection,配置Statement等繁琐过程。

我们通过测试案例来看下MyBatis的基本API的使用及相关简介;

public void insertTest(Student student) {
		try {
			// 1.加载主配置文件
			InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
			// 2.创建SqlSessionFactory对象
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			sqlSession = sqlSessionFactory.openSession();
			// 4.相关数据库操作
			sqlSession.insert("insert", student);
			
			sqlSession.commit();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(sqlSession != null) {
				sqlSession.close();
			}
		}
	}

我们需要通过SqlSession对象来操作数据库,而SqlSession对象的创建,需要其工厂对象SqlSessionFactory对象;SqlSessionFactory对象需要通过其构建器对象SqlSessionFactoryBuilder的build()方法,在加载了主配置文件的输入流对象后创建的;

SqlSessionFactoryBuilder类

SqlSessionFactory的创建,需要使用SqlSessionFactoryBuilder对象的build()方法,由于SqlSessionFactory对象在创建完工厂后,就完成了其使命,即可被销毁。所以我们一般=将SqlSessionFactoryBuilder对象创建为一个方法内的局部对象,方法结束后,对象销毁;

SqlSessionFactory接口

SqlSessionFactory接口对象是一个重量级对象,系统开销大,是线程安全的,所以一个应用只需要一个该对象即可。创建SqlSession需要使用SqlSessionFactory接口的openSession()方法;
openSession(true):创建一个有自动提交功能的SqlSession
openSession(false):创建一个非自动提交功能的Sql’Session,需要手动提交;
默认为创建一个非自动提交功能的SqlSession.

SqlSession接口

SqlSession接口对象用于执行持久化操作,一个SqlSession对应这一次数据库会话,一次会话以SqlSession对象的创建开始,以SqlSession对象的关闭结束。
SqlSession接口的对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其close()方法,将其关闭。再次需要会话,再次创建。而关闭时会判断当前SqlSession是否被提交,若没有被提交,则会执行回滚后关闭;若已被提交,则直接将SqlSession关闭,所以,SqlSession无需手工回滚;

在上面的测试案例我们发现有几个问题,看MyBatis是如何帮我们解决的;
1.我们读取配置的文件的流没有关闭?
我们查看SqlSessionFactoryBuilder对象的build()方法,查看其底层源码:
在这里插入图片描述
我们可以看到在输入流被使用后,SqSessionFactoryBuilder对象的build()方法会自动将输入流关闭,不需要我们手动关闭;

2.我们调用SqlSession.commit()方法就会提交事务?
我们查看SqlSession对象的创建,需要使用SqlSessionFactory接口对象的openSession()方法;SqlSessionFactory接口的实现类为DefaultSqlSessionFactory;
在这里插入图片描述
从这里我们也可以知道openSession()方法默认是创建了一个非自动提交的SqlSession;

在这里插入图片描述
在这里插入图片描述
我们看到创建SqlSession时就是加载主配置文件,然后创建一个执行器对象,然后会初始化一个数据库数据被修改的标志变量dirty;

然后SqlSession对象调用对应的增删改查方法,我们在测试案例中调用insert方法,我们看其底层实现:
在这里插入图片描述
大家可以查看下SqlSession的insert(),delete(),update()方法,其底层均是调用的update()方法;我们也可以看到底层调用update()方法中会将变量dirty修改为true; 并且根据对应的statement获取映射文件中指定id的Sql语句,然后将Sql交给执行器executor执行;

我们接下来在看我们SqlSession的commit()方法;
在这里插入图片描述
当executor执行完成后,又会将dirty变量更新为false;
在这里插入图片描述
我们从底层代码知道,isCommitOrRollbackRequired(false)方法的返回值为true; 即:autoCommit为false; dirty = true ; force = false;
然后在调用executor的commit()方法;
在这里插入图片描述
从底层代码调用可以看到SqlSession的无参commit()方法,最终会将事务进行提交的。

3.SqlSession如何进行回滚的?
我们查看SqlSession的关闭close()方法底层的实现:
在这里插入图片描述
executor关闭后,会将数据被修改的标志dirty重置为false,表示前面的更新操作已经结束了,此时的数据处于未被修改的状态;
我们首先看下sqlSession.commit后在进行sqlSession.close():
在这里插入图片描述
在这里插入图片描述
注意此时isCommitOrRollbackRequired(false)方法返回的是false;
this.autoCommit = false;
this.dirty = false; 由于SqlSession.commit后,会将改变量重置为false;

在这里插入图片描述
this.rollback()方法实现:
在这里插入图片描述
接下来我们在看下,如果没有执行commit(),直接执行的close()方法会怎么样?
我们直接看下isCommitOrRollbackRequired方法
在这里插入图片描述
我们在执行更新操作的时候,底层调用update()方法就会将dirty更新为true;可以看到isCommitOrRollbackRequired方法最终返回的是true; 继续看executor的close方法:
在这里插入图片描述

在这里插入图片描述
从上面的代码中可以知道,在SqlSession进行关闭时,会将事务回滚后关闭,所以对于,无需通过显示的对SqlSession进行回滚,达到事务回滚的目的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值