打开一个会话Session
前文阐明白MyBatis将设置文件转换为Java工具的流程,本文开始阐明一下insert要领、update要领、delete要领处理惩罚的流程,至于为什么这三个要领要放在一起说,是因为:
示例代码为这段:
public long insertMail(Mail mail) { SqlSession ss = ssf.openSession(); try { int rows = ss.insert(NAME_SPACE + "insertMail", mail); ss.commit(); if (rows > 0) { return mail.getId(); } return 0; } catch (Exception e) { ss.rollback(); return 0; } finally { ss.close(); } }
首先存眷的是第2行的代码,ssf是SqlSessionFactory,其范例是DefaultSqlSessionFactory,上文最后已经阐明过了,这里通过DefaultSqlSessionFactory来打开一个Session,通过Session去举办CRUD操纵。
看一下openSession()要领的实现:
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }
顾名思义,从DataSource中获取Session,第一个参数的值是ExecutorType.SIMPLE,继承跟代码:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
第4行的代码,获取设置的情况信息Environment。
第5行的代码,从Environment中获取事物工场TransactionFactory,由于<environment>中设置的是”JDBC”,因此其真实范例是JdbcTransactionFactory,上文有说过。
第6行的代码,按照Environment中的DataSource(其实际范例是PooledDataSource)、TransactionIsolationLevel、autoCommit三个参数从TransactionFactory中获取一个事物,留意第三个参数autoCommit,它是openSession()要领中传过来的,其值为false,即MyBatis默认事物是不自动提交的。
第7行的代码,代码跟一下:
public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } if (cacheEnabled) { executor = new CachingExecutor(executor); } executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
这里总结一下:
这样就获取了一个Executor。最后将Executor、Configuration、autoCommit三个变量作为参数,实例化一个SqlSession出来,其实际范例为DefaultSqlSession。
insert要领执行流程
在看了openSession()要领知道最终得到了一个DefaultSqlSession之后,看一下DefaultSqlSession的insert要领是如何实现的:
public int insert(String statement, Object parameter) { return update(statement, parameter); }
看到固然挪用的是insert要领,可是最终统一城市去执行update要领,delete要领也是如此,这个开头已经说过了,这里证明白这一点。
接着继承看第2行的要领实现:
public int update(String statement, Object parameter) { try { dirty = true; MappedStatement ms = configuration.getMappedStatement(statement); return executor.update(ms, wrapCollection(parameter)); } catch (Exception e) { throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
第4行的代码按照statement从Configuration中获取MappedStatement,MappedStatement上文已经阐明过了,存储在Configuration的mappedStatements字段中。