SQL语句解析执行的过程及原理

吾爱主题 阅读:144 2024-04-01 23:24:06 评论:0

一、sqlSession简单介绍

  • 拿到SqlSessionFactory对象后,会调用SqlSessionFactoryopenSesison方法,这个方法会创建一个Sql执行器(Executor),这个Sql执行器会代理你配置的拦截器方法。
  • 获得上面的Sql执行器后,会创建一个SqlSession(默认使用DefaultSqlSession),这个SqlSession中也包含了Configration对象,所以通过SqlSession也能拿到全局配置;
  • 获得SqlSession对象后就能执行各种CRUD方法了。

二、获得sqlSession对象源码分析

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 /**   * 通过sqlSessionFactory.openSession进行获取sqlSession对象   * 源码位置:org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession()   */ public SqlSession openSession() {      return openSessionFromDataSource(configuration.getDefaultExecutorType(), null , false ); }   /**   * 通过数据源去获取SqlSession   * 源码位置:org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(ExecutorType, TransactionIsolationLevel, boolean)   */ 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);          // 根据获取的执行器创建SqlSession          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();      } }   /**   * 获取执行器   * 源码位置:org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(ExecutorType, TransactionIsolationLevel, boolean)   */ public Executor newExecutor( Transaction transaction , ExecutorType executorType) {      // 默认使用SIMPLE的执行器      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) {          // 开启缓存,吧executor包装为CachingExecutor          executor = new CachingExecutor(executor);      }           // 插件的调用:责任链模式      executor = (Executor) interceptorChain.pluginAll(executor);      return executor; }

三、SQL执行流程,以查询为例

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 /**   * 查询的入口方法   * 源码位置:org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(String, Object)   */ public <T> T selectOne(String statement, Object parameter) {      // Popular vote was to return null on 0 results and throw exception on too many.      // 查询数据      List<T> list = this.<T>selectList(statement, parameter);        // 长度为1,拿第一个      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 ;      } }   /**   * 查询数据   * 源码位置:org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(String, Object, RowBounds)   */ public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {      try {          // 通过statement去全局配置文件中获取MappedStatement(得到mapper中增删改查的节点)          MappedStatement ms = configuration.getMappedStatement(statement);            // 通过执行器去执行SQL          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();      } }   /**   * 执行查询操作的准备工作   * 源码位置:org.apache.ibatis.executor.CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler)   */ public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds,          ResultHandler resultHandler) throws SQLException {        // 通过参数进行sql解析      BoundSql boundSql = ms.getBoundSql(parameterObject);      CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);      return query(ms, parameterObject, rowBounds, resultHandler, key , boundSql); }   /**   * 执行查询操作的准备工作   * 源码位置:org.apache.ibatis.executor.CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)   */ public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds,          ResultHandler resultHandler, CacheKey key , BoundSql boundSql) throws SQLException {      // 判断sql是否开启了缓存 <cache></cache>      Cache cache = ms.getCache();           // 有缓存      if (cache != null ) {          // 判断是否需要刷新缓存          flushCacheIfRequired(ms);          if (ms.isUseCache() && resultHandler == null ) {              ensureNoOutParams(ms, boundSql);              @SuppressWarnings( "unchecked" )                // 去二级缓存中获取(装饰者模式)              List<E> list = (List<E>) tcm.getObject(cache, key );                // 二级缓存没有找到              if (list == null ) {                    // 查询数据,并放入缓存                  list = delegate.<E>query(ms, parameterObject, rowBounds, resultHandler, key , boundSql);                  tcm.putObject(cache, key , list); // issue #578 and #116              }              return list;          }      }      // 查询数据      return delegate.<E>query(ms, parameterObject, rowBounds, resultHandler, key , boundSql); }   /**   * 一级缓存查询的调用   * 源码位置:org.apache.ibatis.executor.BaseExecutor.query(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)   */ public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler,          CacheKey key , BoundSql boundSql) throws SQLException {      ErrorContext.instance().resource(ms.getResource()).activity( "executing a query" ).object(ms.getId());        // 已经关闭了,抛异常      if (closed) {          throw new ExecutorException( "Executor was closed." );      }        // 清空本地缓存      if (queryStack == 0 && ms.isFlushCacheRequired()) {          clearLocalCache();      }      List<E> list;      try {          // 从一级缓存中获取数据          queryStack++;          list = resultHandler == null ? (List<E>) localCache.getObject( key ) : null ;          if (list != null ) {              // 缓存里面有,进行处理              handleLocallyCachedOutputParameters(ms, key , parameter, boundSql);          } else {              // 缓存没有,进行查询              list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key , boundSql);          }      } finally {          queryStack --;      }      if (queryStack == 0) {          for (DeferredLoad deferredLoad : deferredLoads) {              deferredLoad. load ();          }          // issue #601          deferredLoads.clear();          if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {              // issue #482              clearLocalCache();          }      }      return list; }   /**   * 在数据库中查询   * 源码位置:org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)   */ private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds,          ResultHandler resultHandler, CacheKey key , BoundSql boundSql) throws SQLException {      List<E> list;      localCache.putObject( key , EXECUTION_PLACEHOLDER);      try {          // 去数据库查询          list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);      } finally {          localCache.removeObject( key );      }        // 一级缓存进行缓存      localCache.putObject( key , list);      if (ms.getStatementType() == StatementType.CALLABLE) {          localOutputParameterCache.putObject( key , parameter);      }      return list; }   /**   * 查询逻辑   * 源码位置:org.apache.ibatis.executor.SimpleExecutor.doQuery(MappedStatement, Object, RowBounds, ResultHandler, BoundSql)   */ public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler,          BoundSql boundSql) throws SQLException {      Statement stmt = null ;      try {          // 得到整体的配置对象          Configuration configuration = ms.getConfiguration();            // 内部封装了ParameterHandler和ResultSetHandler          StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds,                  resultHandler, boundSql);          stmt = prepareStatement(handler, ms.getStatementLog());            // 执行查询          return handler.<E>query(stmt, resultHandler);      } finally {          closeStatement(stmt);      } }   /**   * 执行查询语句   * 源码位置:org.apache.ibatis.executor.statement.SimpleStatementHandler.query(Statement, ResultHandler)   */ public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {      // 得到要执行的sql      String sql = boundSql.getSql();        // 执行sql      statement. execute (sql);        // 处理结果集      return resultSetHandler.<E>handleResultSets(statement); }

到此这篇关于SQL语句解析执行的过程及原理的文章就介绍到这了,更多相关SQL语句解析原理内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/zfcq/p/16069357.html

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容