赞
踩
Mybatis通过对JDBC进行封装,极大地简化了程序员对数据库的操作,例如对数据库的增删改查操作。其中当进行增删改操作时,都会涉及到用户数据的提交,那么Mybatis中究竟是如何完成数据的提交的呢?这里将对Mybatis中的commit()方法进行简单的剖析,看看底层是如何实现事物提交的。
其实Mybatis中可以设置自动提交功能。在利用工厂模式获得SqlSession实现类对象时,采用openSession(true),即可实现自动提交,无需调用commit()方法。
代码:
创建sqlsession方法(放在工具类里使用)
/**
* @Description: 获取sqlsession
* @param sqlMapConfgi.xml 输入流
* @return sqlSession
* @throws
* @author 康世行
* @date 2021-07-09 11:04
*/
public static SqlSession createSqlSession(InputStream resourcesAsStram){
//创建sqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(resourcesAsStram);
return sqlSessionFactory.openSession(true);//根据SqlSeesion工厂创建SqlSeesion
}
测试代码
/**
* @Description: 保存用户
* @param
* @return ${return_type}
* @throws
* @author 康世行
* @date 2021-07-09 11:40
*/
@Test
public void InsertTest() throws IOException {
//读取配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqMapConfig1.xml");
//获取sqlSession
SqlSession sqlSession = MydatisUtil.createSqlSession(resourceAsStream);
//获取代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//实例化实体
User user=new User();
user.setAddress("廊坊");
user.setSex("男");
user.setUsername("dfasd");
user.setBirthday(new Date());
System.out.println("保存之前"+user);
//获取保存用户方法
int i = userDao.saveUser(user);
System.out.println(i);
if(i==0){
System.out.println("保存失败!");
}else {
System.out.println("保存成功!");
}
System.out.println("保存之后 "+user);
}
结果:
但是程序是为了现实中的应用场景而产生的,现实中往往采用手动提交的方式,避免误操作,因此通常使用的是openSession()方法。
底层获得了一个SqlSession接口的实现类DefaultSqlSession,这是它的构造方法,这里提一句,dirty=false表示该对象中的数据与数据库同步,不是脏数据。改成true就是不与数据库同步,暂时标记为脏数据。
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
//提交事务
sqlSession.commit();
SqlSession 接口
可以在SqlSession接口里看到有两个commit方法,一个是无参数和一个有参数的。
无参数的那个就是我们使用的手动提交事务的方法,有参数的我们传递TRUE进去,就可以不使用手动提交了。可以进行自动提交事务(这样不太安全,不推荐使用)
sqlSession.commit() 里调用DefaulttSqlSession 类里有参数的commit方法,赋值一个默认值 FALSE。 就取消了事务的自动提交!
//无参数
public void commit() {
this.commit(false);
}
//有参数
public void commit(boolean force) {
try {
//调用Executor的commit方法进行提交事务
//
this.executor.commit(this.isCommitOrRollbackRequired(force));
//表示数据与数据库同步,不是脏数据
this.dirty = false;
} catch (Exception var6) {
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + var6, var6);
} finally {
ErrorContext.instance().reset();
}
}
//这个方法里返回TRUE
this.isCommitOrRollbackRequired(force)
private boolean isCommitOrRollbackRequired(boolean force) {
return !this.autoCommit && this.dirty || force;
}
使用的是或的逻辑,左边或者右边任意一个成立都会返回TRUE
this.executor.commit(true); //这就是把this.isCommitOrRollbackRequired(force)方法返回的TRUE赋值给 executor的commit方法。
this.dirty=false;表示数据与数据库同步,不是脏数据。 到此刻数据提交成功!
Executtor //执行器
Defaultsqlsession类里还包含了,增删改查的方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。