Mybatis-SqlSession源码解析

Mybatis3.5.1源码分析

  1. Mybatis-SqlSessionFactoryBuilder,XMLConfigBuilder,XPathParser源码解析
  2. Mybatis-Configuration源码解析
  3. Mybatis-事务对象源码解析
  4. Mybatis-数据源源码解析
  5. Mybatis缓存策略源码解析
  6. Mybatis-DatabaseIdProvider源码解析
  7. Mybatis-TypeHandler源码解析
  8. Mybatis-Reflector源码解析
  9. Mybatis-ObjectFactory,ObjectWrapperFactory源码分析
  10. Mybatis-Mapper各类标签封装类源码解析
  11. Mybatis-XMLMapperBuilder,XMLStatmentBuilder源码分析
  12. Mybatis-MapperAnnotationBuilder源码分析
  13. [Mybatis-MetaObject,MetaClass源码解析]https://www.jianshu.com/p/f51fa552f30a)
  14. Mybatis-LanguageDriver源码解析
  15. Mybatis-SqlSource源码解析
  16. Mybatis-SqlNode源码解析
  17. Mybatis-KeyGenerator源码解析
  18. Mybatis-Executor源码解析
  19. Mybatis-ParameterHandler源码解析
  20. Mybatis-StatementHandler源码解析
  21. Mybatis-DefaultResultSetHandler(一)源码解析
  22. Mybatis-DefaultResultSetHandler(二)源码解析
  23. Mybatis-ResultHandler,Cursor,RowBounds 源码分析
  24. Mybatis-MapperProxy源码解析
  25. Mybatis-SqlSession源码解析
  26. Mybatis-Interceptor源码解析

SqlSession

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.session;

import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;

