• MyBatis源码探索


      

      每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML (mybatis-config.xml) 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

    类图

    其中SqlSession是比较重要的接口,提供基本的方法,比如:sql语句、事务等操作;

    具体执行过程以<E> List<E> selectList(String statement);方法为例:SqlSession的实现类DefaultSqlSession调用configuration.getMappedStatement(statement);获取statement节点的sql,存放在MappedStatement,传给接口Executor的query方法。

     1   @Override
     2   public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
     3     try {
     4       MappedStatement ms = configuration.getMappedStatement(statement);
     5       return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
     6     } catch (Exception e) {
     7       throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
     8     } finally {
     9       ErrorContext.instance().reset();
    10     }
    11   }

    Executor处理MappedStatement的关键代码和注释如下

     1   // 是否需要刷新缓存
     2   if (queryStack == 0 && ms.isFlushCacheRequired()) {
     3       clearLocalCache();
     4     }
     5     List<E> list;
     6     try {
     7       queryStack++;
     8       list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
     9       if (list != null) {
    10         // 如果缓存中有数据,直接拿到缓存中的数据
    11         handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
    12       } else {
    13         // 否则从数据库中获取
    14         list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
    15       }
    16     } finally {
    17       queryStack--;
    18     }
     1   private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
     2     List<E> list;
     3     localCache.putObject(key, EXECUTION_PLACEHOLDER);
     4     try {
     5       list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
     6     } finally {
     7       localCache.removeObject(key);
     8     }
     9     // 把查询结果放入缓存后返回结果list
    10     localCache.putObject(key, list);
    11     if (ms.getStatementType() == StatementType.CALLABLE) {
    12       localOutputParameterCache.putObject(key, parameter);
    13     }
    14     return list;
    15   }
     1   @Override
     2   public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
     3     // 用来执行静态sql语句的对象
     4     Statement stmt = null;
     5     try {
     6       Configuration configuration = ms.getConfiguration();
     7       StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
     8       stmt = prepareStatement(handler, ms.getStatementLog());
     9       // StatementHandler中处理sql的执行和结果的返回
    10       return handler.<E>query(stmt, resultHandler);
    11     } finally {
    12       closeStatement(stmt);
    13     }
    14   }
    1   @Override
    2   public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    3     String sql = boundSql.getSql();
    4     statement.execute(sql);
    5     return resultSetHandler.<E>handleResultSets(statement);
    6   }

    参考文档

    MyBatis官方文档

  • 相关阅读:
    解决:只有 DBA 才能导入由其他 DBA 导出的文件
    查找—顺序查找
    软件测试,想说爱你不容易
    Oracle常用SQL
    排序—直接插入排序
    排序—归并排序
    排序—快速排序
    排序—选择排序
    查找—折半查找
    排序—堆排序
  • 原文地址:https://www.cnblogs.com/bigshark/p/8016757.html
Copyright © 2020-2023  润新知