《Mybatis源码》第7章 SqlSession

一、SqlSessionFactory

前两章我们已经介绍了如何解析mybatis-config.xmlmapper文件,同时也生成了我们的全局配置对象configuration,那么就通过SqlSessionFactoryBuilder创建了一个DefaultSqlSessionFactory返回

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      // 读取配置文件
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      // build()
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }
  
  // 创建DefaultSqlSessionFactory
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

DefaultSqlSessionFactory类实现了SqlSessionFactory接口,接下来我们通过其openSession()方法来创建SqlSession,一个session就对应JDBC底层连接的一个对象

SqlSessionFactory

public interface SqlSessionFactory {
  // 默认设置
  SqlSession openSession();
  // 自动提交模式
  SqlSession openSession(boolean autoCommit);
  // 特定的jdbc连接
  SqlSession openSession(Connection connection);
  // 事务隔离级别
  SqlSession openSession(TransactionIsolationLevel level);
  // 执行的执行器类型
  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);

  Configuration getConfiguration();
}

DefaultSqlSessionFactory

public class DefaultSqlSessionFactory implements SqlSessionFactory {
  // 配置对象
  private final Configuration configuration;
  // 构造方法
  public DefaultSqlSessionFactory(Configuration configuration) {
    this.configuration = configuration;
  }
  // 创建sqlSession
  @Override
  public SqlSession openSession() {
    // 调用的是另外一个openSessionFromDataSource方法
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }

  @Override
  public SqlSession openSession(boolean autoCommit) {
    //调用的是另外一个openSessionFromDataSource方法
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }
    
  // 省略一些代码...
  
  // 在这个类里面有很多openSession的重载方法,都是调用的该方法
  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);
      // 构建一个executor来执行SQL
      final Executor executor = configuration.newExecutor(tx, execType);
      // 创建一个DefaultSqlSession返回
      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();
    }
  }
  
  // 从环境获取事务工厂
  private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
    // 如果环境为空 则创建ManagedTransactionFactory 代表事务由框架管理
    if (environment == null || environment.getTransactionFactory() == null) {
      return new ManagedTransactionFactory();
    }
    // 否则从环境中获取
    return environment.getTransactionFactory();
  }
  

3.创建SqlSession

SqlSession

上文我们介绍了通过DefaultSqlSessionFactory将事务和执行器封装,创建DefaultSqlSession对象,那么接下来我们就看一下

public interface SqlSession extends Closeable {

  // 查询一个
  <T> T selectOne(String statement);

  
  <T> T selectOne(String statement, Object parameter);

  // 查询列表
  <E> List<E> selectList(String statement);

  
  <E> List<E> selectList(String statement, Object parameter);

  // 分页查询列表
  <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);

  // 查询集合
  <K, V> Map<K, V> selectMap(String statement, String mapKey);

  
  <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);

  //分页查询集合
  <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);

  
  <T> Cursor<T> selectCursor(String statement);

  
  <T> Cursor<T> selectCursor(String statement, Object parameter);

  
  <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);

  
  void select(String statement, Object parameter, ResultHandler handler);

  
  void select(String statement, ResultHandler handler);

  
  void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);

  // 添加
  int insert(String statement);

  
  int insert(String statement, Object parameter);

  
  int update(String statement);

  
  int update(String statement, Object parameter);

  // 删除
  int delete(String statement);

  
  int delete(String statement, Object parameter);

  // 提交
  void commit();

  
  void commit(boolean force);

  // 回滚
  void rollback();

  
  void rollback(boolean force);

  
  List<BatchResult> flushStatements();

  
  @Override
  void close();

  
  void clearCache();

  
  Configuration getConfiguration();

  // 获取Mapper
  <T> T getMapper(Class<T> type);
    
  Connection getConnection();
}

DefaultSqlSession