/**
 * The primary Java interface for working with MyBatis.
 * Through this interface you can execute commands, get mappers and manage transactions.
 * 

* 数据库对话 *

*

* 这个Mybatis的主要Java接口,通过这个接口可以执行命令,映射器和管理事务。 *

*

* Closeable:表示可以关闭的数据的源或目的地。 调用close方法来释放对象持有的资源(如打开的文件)。 *

* @author Clinton Begin */ public interface SqlSession extends Closeable { /** * Retrieve a single row mapped from the statement key. 返回单个查询结果 * @param the returned object type 结果对象类型 * @param statement 唯一标识匹配的语句. * @return Mapped object 映射对象 */ T selectOne(String statement); /** * Retrieve a single row mapped from the statement key and parameter. 返回单个查询结果 * @param the returned object type 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @param parameter A parameter object to pass to the statement. 查询参数对象 * @return Mapped object 映射对象 */ T selectOne(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter. 返回查询结果集合 * @param the returned list element type 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @return List of mapped object 映射对象集合 */ List selectList(String statement); /** * Retrieve a list of mapped objects from the statement key and parameter. 返回查询结果集合 * @param the returned list element type 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @param parameter A parameter object to pass to the statement. 查询参数对象 * @return List of mapped object 映射对象集合 */ List selectList(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter, * within the specified row bounds. 返回集合结果 * @param the returned list element type 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 查询参数对象 * @param rowBounds Bounds to limit object retrieval 返回结果的大小控制 * @return List of mapped object 映射对象集合 */ List selectList(String statement, Object parameter, RowBounds rowBounds); /** * The selectMap is a special case in that it is designed to convert a list * of results into a Map based on one of the properties in the resulting * objects. * 返回Map对象 * Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id") * @param the returned Map keys type Map的Key类型 * @param the returned Map values type Map的Value类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名 * @return Map containing key pair data. 结果对象映射 */ Map selectMap(String statement, String mapKey); /** * The selectMap is a special case in that it is designed to convert a list * of results into a Map based on one of the properties in the resulting * objects. 返回Map对象 * @param the returned Map keys type Map的Key类型 * @param the returned Map values type Map的Value类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @param parameter A parameter object to pass to the statement. 查询参数对象 * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名 * @return Map containing key pair data. 结果对象映射 */ Map selectMap(String statement, Object parameter, String mapKey); /** * The selectMap is a special case in that it is designed to convert a list * of results into a Map based on one of the properties in the resulting * objects. 返回Map对象 * @param the returned Map keys type Map的Key类型 * @param the returned Map values type Map的Value类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句. * @param parameter A parameter object to pass to the statement. 查询参数对象 * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名 * @param rowBounds Bounds to limit object retrieval 返回结果的大小控制 * @return Map containing key pair data. 结果对象映射 */ Map selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游标查询 * @param the returned cursor element type. 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @return Cursor of mapped objects 结果对象游标 */ Cursor selectCursor(String statement); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游标查询 * @param the returned cursor element type. 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement.查询参数对象 * @return Cursor of mapped objects 结果对象游标 */ Cursor selectCursor(String statement, Object parameter); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游标查询 * @param the returned cursor element type. 结果对象类型 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 查询参数对象 * @param rowBounds Bounds to limit object retrieval 返回结果的大小控制 * @return Cursor of mapped objects 结果对象游标 */ Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds); /** * Retrieve a single row mapped from the statement key and parameter * using a {@code ResultHandler}. 查询单条,用ResultHandler接收结果 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 查询参数对象 * @param handler ResultHandler that will handle each retrieved row 结果接收处理器 */ void select(String statement, Object parameter, ResultHandler handler); /** * Retrieve a single row mapped from the statement * using a {@code ResultHandler}. 查询单条,用ResultHandler接收结果 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param handler ResultHandler that will handle each retrieved row 结果接收处理器 */ void select(String statement, ResultHandler handler); /** * Retrieve a single row mapped from the statement key and parameter * using a {@code ResultHandler} and {@code RowBounds}. 查询单条,用ResultHandler接收结果 * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句 * @param rowBounds RowBound instance to limit the query results 返回结果的大小控制 * @param handler ResultHandler that will handle each retrieved row 结果接收处理器 */ void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler); /** * Execute an insert statement. 执行插入SQL * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句 * @return int The number of rows affected by the insert. 更新记录数 */ int insert(String statement); /** * Execute an insert statement with the given parameter object. Any generated * autoincrement values or selectKey entries will modify the given parameter * object properties. Only the number of rows affected will be returned. 执行插入SQL * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 插入参数对象 * @return int The number of rows affected by the insert. 更新记录数 */ int insert(String statement, Object parameter); /** * Execute an update statement. The number of rows affected will be returned. 执行修改SQL * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句 * @return int The number of rows affected by the update.更新记录数 */ int update(String statement); /** * Execute an update statement. The number of rows affected will be returned. 执行修改SQL * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 修改参数对象 * @return int The number of rows affected by the update. .更新记录数 */ int update(String statement, Object parameter); /** * Execute a delete statement. The number of rows affected will be returned. 执行删除SQL * @param statement Unique identifier matching the statement to execute.唯一标识匹配的语句 * @return int The number of rows affected by the delete. 更新记录数 */ int delete(String statement); /** * Execute a delete statement. The number of rows affected will be returned. 执行delete语句。将返回受影响的行数; * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句 * @param parameter A parameter object to pass to the statement. 删除参数对象 * @return int The number of rows affected by the delete. 更新记录数 */ int delete(String statement, Object parameter); /** * Flushes batch statements and commits database connection. 事务提交 * Note that database connection will not be committed if no updates/deletes/inserts were called. 注意,数据库连接将不会提交如果没有更新/删除/插入被称为。; * To force the commit call {@link SqlSession#commit(boolean)} 如果需要强制提交,可以调用 {@link SqlSession#commit(boolean)} */ void commit(); /** * Flushes batch statements and commits database connection. 事务提交 * @param force forces connection commit 强制提交数据库连接 */ void commit(boolean force); /** * Discards pending batch statements and rolls database connection back. 事务回退 * Note that database connection will not be rolled back if no updates/deletes/inserts were called. 注意,数据库连接将不会回退如果没有更新/删除/插入被调用; * To force the rollback call {@link SqlSession#rollback(boolean)} 如果需要强制回退,可以调用 {@link SqlSession#commit(boolean)} */ void rollback(); /** * Discards pending batch statements and rolls database connection back. 事务回退; * Note that database connection will not be rolled back if no updates/deletes/inserts were called.注意,数据库连接将不会回退如果没有更新/删除/插入被称为。; * @param force forces connection rollback 强制回退数据库连接 */ void rollback(boolean force); /** * Flushes batch statements.执行全部等待批处理语句,并将结果封装到BatchResult集合中 * @return BatchResult list of updated records 更新记录的BatchResult集合 * @since 3.0.6 */ List flushStatements(); /** * Closes the session. 关闭数据库对话 */ @Override void close(); /** * Clears local session cache. 清空数据库对话缓存 */ void clearCache(); /** * 获取Mybatis全局配置信息 * Retrieves current configuration. * @return Configuration */ Configuration getConfiguration(); /** * Retrieves a mapper. 获取Mapper * @param the mapper type Mapper对应的Class类型 * @param type Mapper interface class Mapper对应的Class类型 * @return a mapper bound to this SqlSession 一个绑定到这个Sql会话的Mapper; */ T getMapper(Class type); /** * Retrieves inner database connection. 获取数据库连接 * @return Connection */ Connection getConnection(); }

