前言
本篇幅是继 MyBatis详解(一)的下半部分。
MyBatis执行Sql的流程分析
【1】基于前面已经将XML文件进行build解析了并且返回了SqlSessionFactory
【1.1】那么分析SqlSessionFactory.openSession()方法是怎么返回SqlSession的,且SqlSession又是什么东西:
@Override public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } /** * 方法实现说明:从session中开启一个数据源 * @param execType:执行器类型 * @param level:隔离级别 */ 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); // 创建一个sql执行器对象 // 一般情况下 若我们的mybaits的全局配置文件的cacheEnabled默认为ture就返回一个cacheExecutor,若关闭的话返回的就是一个SimpleExecutor final Executor executor = configuration.newExecutor(tx, execType); // 创建返回一个DeaultSqlSessoin对象返回 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(); } }
【1.1.1】分析newExecutor方法中执行器的产生:
/** * 方法实现说明:创建一个sql语句执行器对象 * @param transaction:事务 * @param executorType:执行器类型 * @return:Executor执行器对象 */ 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 { //简单的sql执行器对象 executor = new SimpleExecutor(this, transaction); } //判断mybatis的全局配置文件是否开启缓存 if (cacheEnabled) { //把当前的简单的执行器包装成一个CachingExecutor executor = new CachingExecutor(executor); } //调用所有的拦截器对象plugin方法,也就是生成代理对象 executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
【1.1.1.1】图示:
【1.1.2】分析底层如何执行JDBC【User user = (User)session.selectOne("com.mapper.UserMapper.selectById", 1);】
/** * 方法实现说明:查询我们当个对象 * @param statement:SQL语句 * @param parameter:调用时候的参数 * @return: T 返回结果 */ @Override public <T> T selectOne(String statement, Object parameter) { // 这里selectOne调用也是调用selectList方法 List<T> list = this.selectList(statement, parameter); //若查询出来有且有一个一个对象,直接返回要给 if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { //查询的有多个,那么就抛出异常 throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } @Override public <E> List<E> selectList(String statement, Object parameter) { return this.selectList(statement, parameter, RowBounds.DEFAULT); } /** * @param statement: statementId * @param parameter:参数对象 * @param rowBounds :mybiats的逻辑分页对象 */ @Override public