public class DefaultSqlSession implements SqlSession {
  // 配置
  private final Configuration configuration;
  // 执行器
  private final Executor executor;
  // 自动提交
  private final boolean autoCommit;
  private boolean dirty;
  // 游标集合
  private List<Cursor<?>> cursorList;
  // 构造方法
  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
  }
  
  public DefaultSqlSession(Configuration configuration, Executor executor) {
    this(configuration, executor, false);
  }
  
  @Override
  public <T> T selectOne(String statement) {
    return this.<T>selectOne(statement, null);
  }
  // 查询单个
  @Override
  public <T> T selectOne(String statement, Object parameter) {
    // Popular vote was to return null on 0 results and throw exception on too many.
    // 查询集合 判断长度是1
    List<T> list = this.<T>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 <K, V> Map<K, V> selectMap(String statement, String mapKey) {
    return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
  }
  
  @Override
  public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
    return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
  }
  // 查询Map
  @Override
  public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
    // 查询集合 注意这里使用的 泛型上界通配符 
    final List<? extends V> list = selectList(statement, parameter, rowBounds);
    // 创建Map处理器
    final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<K, V>(mapKey,
        configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
    final DefaultResultContext<V> context = new DefaultResultContext<V>();
    // 通过遍历将集合封装到Map里面
    for (V o : list) {
      // 赋值到结果集的下一个结果中
      context.nextResultObject(o);
      // 取出结果对象,并添加到mapResultHandler内部维护的Map对象中
      mapResultHandler.handleResult(context);
    }
    return mapResultHandler.getMappedResults();
  }

  @Override
  public <T> Cursor<T> selectCursor(String statement) {
    return selectCursor(statement, null);
  }

  @Override
  public <T> Cursor<T> selectCursor(String statement, Object parameter) {
    return selectCursor(statement, parameter, RowBounds.DEFAULT);
  }
  // 查询游标
  @Override
  public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      // 通过执行器执行
      Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);
      // 将其添加到字段cursorList游标集合中
      registerCursor(cursor);
      return cursor;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

  @Override
  public <E> List<E> selectList(String statement) {
    return this.selectList(statement, null);
  }

  @Override
  public <E> List<E> selectList(String statement, Object parameter) {
    return this.selectList(statement, parameter, RowBounds.DEFAULT);
  }
  // 查询集合
  @Override
  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      // 封装的DML标签
      MappedStatement ms = configuration.getMappedStatement(statement);
      // 执行器执行
      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();
    }
  }

  @Override
  public void select(String statement, Object parameter, ResultHandler handler) {
    select(statement, parameter, RowBounds.DEFAULT, handler);
  }

  @Override
  public void select(String statement, ResultHandler handler) {
    select(statement, null, RowBounds.DEFAULT, handler);
  }

  @Override
  public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      executor.query(ms, wrapCollection(parameter), rowBounds, handler);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

  @Override
  public int insert(String statement) {
    return insert(statement, null);
  }
  // 插入
  @Override
  public int insert(String statement, Object parameter) {
    return update(statement, parameter);
  }

  @Override
  public int update(String statement) {
    return update(statement, null);
  }
  // 修改
  @Override
  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();
    }
  }
  // 删除
  @Override
  public int delete(String statement) {
    return update(statement, null);
  }

  @Override
  public int delete(String statement, Object parameter) {
    return update(statement, parameter);
  }

  @Override
  public void commit() {
    commit(false);
  }

  @Override
  public void commit(boolean force) {
    try {
      executor.commit(isCommitOrRollbackRequired(force));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

  @Override
  public void rollback() {
    rollback(false);
  }

  @Override
  public void rollback(boolean force) {
    try {
      executor.rollback(isCommitOrRollbackRequired(force));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error rolling back transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
  // 执行全部等待批处理语句,并将结果封装到BatchResult集合中
  @Override
  public List<BatchResult> 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 {
      executor.close(isCommitOrRollbackRequired(false));
      closeCursors();
      dirty = false;
    } finally {
      ErrorContext.instance().reset();
    }
  }

  private void closeCursors() {
    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();
    }
  }

  @Override
  public Configuration getConfiguration() {
    return configuration;
  }

  @Override
  public <T> T getMapper(Class<T> type) {
    return configuration.<T>getMapper(type, this);
  }

  @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();
  }

  private <T> void registerCursor(Cursor<T> cursor) {
    if (cursorList == null) {
      cursorList = new ArrayList<Cursor<?>>();
    }
    cursorList.add(cursor);
  }

  private boolean isCommitOrRollbackRequired(boolean force) {
    return (!autoCommit && dirty) || force;
  }

  private Object wrapCollection(final Object object) {
    if (object instanceof Collection) {
      StrictMap<Object> map = new StrictMap<Object>();
      map.put("collection", object);
      if (object instanceof List) {
        map.put("list", object);
      }
      return map;
    } else if (object != null && object.getClass().isArray()) {
      StrictMap<Object> map = new StrictMap<Object>();
      map.put("array", object);
      return map;
    }
    return object;
  }

  public static class StrictMap<V> extends HashMap<String, V> {

    private static final long serialVersionUID = -5741767162221585340L;

    @Override
    public V get(Object key) {
      if (!super.containsKey(key)) {
        throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
      }
      return super.get(key);
    }
  }
}

map = new StrictMap();
map.put(“array”, object);
return map;
}
return object;
}

public static class StrictMap extends HashMap<String, V> {

private static final long serialVersionUID = -5741767162221585340L;

@Override
public V get(Object key) {
  if (!super.containsKey(key)) {
    throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
  }
  return super.get(key);
}

}
}














评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为人师表好少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值