DefaultSqlSession

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.session.defaults;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.result.DefaultMapResultHandler;
import org.apache.ibatis.executor.result.DefaultResultContext;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;

/**
 * The default implementation for {@link SqlSession}. 这是一个SqlSession接口的默认实现类
 * Note that this class is not Thread-Safe. 注意,这个类并不是线程安全的
 *
 * @author Clinton Begin
 */
public class DefaultSqlSession implements SqlSession {

  /**
   * mybatis全局配置新
   */
  private final Configuration configuration;
  /**
   * SQL脚本执行器
   */
  private final Executor executor;

  /**
   * 是否自动提交
   */
  private final boolean autoCommit;
  /**
   * 是否有调用更新SQL脚本标记
   */
  private boolean dirty;
  /**
   * 游标集合
   */
  private List> cursorList;

  /**
   *
   * @param configuration mybatis全局配置信息
   * @param executor SQL脚本执行器
   * @param autoCommit 是否自动提交标记
   */
  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
  }

  /**
   *
   * @param configuration Mybatis全局配置信息
   * @param executor SQL脚本执行器
   */
  public DefaultSqlSession(Configuration configuration, Executor executor) {
    //不设置自动提交
    this(configuration, executor, false);
  }

  /**
   * 返回单个查询结果
   * @param statement 唯一标识匹配的语句.
   * @param  结果对象类型
   * @return 映射对象
   */
  @Override
  public  T selectOne(String statement) {
    return this.selectOne(statement, null);
  }

  /**
   * 返回单个查询结果
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句.
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param  结果对象类型
   * @return 映射对象
   */
  @Override
  public  T selectOne(String statement, Object parameter) {
    // Popular vote was to return null on 0 results and throw exception on too many.
    // 民众投票 当没有结果对象时,返回null;当超过1条结果对象时,抛出异常
    List 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 {
      //返回null
      return null;
    }
  }

  /**
   * 返回Map对象
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句.
   * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名
   * @param  Map的Key类型
   * @param  Map的Value类型
   * @return 结果对象映射
   */
  @Override
  public  Map selectMap(String statement, String mapKey) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
  }

  /**
   * 返回Map对象
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句.
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名
   * @param  Map的Key类型
   * @param  Map的Value类型
   * @return 结果对象映射
   */
  @Override
  public  Map selectMap(String statement, Object parameter, String mapKey) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
  }

  /**
   * 返回Map对象
   * @param statement Unique identifier matching the statement to use.  唯一标识匹配的语句.
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param mapKey The property to use as key for each value in the list. key值,字段的属性别名
   * @param rowBounds  Bounds to limit object retrieval 返回结果的大小控制
   * @param  Map的Key类型
   * @param   Map的Value类型
   * @return 结果对象映射
   */
  @Override
  public  Map selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
    //执行查询SQL脚本,返回结果对象集合
    final List list = selectList(statement, parameter, rowBounds);
    //新建一个默认Map形式的ResultHandler
    final DefaultMapResultHandler mapResultHandler = new DefaultMapResultHandler<>(mapKey,
            configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
    //新建一个默认结果上下文:这个类封装了结果集个数和当前结果
    final DefaultResultContext context = new DefaultResultContext<>();
    //遍历结果对象集合
    for (V o : list) {
      //将结果对象赋值到结果上下文的下一个结果对象中
      context.nextResultObject(o);
      //接收结果上下文,取出结果对象,添加到mapResultHandler内部维护的Map对象中
      mapResultHandler.handleResult(context);
    }
    //返回mapResultHandler内部维护的Map对象
    return mapResultHandler.getMappedResults();
  }

  /**
   * 游标查询
   * @param statement Unique identifier matching the statement to use.  唯一标识匹配的语句
   * @param  结果对象类型
   * @return 结果对象游标
   */
  @Override
  public  Cursor selectCursor(String statement) {
    return selectCursor(statement, null);
  }

  /**
   * 游标查询
   * @param statement Unique identifier matching the statement to use.  唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement.查询参数对象
   * @param  结果对象类型
   * @return 结果对象游标
   */
  @Override
  public  Cursor selectCursor(String statement, Object parameter) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    return selectCursor(statement, parameter, RowBounds.DEFAULT);
  }

  /**
   * 游标查询
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param rowBounds  Bounds to limit object retrieval 返回结果的大小控制
   * @param  结果对象类型
   * @return  结果对象游标
   */
  @Override
  public  Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds) {
    try {
      //MappedStatement: Mapper.xml文件的select,delete,update,insert这些DML标签的封装类
      //获取statement对应的MappedStatment对象
      MappedStatement ms = configuration.getMappedStatement(statement);
      /**
       * 如果{@code object}是数组,或者是Collection实现类,会将 {@code object} 包装成StrictMap对象,
       * 否则直接返回 {@code object},执行查询,返回结果对象游标
       */
      Cursor cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);
      //注册游标,将cursor添加到cursorList中
      registerCursor(cursor);
      //返回结果对象游标
      return cursor;
    } catch (Exception e) {
      //如果出现异常,就包装异常对象,并加以描述再抛出
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      //错误上下文实例重置
      ErrorContext.instance().reset();
    }
  }

  /**
   * 返回查询结果集合
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句.
   * @param  结果对象类型
   * @return 映射对象集合
   */
  @Override
  public  List selectList(String statement) {
    return this.selectList(statement, null);
  }

  /**
   * 返回查询结果集合
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句.
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param  结果对象类型
   * @return 映射对象集合
   */
  @Override
  public  List selectList(String statement, Object parameter) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    return this.selectList(statement, parameter, RowBounds.DEFAULT);
  }

  /**
   * 返回集合结果
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param rowBounds  Bounds to limit object retrieval 返回结果的大小控制
   * @param  结果对象类型
   * @return 结果对象集合
   */
  @Override
  public  List selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      //MappedStatement: Mapper.xml文件的select,delete,update,insert这些DML标签的封装类
      //获取statement对应的MappedStatment对象
      MappedStatement ms = configuration.getMappedStatement(statement);
      /**
       * 如果{@code object}是数组,或者是Collection实现类,会将 {@code object} 包装成StrictMap对象,
       * 否则直接返回 {@code object},执行查询,返回结果对象集合
       */
      return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    } catch (Exception e) {
      //如果出现异常,就包装异常对象,并加以描述再抛出
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      //错误上下文实例重置
      ErrorContext.instance().reset();
    }
  }

  /**
   * 查询单条,用ResultHandler接收结果
   * @param statement Unique identifier matching the statement to use.  唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement. 查询参数对象
   * @param handler ResultHandler that will handle each retrieved row 结果接收处理器
   */
  @Override
  public void select(String statement, Object parameter, ResultHandler handler) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    select(statement, parameter, RowBounds.DEFAULT, handler);
  }

  /**
   * 查询单条,用ResultHandler接收结果
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句
   * @param handler ResultHandler that will handle each retrieved row 结果接收处理器
   */
  @Override
  public void select(String statement, ResultHandler handler) {
    //RowBounds.DEFAULT:从0开始到Integer.MAX_VALUE
    select(statement, null, RowBounds.DEFAULT, handler);
  }

  /**
   * 查询单条,用ResultHandler接收结果
   * @param statement Unique identifier matching the statement to use. 唯一标识匹配的语句
   * @param parameter 参数对象
   * @param rowBounds RowBound instance to limit the query results 返回结果的大小控制
   * @param handler ResultHandler that will handle each retrieved row 结果接收处理器
   */
  @Override
  public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
    try {
      //MappedStatement: Mapper.xml文件的select,delete,update,insert这些DML标签的封装类
      //获取statement对应的MappedStatment对象
      MappedStatement ms = configuration.getMappedStatement(statement);
      /**
       * 如果parameter是数组,或者是Collection实现类,会将parameter 包装成StrictMap对象,
       * 否则直接返回parameter,执行查询,用handler接收结果对象
       */
      executor.query(ms, wrapCollection(parameter), rowBounds, handler);
    } catch (Exception e) {
      //如果出现异常,就包装异常对象,并加以描述再抛出
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      //错误上下文实例重置
      ErrorContext.instance().reset();
    }
  }

  /**
   * 执行插入SQL
   * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句
   * @return 更新记录数
   */
  @Override
  public int insert(String statement) {
    return insert(statement, null);
  }

  /**
   * 执行插入SQL
   * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement. 插入参数对象
   * @return 更新记录数
   */
  @Override
  public int insert(String statement, Object parameter) {
    return update(statement, parameter);
  }

  /**
   * 执行修改SQL
   * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句
   * @return 更新记录数
   */
  @Override
  public int update(String statement) {
    return update(statement, null);
  }

  /**
   * 执行修改SQL
   * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement.  修改参数对象
   * @return 更新记录数
   */
  @Override
  public int update(String statement, Object parameter) {
    try {
      //将是否有调用更新SQL标记设置为true,表示有有调用更新SQL
      dirty = true;
      //MappedStatement: Mapper.xml文件的select,delete,update,insert这些DML标签的封装类
      //获取statement对应的MappedStatment对象
      MappedStatement ms = configuration.getMappedStatement(statement);
      /**
       * wrapCollection:如果parameter是数组,或者是Collection实现类,会将parameter 包装成StrictMap对象,
       * 否则直接返回parameter
       */
      //执行更新SQL脚本
      return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
      //如果出现异常,就包装异常对象,并加以描述再抛出
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
      //错误上下文实例重置
      ErrorContext.instance().reset();
    }
  }

  /**
   * 执行删除SQL
   * @param statement Unique identifier matching the statement to execute.唯一标识匹配的语句
   * @return 更新记录数
   */
  @Override
  public int delete(String statement) {
    return update(statement, null);
  }

  /**
   * 执行删除SQL
   * @param statement Unique identifier matching the statement to execute. 唯一标识匹配的语句
   * @param parameter A parameter object to pass to the statement. 删除参数对象
   * @return 更新记录数
   */
  @Override
  public int delete(String statement, Object parameter) {
    return update(statement, parameter);
  }

  /**
   * 事务提交
   * 

* 注意,数据库连接将不会提交如果没有更新/删除/插入被称为。 * 如果需要强制提交,可以调用 {@link SqlSession#commit(boolean)} *

*/ @Override public void commit() { commit(false); } /** * 事务提交 * @param force forces connection commit 强制提交数据库连接 */ @Override public void commit(boolean force) { try { /** * isCommitOrRollbackRequired:只要force为true,一定返回ture;如果force * 为false,如果没有设置自动提交但有执行更新的SQL脚本;否则返回false */ //通知执行器提交事务 executor.commit(isCommitOrRollbackRequired(force)); //事务结束,标记还原 dirty = false; } catch (Exception e) { //如果出现异常,就包装异常对象,并加以描述再抛出 throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e); } finally { //错误上下文实例重置 ErrorContext.instance().reset(); } } /** * 事务回退 *

* 注意,数据库连接将不会回退如果没有更新/删除/插入被调用; * 如果需要强制回退,可以调用 {@link SqlSession#commit(boolean)} *

*/ @Override public void rollback() { rollback(false); } /** * 事务回退 * @param force forces connection rollback 强制回退数据库连接 */ @Override public void rollback(boolean force) { try { /** * isCommitOrRollbackRequired:只要force为true,一定返回ture;如果force * 为false,如果没有设置自动提交但有执行更新的SQL脚本;否则返回false */ //通知执行器回退事务 executor.rollback(isCommitOrRollbackRequired(force)); //事务结束,标记还原 dirty = false; } catch (Exception e) { //如果出现异常,就包装异常对象,并加以描述再抛出 throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e); } finally { //错误上下文实例重置 ErrorContext.instance().reset(); } } /** * 执行全部等待批处理语句,并将结果封装到BatchResult集合中 * @return 更新记录的BatchResult集合 */ @Override public List flushStatements() { try { //通知执行器执行全部等待批处理语句,并将结果封装到BatchResult集合中 return executor.flushStatements(); } catch (Exception e) { //如果出现异常,就包装异常对象,并加以描述再抛出 throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e); } finally { //错误上下文实例重置 ErrorContext.instance().reset(); } } @Override public void close() { try { /** * isCommitOrRollbackRequired:只要force为true,一定返回ture;如果force * 为false,如果没有设置自动提交但有执行更新的SQL脚本;否则返回false */ //关闭执行器,回退事务,关闭事务 executor.close(isCommitOrRollbackRequired(false)); //关闭游标集合中的所有游标对象,清空游标集合 closeCursors(); //标记还原 dirty = false; } finally { //错误上下文实例重置 ErrorContext.instance().reset(); } } /** * 关闭游标集合中的所有游标对象,清空游标集合 */ private void closeCursors() { //如果游标集合不为null且游标集合不是空集合 if (cursorList != null && cursorList.size() != 0) { //遍历游标集合 for (Cursor cursor : cursorList) { try { //关闭游标 cursor.close(); } catch (IOException e) { //如果出现异常,就包装异常对象,并加以描述再抛出 throw ExceptionFactory.wrapException("Error closing cursor. Cause: " + e, e); } } //清空游标集合中的所有游标 cursorList.clear(); } } /** * 获取Mybatis全局配置信息 * @return Mybatis全局配置信息对象 */ @Override public Configuration getConfiguration() { return configuration; } /** * 获取Mapper * @param type Mapper interface class Mapper对应的Class类型 * @param Mapper对应的Class类型 * @return 一个绑定到这个Sql会话的Mapper; */ @Override public T getMapper(Class type) { return configuration.getMapper(type, this); } /** * 获取数据库连接 * @return 数据库连接对象 */ @Override public Connection getConnection() { try { //从执行器中获取事务对象,再从事务对象中获取数据库连接并返回 return executor.getTransaction().getConnection(); } catch (SQLException e) { ////如果出现异常,就包装异常对象,并加以描述再抛出 throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e); } } /** * 清空数据库对话缓存 */ @Override public void clearCache() { //清空执行器本地缓存(一级缓存) executor.clearLocalCache(); } /** * 注册游标,将 {@code cursor} 添加到cursorList中 * @param cursor 结果对象游标 * @param 结果对象类型 */ private void registerCursor(Cursor cursor) { //如果游标集合为null if (cursorList == null) { //实例化cursorList为ArrayList cursorList = new ArrayList<>(); } //添加cursor到游标对象集合中 cursorList.add(cursor); } /** * 是否必须提交或者回滚 * @param force 是否强制提交或者强制关闭 * @return 只要force为true,一定返回ture;如果 {@code force} 为false,如果没有设置自动提交但有执行更新的SQL脚本;否则返回false */ private boolean isCommitOrRollbackRequired(boolean force) { //只要force为true,一定返回ture //如果force为false,如果没有设置自动提交但有执行更新的SQL脚本,返回true;否则返回false return (!autoCommit && dirty) || force; } /** * 如果{@code object}是数组,或者是Collection实现类,会将 {@code object} 包装成StrictMap对象,否则直接返回 {@code object} * @param object 参数对象 * @return 如果object是数组,或者是Collection的实现类,就直接返回StrictMap对象;否则直接返回 {@code object} */ private Object wrapCollection(final Object object) { //如果Object是Collection的实现类 if (object instanceof Collection) { //StrictMap:HashMap的子类,对获取集合没有元素时会抛出异常。 //新建一个Map StrictMap map = new StrictMap<>(); //将object添加到map,key为collection map.put("collection", object); //如果object还是List的实现类 if (object instanceof List) { //将object再次添加到map,key为list map.put("list", object); } return map; //如果object不为null,且 object是数组 } else if (object != null && object.getClass().isArray()) { //StrictMap:HashMap的子类,对获取集合没有元素时会抛出异常。 //新建一个Map StrictMap map = new StrictMap<>(); //将object再次添加到map,key为array map.put("array", object); return map; } //如果object不是数组,又不是Collection的实现类,就直接返回object return object; } /** * HashMap的子类,对获取集合没有元素时会抛出异常。 */ public static class StrictMap extends HashMap { private static final long serialVersionUID = -5741767162221585340L; @Override public V get(Object key) { //如果没有key对应的value时 if (!super.containsKey(key)) { throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet()); } return super.get(key); } } }

你可能感兴趣的:(Mybatis-SqlSession源码解析)